【Elastic Search權威指南 讀書小記8】ES之深入分片

有道雲排版好一點:https://note.youdao.com/ynoteshare1/index.html?id=a38978147bd85dd15148027aeadd1c92&type=note

倒排索引存儲了比包含了一個特定term的文檔列表多地多的信息。它可能存儲包含每個term的文檔數量,一個term出現在指定文檔中的頻次,每個文檔中term的順序,每個文檔的長

度,所有文檔的平均長度,等等。這些統計信息讓Elasticsearch知道哪些term更重要,哪些

文檔更重要,也就是相關性。

 

1.不可變性

寫入磁盤的倒排索引是不可變的,它有如下好處:

1.不需要鎖。如果從來不需要更新一個索引,就不必擔心多個程序同時嘗試修改。

2.一旦索引被讀入文件系統的緩存(譯者:在內存),它就一直在那兒,因爲不會改變。只要文件系統緩存有足夠的空間,大部分的讀會直接訪問內存而不是磁盤。這有助於性能提升。

3.在索引的聲明週期內,所有的其他緩存都可用。它們不需要在每次數據變化了都重建,因爲數據不會變。

4.寫入單個大的倒排索引,可以壓縮數據,較少磁盤IO和需要緩存索引的內存大小。

此處的不可變可以理解爲已寫入的索引不會局部變化,只會不斷累加或者重寫。有點類似redis持久化裏面的aof,不斷累加日誌,然後到一定量之後經行“重寫”。

 

2.動態索引

既然要不可變,那麼更新的話只能選擇多個索引。不是重寫整個倒排索引,而是增加額外的索引反映最近的變化。每個倒排索引都可以按順序查詢,從最老的開始,最後把結果聚合。有點像累加,但是每次累加都是獨立的小索引。

Elasticsearch底層依賴的Lucene,引入了 per-segment search 的概念。一個段(segment)是有

完整功能的倒排索引,但是現在Lucene中的索引指的是段的集合,再加上提交點。

索引vs分片

爲了避免混淆,需要說明,Lucene索引是Elasticsearch中的分片,Elasticsearch中的索引是分片的集合。當Elasticsearch搜索索引時,它發送查詢請求給該索引下的所有分

片,然後過濾這些結果,聚合成全局的結果。

更新過程

1. 新的文檔首先寫入內存區的索引緩存。

2. 不時,這些buffer被提交:

2.1)一個新的段——額外的倒排索引——寫入磁盤。

2.2)新的提交點寫入磁盤,包括新段的名稱。

2.3)磁盤是fsync’ed(文件同步)——所有寫操作等待文件系統緩存同步到磁盤,確保它們

可以被物理寫入。

3. 新段被打開,它包含的文檔可以被檢索

4. 內存的緩存被清除,等待接受新的文檔。

 

3.緩存進磁盤

在緩存區數據,不可能實時往磁盤寫入同步,這樣太耗費磁盤性能了。但是同步太慢的話,又會有寫入的數據無法快速查到的問題。ES提供了每秒自動同步一次的服務,並且提供了refeash API用於手動同步。

 

POST /_refresh <1>
POST /blogs/_refresh <2>
PUT /my_logs//設置自動同步時間
{
    "settings": {
        "refresh_interval": "30s" <1>
    }
}

 

4.持久化

這一點和mysql的redolog,防止內存中的提交因爲關機而丟失,專門針對這部分未提交的內存中的數據做持久化。在ES中稱爲事務日誌translog

1. 當一個文檔被索引,它被加入到內存緩存,同時加到事務日誌。

2. refresh使得分片的進入如下圖描述的狀態。每秒分片都進行refeash:

內存緩衝區的文檔寫入到段中,但沒有fsync。

段被打開,使得新的文檔可以搜索。

緩存被清除

3. 隨着更多的文檔加入到緩存區,寫入日誌,這個過程會繼續

4. 不時地,比如日誌很大了,新的日誌會創建,會進行一次全提交:

內存緩存區的所有文檔會寫入到新段中。

清除緩存

一個提交點寫入硬盤

文件系統緩存通過fsync操作flush到硬盤

事務日誌被清除

事務日誌記錄了沒有flush到硬盤的所有操作。當故障重啓後,ES會用最近一次提交點從硬盤恢復所有已知的段,並且從日誌裏恢復所有的操作。事務日誌還用來提供實時的CRUD操作。當你嘗試用ID進行CRUD時,它在檢索相關段內的文檔前會首先檢查日誌最新的改動。這意味着ES可以實時地獲取文檔的最新版本。

5.合併段

此處類似redis aof的重寫達到的效果。

ES通過後臺合併段解決這個問題。小段被合併成大段,再合併成更大的段。這是舊的文檔從文件系統刪除的時候。舊的段不會再複製到更大的新段中。修改和刪除在這裏免除了重複,得到了真正的實現。

1. 索引過程中,refresh會創建新的段,並打開它。

2. 合併過程會在後臺選擇一些小的段合併成大的段,這個過程不會中斷索引和搜索。

3. 下圖描述了合併後的操作:

新的段flush到了硬盤。

新的提交點寫入新的段,排除舊的段。

新的段打開供搜索。

舊的段被刪除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章