1. 程式人生 > >深入分析Elastic Search的寫入過程

深入分析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節點。

  2. coodinate節點通過hash演算法計算出資料在shard1上shard = hash(document_id) % (num_of_primary_shards)
    ,然後根據節點上維護的shard資訊,將請求傳送到node1上。
  3. node1 對索引資料進行校驗,然後寫入到shard中。具體細節見下一節寫入到shard
  4. 主節點資料寫入成功後,將資料並行傳送到副本集節點Node2,Node3。
  5. Node2,Node3寫入資料成功後,傳送ack訊號給shard1主節點Node1。
  6. Node1傳送ack給coordinate node
  7. 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-7ac9a13b0