深入分析Elastic Search的寫入過程

摘要

之前寫過一篇ElasticSearch初識之吐槽,不知覺竟然過去了兩年了。哎,時光催人老啊。最近又用到了ES,想找找過去的總結文檔,居然只有一篇,搞了半年的ES,遇到那麼多的問題,產出只有這麼點,真是說不過去啊。只好又重新撿起ES,發現ES槽點依然很多,不兼容的更新太多了,各個版本之間的差異不小,感覺ES就是偏理論算法的人設計出來的,而不是工程學家寫的。非常像公司裏面,算法工程師吐槽後端應用開發算法能力弱,後端應用開發吐槽算法工程師工程能力太差。作爲一個應用開發對ES差不多就是這種感覺。不過要用到搜索,不用他又不行。既然不能拒絕,只能去享受了。

寫入分析

爲什麼要分析寫入了,因爲好奇唄。比如有如下問題一直困惑着我

  1. 爲什麼es會丟數據
  2. 什麼樣的節點可以是coordinate node
  3. refresh index和flush index是什麼操作
  4. memory buffer,filesystem cache都存在什麼地方。
  5. 集羣中的節點如何配合寫入的
  6. 數據怎麼存放的
  7. 爲什麼寫入到filesystem cache中就可以索引了

寫入概覽

首先我們從分佈式集羣的角度分析下寫入,採用系統默認的參數來說明

集羣有三個節點,都存儲數據,indexA 有5個分片,2個複製集。
數據如下分佈
Node1: shard1
Node2: shard2,shard3,shard1-R1(shard1的複製集)
Node3: shard4,shard5,shard-R2(shard1的複製集)

爲了簡化問題,shard2,shard5等shard的複製集忽略問題了。
現在以寫入shard1爲例說明問題。

  1. 首先客戶端根據配置的連接節點,通過輪詢方式連接到一個coordinate節點。

coordinate節點不是很master/client/data節點一個維度的描述,它就是指處理客戶端請求的節點。這個描述和cassandra的coordinate節點是一個概念。集羣中所有的節點都可以是coordinate節點。

  1. coodinate節點通過hash算法計算出數據在shard1上shard = hash(document_id) % (num_of_primary_shards),然後根據節點上維護的shard信息,將請求發送到node1上。
  2. node1 對索引數據進行校驗,然後寫入到shard中。具體細節見下一節寫入到shard
  3. 主節點數據寫入成功後,將數據並行發送到副本集節點Node2,Node3。
  4. Node2,Node3寫入數據成功後,發送ack信號給shard1主節點Node1。
  5. Node1發送ack給coordinate node
  6. coordinate node發送ack給客戶端。

整個過程coordinate node部分類似cassandra,主shard節點和副本集受master-slave模式影響,必須有master決定寫入成功與否,和mysql類似的。

寫入shard

上面第三步驟,shard內寫入還需要詳細分析下

  1. 數據寫入到內存buffer
  2. 同時寫入到數據到translog buffer
  3. 每隔1s數據從buffer中refresh到FileSystemCache中,生成segment文件,一旦生成segment文件,就能通過索引查詢到了
  4. refresh完,memory buffer就清空了。
  5. 每隔5s中,translog 從buffer flush到磁盤中
  6. 定期/定量從FileSystemCache中,結合translog內容flush index到磁盤中。做增量flush的。

各種數據庫的單節點寫入過程大同小異,一般都是寫內存,記錄操作日誌(防止節點宕機,內存中的數據丟失)然後flush到磁盤,有個線程不斷的merge 數據塊。不過是寫入的數據格式不同。

另外分佈式或者主從式部署結構,又需要將寫入的數據複製到不同的節點,這個過程比較複雜,每個數據庫處理也有不同的邏輯。

elastic search 寫入的中間過程還多了一層buffer,我們知道buffer和cache雖然都是爲了提高寫入效率,但是工作原理不同,

1、Buffer(緩衝區)是系統兩端處理速度平衡(從長時間尺度上看)時使用的。它的引入是爲了減小短期內突發I/O的影響,起到流量整形的作用。比如生產者——消費者問題,他們產生和消耗資源的速度大體接近,加一個buffer可以抵消掉資源剛產生/消耗時的突然變化。
2、Cache(緩存)則是系統兩端處理速度不匹配時的一種折衷策略。因爲CPU和memory之間的速度差異越來越大,所以人們充分利用數據的局部性(locality)特徵,通過使用存儲系統分級(memory hierarchy)的策略來減小這種差異帶來的影響。

所以寫入到buffer中的數據,還是原始數據,還沒有索引,搜索不到的。只有到Cache中還可以。

和MySQL,Cassandra,Mongo的寫入對比

數據庫寫入過程都需要寫入操作日誌,複製集日誌,不同的數據庫不一樣的處理方法。
有些數據庫是共用的,有些數據庫則是分開的。

寫操作日誌的過程一般是直接寫入磁盤的,因爲它本身就是防止進程,機器宕機造成內存數據丟失,而用來恢復數據的。寫入buffer中又會可能會導致數據的丟失。所以像elastic search mysql innodb這種操作日誌寫buffer的也會提供配置項,來保證當事務成功後,操作日誌會被刷盤的。不過es 的操作日誌最小刷盤不能低於100ms.

下面是各個數據庫的日誌對比,相同的功能,但是每個創建者都有自己的逼格,需要有不同的命名。

數據庫 記錄日誌,刷磁盤 複製日誌 備註
cassandra commit log commit log commit log 直接寫磁盤的
mongo journal oplog journal log寫磁盤的
mysql redo logs bin log redo logs寫buffer的,
elastic search translog translog 寫buffer的

有興趣的同學可以之前寫過的mongo,cassandra寫入分析

mongo寫入分析

cassandra寫入分析

關注公衆號【方丈的寺院】,第一時間收到文章的更新,與方丈一起開始技術修行之路
在這裏插入圖片描述

參考

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-translog.html

https://www.elastic.co/pdf/architecture-best-practices.pdf

https://lalitvc.files.wordpress.com/2018/05/mysql_architecture_guide.pdf

https://www.infoq.cn/article/analysis-of-elasticsearch-cluster-part01

https://blog.insightdatascience.com/anatomy-of-an-elasticsearch-cluster-part-i-7ac9a13b05db

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