深入分析Elastic Search的寫入過程
摘要
之前寫過一篇ElasticSearch初識之吐槽,不知覺竟然過去了兩年了。哎,時光催人老啊。最近又用到了ES,想找找過去的總結文件,居然只有一篇,搞了半年的ES,遇到那麼多的問題,產出只有這麼點,真是說不過去啊。只好又重新撿起ES,發現ES槽點依然很多,不相容的更新太多了,各個版本之間的差異不小,感覺ES就是偏理論演算法的人設計出來的,而不是工程學家寫的。非常像公司裡面,演算法工程師吐槽後端應用開發演算法能力弱,後端應用開發吐槽演算法工程師工程能力太差。作為一個應用開發對ES差不多就是這種感覺。不過要用到搜尋,不用他又不行。既然不能拒絕,只能去享受了。
寫入分析
為什麼要分析寫入了,因為好奇唄。比如有如下問題一直困惑著我
- 為什麼es會丟資料
- 什麼樣的節點可以是coordinate node
- refresh index和flush index是什麼操作
- memory buffer,filesystem cache都存在什麼地方。
- 叢集中的節點如何配合寫入的
- 資料怎麼存放的
- 為什麼寫入到filesystem cache中就可以索引了
寫入概覽
首先我們從分散式叢集的角度分析下寫入,採用系統預設的引數來說明
叢集有三個節點,都儲存資料,indexA 有5個分片,2個複製集。
資料如下分佈
Node1: shard1
Node2: shard2,shard3,shard1-R1(shard1的複製集)
Node3: shard4,shard5,shard-R2(shard1的複製集)
為了簡化問題,shard2,shard5等shard的複製集忽略問題了。
現在以寫入shard1為例說明問題。
首先客戶端根據配置的連線節點,通過輪詢方式連線到一個coordinate節點。
coordinate節點不是很master/client/data節點一個維度的描述,它就是指處理客戶端請求的節點。這個描述和cassandra的coordinate節點是一個概念。叢集中所有的節點都可以是coordinate節點。
- coodinate節點通過hash演算法計算出資料在shard1上
shard = hash(document_id) % (num_of_primary_shards)
- node1 對索引資料進行校驗,然後寫入到shard中。具體細節見下一節
寫入到shard
。 - 主節點資料寫入成功後,將資料並行傳送到副本集節點Node2,Node3。
- Node2,Node3寫入資料成功後,傳送ack訊號給shard1主節點Node1。
- Node1傳送ack給coordinate node
coordinate node傳送ack給客戶端。
整個過程coordinate node部分類似cassandra,主shard節點和副本集受master-slave模式影響,必須有master決定寫入成功與否,和mysql類似的。
寫入shard
上面第三步驟,shard內寫入還需要詳細分析下
- 資料寫入到記憶體buffer
- 同時寫入到資料到translog buffer
- 每隔1s資料從buffer中refresh到FileSystemCache中,生成segment檔案,一旦生成segment檔案,就能通過索引查詢到了
- refresh完,memory buffer就清空了。
- 每隔5s中,translog 從buffer flush到磁碟中
- 定期/定量從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