ElasticSearch 學習記錄之集羣分片內部原理

ElasticSearch 系列文章

1 ES 入門之一 安裝ElasticSearcha

2 ES 記錄之如何建立一個索引映射

3 ElasticSearch 學習記錄之Text keyword 兩種基本類型區別

4 ES 入門記錄之 match和term查詢的區別

5 ElasticSearch 學習記錄之ES幾種常見的聚合操做

6 ElasticSearch 學習記錄之父子結構的查詢

7 ElasticSearch 學習記錄之ES查詢添加排序字段和使用missing或existing字段查詢

8 ElasticSearch 學習記錄之ES高亮搜索

9 ElasticSearch 學習記錄之ES短語匹配基本用法

10 ElasticSearch 學習記錄之 分佈式文檔存儲往ES中存數據和取數據的原理

11 ElasticSearch 學習記錄之集羣分片內部原理

12 ElasticSearch 學習記錄之ES如何操做Lucene段

13 ElasticSearch 學習記錄之如任何設計可擴容的索引結構

14 ElasticSearch之 控制相關度原理講解







分片內部原理

  • 分片是如何工做的
    • 爲何ES搜索是近實時性
    • 爲何CRUD 操做也是實時性
    • ES 是怎麼保證更新被持久化時斷電也不丟失數據
    • 爲何刪除文檔不會當即釋放空間
    • refresh, flush, 和 optimize API 做用
  • 使文本可被搜索
    倒排索引的結構html

    詞項 文檔列表
    Term | Doc 1 | Doc 2 | Doc 3 | ...
    ------------------------------------
    brown | X | | X | ...
    fox | X | X | X | ...
    quick | X | X | | ...
    the | X | | X | ...緩存

  • 倒排索引的不變性
    • 不須要鎖
    • 可被內核的文件系統緩存,停留在內存中,大部分請求會直接請求到內存,不會落到磁盤上
    • filter緩存,在索引的生命週期始終有效。不須要再每次數據改變時重建
    • 寫入單個較大的倒排索引使容許數據被壓縮
  • 如何在索引不變狀況下 動態更新索引
    • 使用更多的索引,來解決這個問題
    • 經過增長新的補充索引來反映新近的修改,而不是直接重寫整個倒排索引
    • 一個 Lucene 索引包含一個提交點和三個段
      elasticsearch

    • 逐段搜索的流程
      • 新文檔被收集到內存索引緩存
      • 不時地, 緩存被 提交
        • 一個新的段----一個追加的倒排索引--被寫入磁盤
        • 一個新的包含新段名字的 提交點 被寫入磁盤
        • 磁盤進行 同步 — 全部在文件系統緩存中等待的寫入都刷新到磁盤
      • 新的段被開啓,讓它包含的文檔可見以被搜索
      • 內存緩存被清空,等待接收新的文檔
    • 一個在內存緩存中包含新文檔的 Lucene 索引
    • 在一次提交後,一個新的段被添加到提交點並且緩存被清空
  • 刪除和更新文檔
    • 段是不可改變的,每一個提交點都會有一個.del文件。在這個文件中能列出這些刪除文檔的短信息
    • 當文檔被刪除時不是刪除,只是在.del文件中被登記
    • 文檔的更新也是這樣的,先將更新的文檔標記爲刪除。而後文檔的新版本被索引到一個新的段中

近實時搜索

  • 提交(Commiting)一個新的段到磁盤須要一個 fsync 來確保段被物理性地寫入磁盤,這樣在斷電的時候就不會丟失數據。可是每次提交的一個新的段都fsync 這樣操做代價過大。可使用下面這種更輕量的方式
  • 在內存緩衝區中包含了新文檔的 Lucene 索引
    • Lucene 容許新段被寫入和打開--使其包含的文檔在未進行一次完整提交時便對搜索可見
  • 緩衝區的內容已經被寫入一個可被搜索的段中,但尚未進行提交
    • 這裏新段會被先寫入到文件系統緩存--這一步代價會比較低,稍後再被刷新到磁盤--這一步代價比較高
  • 默認狀況下每一個分片會每秒自動刷新一次
    • 近 實時搜索: 文檔的變化並非當即對搜索可見,但會在一秒以內變爲可見
    • POST /_refresh // 刷新Refresh 全部的索引
    • POST /blogs/_refresh // 只刷新Refresh blogs 索引
      能夠在settings 設置對定時刷新頻率的大小

    PUT /my_logs
    {
    "settings": {
    "refresh_interval": "30s" //30秒刷新一次
    "refresh_interval": "-1" //關閉自動刷新
    "refresh_interval": "1s"//每秒自動刷新
    }
    }分佈式

    持久化變動
    在沒有 fsync 把數據從內存刷新到硬盤中,咱們不能保證數據在斷電或程序退出時以後依然存在
  • 即時每秒刷新,也不能實現近實時搜索。咱們任然有另外的方法確保從失敗中回覆數據
  • ES 增長一個translog,或者叫作事務日誌。在每次操做是均進行日誌記錄
  • 整個流程是以下的操做
    1. 一個文檔被索引以後,就會被添加到內存緩衝區,而且 追加到了 translog
      -學習

    2. 刷新(refresh)使分片處於緩存被清空,可是事務日誌不會的狀態
      • 內存緩衝區的文檔被寫入新的段中,可是沒有進行fsync
      • 段被打開,且可被搜索到
      • 內存緩衝區被清空
    3. 進程繼續進行,更多的文檔被添加到內存緩衝區和追加的事務日誌中
    4. 每隔一段時間,translog太大 或 索引被刷新。一個新的translog被建立,而且被全量提交
      -ui

      • 全部內存緩衝區的文檔都被寫入一個新的段中
      • 緩衝區內清空
      • 一個提交點被寫入硬盤
      • 文件系統緩存經過fsync被刷新
      • 老的translog 被刪除
  • translog 提供全部沒有被刷新到磁盤操做的一個持久化記錄。當ES啓動時,會根據最後一個提交點去恢復已知的段
  • translog 也可供用來提供實時的CRUD。但咱們進行一些CRUD操做時,它會首先檢查translog任何最近的變動。
  • flush API 執行一次提交,並截斷translog的操做
    • 分片默認每30M自動flush一次。translog太大也會自動flush
    • 可經過本身執行flush API操做設計

      POST /blogs/_flush //刷新索引日誌

      POST /_flush?wait_for_ongoing //刷新索引並等待全部的刷新結果返回htm

段合併
  • 段合併的時候會將那些舊的已刪除的文檔從文件系統中刪除,被刪除或者被更新的文檔不會被複制到新的大段中
  • 段合併的流程
    -blog

    • 當索引的時候,刷新(refresh)操做會建立新的段
    • 合併的時候會選擇一部分大小類似的段,而且將其合併到更大的段中
    • 段的合併結束,老的段就要被刪除
      Alt text
  • optimized API 的做用
    • optimize API大可看作是 強制合併 API 。
相關文章
相關標籤/搜索