Elasticsearch Index模塊
每個索引都可以設置索引級別。可選值有:
static :只能在索引創建的時候,或者在一個關閉的索引上設置
dynamic:可以動態設置
1.1. Static index settings(靜態索引設置)
index.number_of_shards :一個索引應該有的主分片(primary shards)數。默認是5。而且,只能在索引創建的時候設置。(註意,每個索引的主分片數不能超過1024。當然,這個設置也是可以改的,通過在集群的每個節點機器上設置系統屬性來更改,例如:export ES_JAVA_OPTS="-Des.index.max_number_of_shards=128")
index.routing_partition_size :自定義的路由值可以路由到的分片數。默認是1。
1.2. Dynamic index settings(動態索引設置)
如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。
index.number_of_replicas :每個主分片所擁有的副本數,默認是1。
index.refresh_interval :多久執行一次刷新操作,使得最近的索引更改對搜索可見。默認是1秒。設置為-1表示禁止刷新。
index.max_result_window :在這個索引下檢索的 from + size 的最大值。默認是10000。(PS:也就是說最多可以一次返回10000條)
- Analysis
索引分析模塊是一個可配置的分析器註冊表,可用於將字符串字段轉換為以下各個場景中的Term:
添加到反向索引( inverted index)以使文檔可搜索
用於高級查詢,如match查詢
第一、分析器用於將一個字符串轉成一個一個的Term;
第二、這些Term可以被添加到反向索引中,以使得該文檔可以通過這個Term被檢索到;
第三、這些Term還可以高級查詢,比如match查詢)
- Merge(合並)
在Elasticsearch中,一個分片就是一個Lucene索引,而且一個Lucene索引被分解成多個段(segments)。段是索引中存儲索引數據的內部存儲元素,並且是不可變的。較小的段定期合並到較大的段中,以控制索引大小。
合並調度程序(ConcurrentMergeScheduler)在需要時控制合並操作的執行。合並在單獨的線程中運行,當達到最大線程數時,將等待進一步的合並,直到合並線程可用為止。
支持下列參數:
index.merge.scheduler.max_thread_count :在單個碎片上,一次合並的最大線程數。默認是 Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2))
如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。
- Slow log(慢日誌)
4.1. Search Slow Log(查詢慢日誌)
分片級慢查詢日誌,允許將慢查詢記錄到專用的日誌文件中
可以在執行query階段和fetch階段設置閾值,例如:
上面所有的設置項都是動態設置的,而且是按索引設置的。(PS:也就是說,是針對某一個索引設置的)
默認情況下,是禁用狀態(設置為-1)
級別(warn, info, debug, trace)可以控制哪些日誌級別的日誌將會被記錄
註意,日誌記錄是在分片級別範圍內完成的,這意味著只有在特定的分片中執行搜索請求的慢日誌才會被記錄。
日誌文件配置默認在log4j2.properties
4.2. Index Slow Log(索引慢日誌)
和前面的慢查詢日誌類似,索引慢日誌文件名後綴為_index_indexing_slowlog.log
日誌和閾值配置與慢查詢類似,而且默認日誌文件配置也是在log4j2.properties
下面是一個例子:
- Store(存儲)
5.1. 文件存儲類型
不同的文件系統有不同的存儲類型。默認情況下,Elasticsearch將根據操作環境選擇最佳實現。
可選的存儲類型有:
fs :默認實現,取決於操作系統
simplefs :對應Lucene SimpleFsDirectory
niofs :對應Lucene NIOFSDirectory
mmapfs :對應Lucene MMapDirectory
可以改變這種設置,通過在config/elasticsearch.yml中添加如下配置,例如:
index.store.type: niofs
上面的設置對所有的索引都生效。你也可以在索引創建的時候針對某一個特定的索引進行設置,例如:
curl -X PUT "localhost:9200/my_index" -H ‘Content-Type: application/json‘ -d‘
{
"settings": {
"index.store.type": "niofs"
}
}
‘
5.2. 預加載數據到文件系統緩存
默認情況下,Elasticsearch完全依賴於操作系統的文件系統緩存來緩存I/O操作。可以設置index.store.preload來告訴操作系統在打開時將熱點索引文件的內容加載到內存中。這個選項接受一個逗號分隔的文件擴展列表:擴展名在列表中的所有文件將在打開時預加載。這對於提高索引的搜索性能非常有用,特別是在主機操作系統重啟時,因為這會導致文件系統緩存被丟棄。但是請註意,這可能會減慢索引的打開速度,因為只有在將數據加載到物理內存之後,索引才會可用。
靜態設置的話可以這樣設置:
index.store.preload: ["nvd", "dvd"]
或者在索引創建的時候設置:
curl -X PUT "localhost:9200/my_index" -H ‘Content-Type: application/json‘ -d‘
{
"settings": {
"index.store.preload": ["nvd", "dvd"]
}
}
‘
如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。
默認值是一個空數組,意味著文件系統不會預加載任何數據。對於可搜索的索引,你可能想要把它們設置為["nvd", "dvd"],這將會使得norms和doc數據被預先加載到物理內存。不推薦把所有的文件都預加載到內存,通常可能更好的選擇是設置為["nvd", "dvd", "tim", "doc", "dim"],這樣的話將會預加載norms,doc values,terms dictionaries, postings lists 和 points
- Translog(事物日誌)
對Lucene的更改只有在Lucene提交的時候才會持久化到磁盤,這是一個相對昂貴的操作,因此不能再每次索引創建或者刪除以後就執行。如果進程退出或者硬件故障的話,那麽在兩次提交之間所做的更改將會被Lucece從索引中刪除。(PS:上一次提交以後到下一次提交之前這之間的更新會丟失)
如果每次更改以後立即執行Lucene提交,那麽這個開銷實在太大,因此每個分片副本也都有一個事物日誌,它被叫做與之關聯的translog。所有的索引和刪除操作都是在內部Lucene索引處理之後,確認之前,被寫入到translog的。在崩潰的情況下,當分片恢復時,可以從translog中恢復最近的事務,這些事務已經被確認,但是還沒有包含在上一次Lucene提交中。
Elasticsearch flush是執行Lucene提交並啟動新translog的過程。flush是在後臺自動執行的,以確保translog不會變得太大。(PS:因為如果translog很大,那麽恢復所需要的時間越長)。當然,我們也可以通過API手動執行刷新,盡管很少需要這樣做。
6.1. Translog設置
translog中的數據只有在fsync和提交時才會被持久化到磁盤。在硬件失敗的情況下,在translog提交之前的數據都會丟失。
默認情況下,如果index.translog.durability被設置為async的話,Elasticsearch每5秒鐘同步並提交一次translog。或者如果被設置為request(默認)的話,每次index,delete,update,bulk請求時就同步一次translog。更準確地說,如果設置為request, Elasticsearch只會在成功地在主分片和每個已分配的副本分片上fsync並提交translog之後,才會向客戶端報告index、delete、update、bulk成功。
可以動態控制每個索引的translog行為:
index.translog.sync_interval :translog多久被同步到磁盤並提交一次。默認5秒。這個值不能小於100ms
index.translog.durability :是否在每次index,delete,update,bulk請求之後立即同步並提交translog。接受下列參數:
request :(默認)fsync and commit after every request。這就意味著,如果發生崩潰,那麽所有只要是已經確認的寫操作都已經被提交到磁盤。
async :在後臺每sync_interval時間進行一次fsync和commit。意味著如果發生崩潰,那麽所有在上一次自動提交以後的已確認的寫操作將會丟失。
index.translog.flush_threshold_size :當操作達到多大時執行刷新,默認512mb。也就是說,操作在translog中不斷累積,當達到這個閾值時,將會觸發刷新操作。
index.translog.retention.size :translog文件達到多大時執行執行刷新。默認512mb。
index.translog.retention.age :translog最長多久提交一次。默認12h。
6.2. 小結
1、只有在Lucene提交的時候,對Lucene所做的更改才會持久化到磁盤,而這一操作開銷很大,因而不可能每次改變後就立即提交,而如果不是每次更改後立即提交的話,那麽在本次提交以後到下一次提前以前這之間的更改就有丟失的可能。為了解決這種問題,每個索引分片都有一個叫做“translog”的事物日誌,每次Lucene處理完以後,就向translog中寫日誌,最後確認本次更改。也就是說,translog是在Lucene內部處理完以後,確認請求之前寫的。
2、translog是為了避免頻繁Lucene提交所造成的大額開銷,同時又要盡量減少數據丟失而采取的一種方案
3、Elasticsearch flush的時候會提交Lucene更改,同時開啟新的translog。flush是後臺自動進行的。默認30分鐘一次。
4、translog本身作為文件也是需要fsync(同步)到磁盤的。通過translog選項設置,我們可以控制多久同步一次,或者當文件達到多大的時候同步,或者文件最長多久就必須同步。默認每次請求以後就立即同步。如果在同步之前發生崩潰,那麽上一次同步之後的寫操作也是會丟失的。
5、Lucene提交跟translog提交是兩回事,Lucene提交的時候translog肯定會被提交
- Segment(段)
向索引中插入文檔時,文檔首先被保存在內存緩存(in-memory buffer)中,同時將操作寫入到translog中,此時這條剛插入的文檔還不能被搜索到。默認1秒鐘refresh一次,refresh操作會將文件寫到操作系統的文件系統緩存中,並形成一個segment,refresh後文檔可以被檢索到。
當flush的時候,所有segment被同步到磁盤,同時清空translog,然後生成一個新的translog
Lucene把每次生成的倒排索引叫做一個segment,也就是說一個segment就是一個倒排索引。(PS:可以類比Oracle中段區塊的概念)
如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。
Elasticsearch Index模塊