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章節。