對elasticsearch持久化變更的一點理解

refresh–可搜索但還未持久化

數據寫到一個新的segment 實現了1s(默認)的實時搜索。

fsync --持久化

提交(Commiting)一個新的段到磁盤需要一個 fsync 來確保段被物理性地寫入磁盤。

flush --持久化

所有在內存緩衝區的文檔都被寫入一個新的段,生成一個新的提交點。這個執行一個提交併且截斷 translog 的行爲在 Elasticsearch 被稱作一次 flush 。 分片每30分鐘被自動刷新(flush),或者在 translog 太大的時候也會刷新。 — 暫時不用管這段定義。

爲了ES數據的可靠–持久化

ES通過 refresh數據到segment 實現了1s(默認)的實時搜索,
也想要保證操作(插入、更新、刪除)不丟失。但是fsync把數據刷新到磁盤太耗資源。於是決定定時(默認30分鐘)刷新(flush)到磁盤。這裏讓我想到了redis的RDB 快照。
新問題出來了,30分鐘才持久化一次,那麼兩次持久化之間(30分鐘)的數據丟失了怎麼辦?
於是引入了 translog,在操作被refresh到segment之前已經先進入了translog。當重啓ES後, 會恢復到最近的一個提交點後,再重放translog裏面的操作,保證提交點生成之後的數據操作。但是translog本身還不在磁盤中,重啓也會導致translog丟失。

translog持久化

對於一些大容量的偶爾丟失幾秒數據問題也並不嚴重的集羣,使用異步的 fsync 還是比較有益的。

所以讓translog 5s刷新一次到磁盤。

PUT /my_index/_settings { "index.translog.durability": "async", "index.translog.sync_interval": "5s" }

Redis的AOF 不也是這樣嗎:AOF everysec 每秒刷一次到磁盤。
引用下別人的圖片方便理解:
引用來自網絡的圖片

總結

redis兩種持久化機制:
a.執行操作(對照es的refresh到segment階段),然後定時(或一定操作次數後)RDB生成快照。
b.執行操作並記錄操作日誌(AOF),默認 1s異步追加到日誌文件中(持久化操作日誌,對照es的index.translog.sync_interval:5s)。

ES:
將 RDB 與AOF結合了起來:記錄操作日誌translog到內存,然後執行操作到內存(用戶可正常查詢了)。定時持久化translog(a),定時生成提交點(b),刪除translog。

ps:寫着寫着感覺沒寫些啥, 就是抄了官網。之前讀文檔感覺懂了,但是事後一點兒都想不起來。 今天跟羣友討論突然發現ES這種持久化機制跟Redis持久化非常像,故寫下來幫助自己理解。
ps:MySQL也是這樣做的,參考《MySQL技術內幕 innodb存儲引擎》7.2.1 redo章節。

參考

持久化變更
elasticsearch中 refresh 和flush區別

發佈了118 篇原創文章 · 獲贊 47 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章