一文輕鬆圖解搞懂 Elasticsearch 原理!
大家好, 我是 風哥
ES 的集羣模式和 kafka 很像,kafka 又和 redis 的集羣模式很像。總之就是相互借鑑!
不管你用沒用過 ES,今天我們一起聊聊它。就當擴展大家的知識廣度了!
認識倒排索引
正排索引 VS 倒排索引
倒排索引包括兩個部分
- 單詞詞典(Term Dictionary):記錄所有文檔的單詞,記錄單詞到倒排列表的關聯關係
單詞詞典一般比較大,可以通過 B+ 樹 或 哈希拉鍊法實現,以滿足高性能的插入與查詢
-
倒排列表(Posting List):記錄了單詞對應的文檔結合,由倒排索引項(Posting)組成:
-
文檔 ID
-
詞頻 TF:該單詞在文檔中出現的次數,用於相關性評分
-
位置(Position):單詞在文檔中分詞的位置。用於語句搜索(Phrase Query)
-
偏移(Offset):記錄單詞的開始結束位置,實現高亮顯示
ElasticSearch 的倒排索引:
-
ElasticSearch 的 JSON 文檔中的每個字段,都有自己的倒排索引
-
可以針對某些字段不做索引
-
優點:節省存儲空間
-
缺點:字段無法被搜索
分佈式架構原理
分片 shard:一個索引可以拆分成多個 shard 分片。
-
主分片 primary shard:每個分片都有一個主分片。
-
備份分片 replica shard:主分片寫入數據後,會將數據同步給其他備份分片。
將 ES 集羣部署在 3 個 機器上(esnode1、esnode2、esnode3):
創建個索引,分片爲 3 個,副本數設置爲 1:
PUT /sku_index/_settings
{
"settings": {
"number_of_shards" : 3,
"number_of_replicas": 1
}
}
響應:
{
"acknowledged" : true
}
ES 集羣中有多個節點,會自動選舉一個節點爲 master 節點,如上圖的 esnode2 節點:
-
主節點(master):管理工作,維護索引元數據、負責切換主分片和備份分片身份等。
-
從節點(node):數據存儲。
集羣中某節點宕機:
-
主節點宕機:會重新選舉一個節點爲 主節點。
-
從節點宕機:由 主節點,將宕機節點上的 主分片身份轉移到其他機器上的 備份分片上。
寫入數據的工作原理
寫單個文檔所需的步驟:
-
客戶端選擇一個 Node 發送請求,那麼這個 Node 就稱爲 協調節點(Coorinating Node)。
-
Node 使用文檔 ID 來確定文檔屬於分片 0,通過集羣狀態中的內容路由表信息獲知分片 0 的主分片在 Node1 上,因此將請求轉發到 Node1 上。
-
Node1 上的主分片執行寫操作。如果寫入成功,則將請求並行轉發到 Node3 的副分片上,等待返回結果。
當所有的副分片都報告成功,Node1 將向 Node (協調節點)報告成功。
Tips
:客戶端收到成功響應時,意味着寫操作已經在主分片和所有副分片都執行完成。
寫數據底層原理
寫操作可分爲 3 個主要操作:
- 寫入新文檔: 這時候搜索,是搜索不到。
-
將數據寫入內存
-
將這操作寫入 translog 文件中
- refresh 操作: 默認每隔 1s ,將內存中的文檔寫入文件系統緩存(filesystem cache)構成一個 segment
這時候搜索,可以搜索到數據。
- 1s 時間:ES 是近實時搜索,即數據寫入 1s 後可以搜索到。
- flush 操作: 默認每隔 30 分鐘 或者 translog 文件 512MB ,將文件系統緩存中的 segment 寫入磁盤,並將 translog 刪除。
-
translog 文件:來記錄兩次 flush(fsync) 之間所有的操作,當機器從故障中恢復或者重啓,可以根據此還原
-
translog 是文件,存在於內存中,如果掉電一樣會丟失。
-
默認每隔 5s 刷一次到磁盤中
讀取數據的工作原理
讀取文檔所需的步驟:
-
客戶端選擇一個 Node 發送請求,那麼這個 Node 就稱爲 協調節點(Coorinating Node)。
-
Node 使用文檔 ID 來確定文檔屬於分片 0,通過集羣狀態中的內容路由表信息獲知分片 0 有 2 個副本數據(一主一副),會使用隨機輪詢算法選擇出一個分片,這裏將請求轉發到 Node1
-
Node1 將文檔返回給 Node,Node 將文檔返回給客戶端。
在讀取時,文檔可能已經存在於主分片上,但還沒有複製到副分片,這種情況下:
-
讀請求命中副分片時,可能會報告文檔不存在。
-
讀請求命中主分片時,可能成功返回文檔。
搜索工作原理
搜索數據過程:
-
客戶端選擇一個 Node 發送請求,那麼這個 Node 就稱爲 協調節點(Coorinating Node)。
-
Node 協調節點將搜索請求轉發到所有的 分片(shard):主分片 或 副分片,都可以。
-
query 階段:每個分片 shard 將自己的搜索結果(文檔 ID)返回給協調節點,由協調節點進行數據的合併、排序、分頁等操作,產出最終結果。
-
fetch 階段:由協調節點根據 文檔 ID 去各個節點上拉取實際的文檔數據。
舉個栗子: 有 3 個分片,查詢返回前 10 個匹配度最高的文檔
-
每個分片都查詢出當前分片的 TOP 10 數據
-
協調節點 將 3 * 10 = 30 的結果再次排序,返回最終 TOP 10 的結果
刪除 / 更新數據底層原理
-
刪除操作:commit 的時候會生成一個 .del 文件,裏面將某個 doc 標識爲 deleted 狀態,那麼搜索的時候根據 .del 文件就知道這個 doc 是否被刪除了。
-
更新操作:就是將原來的 doc 標識爲 deleted 狀態,然後新寫入一條數據。
底層邏輯是:
-
Index Buffer 每次 refresh 操作,就會產生一個 segment file。(默認情況:1 秒 1 次)
-
定製執行 merge 操作:將多個 segment file 合併成一個,同時將標識爲 deleted 的 doc 物理刪除,將新的 segment file 寫入磁盤,最後打上 commit point 標識所有新的 segment file。
來源:juejin.cn/post/7110610301669605383
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/tPEP6r5iku12zoyR4CstNA