吐血總結了各個中介軟體是如何實現持久化的
到目前為止,我也已經接觸到了不少的中介軟體了,比如說「Elasticsearch」「Redis」「HDFS」「Kafka」「HBase」等等。
可以發現的是,它們的持久化機制都差不得太多。今天想來總結一下,一方面想來回顧一下這些元件,一方面給還沒入門過這些中介軟體的同學總結一下持久化的”套路“,後面再去學習的時候就會輕鬆很多。
持久化
下面我們就直接來分別回顧一下各個中介軟體/元件的持久化機制,最後再總結就好了。
為什麼要持久化?原因也很簡單:資料需要儲存下來,不希望出了問題導致資料丟失
Elasticsearch
Elasticsearch是一個全文搜尋引擎,對模糊搜尋非常擅長。
Elasticsearch在寫資料的時候,會先寫到記憶體快取區,然後寫到translog快取區,每隔5s將translog緩衝區的資料刷到磁碟中
Kafka
眾所周知,Kafka是一個高吞吐量的訊息佇列,那它是怎麼持久化的呢?
Kafka relies heavily on thefilesystemfor storing and caching messages.
沒錯Kafka用的是檔案系統來儲存的。
在Kafka官網上其實也說了,Kafka的持久化依賴作業系統的pagecache和順序寫來實現的。
HDFS
HDFS是分散式檔案系統,能儲存海量的資料,那HDFS在寫入資料的時候是怎麼樣的呢?
HDFS Client客戶端無論讀寫都需要走到NameNode去獲取/增刪改檔案的元資料,而NameNode則是專門維護這些元資料的地方。
所以,在HDFS寫資料,需要先去NameNode上詢問這些切分好的block往哪幾個DataNode上寫資料。
為了提高NameNode的效率,在寫資料的時候,NameNode實際上是操作的是記憶體,然後涉及到增刪改的資料順序寫到editlog日誌檔案上
Redis
Redis是基於記憶體的,如果不想辦法將資料儲存在硬碟上,一旦Redis重啟(退出/故障),記憶體的資料將會全部丟失。
我們肯定不想Redis裡頭的資料由於某些故障全部丟失(導致所有請求都走MySQL),即便發生了故障也希望可以將Redis原有的資料恢復過來,所以Redis有RDB和AOF的持久化機制。
RDB:基於快照,將某一時刻的所有資料儲存到一個RDB檔案中。
AOF(append-only-file),當Redis伺服器執行寫命令的時候,將執行的寫命令儲存到AOF檔案中。
AOF持久化功能的實現可以分為3個步驟:
命令追加:命令寫入aof_buf緩衝區
檔案寫入:呼叫flushAppendOnlyFile函式,考慮是否要將aof_buf緩衝區寫入AOF檔案中
檔案同步:考慮是否將記憶體緩衝區的資料真正寫入到硬碟
HBase
HBase是一個能儲存海量資料的資料庫。
HBase在寫資料的時候,會先寫到Mem Store,當MemStore超過一定閾值,就會將記憶體中的資料刷寫到硬碟上,形成StoreFile,而StoreFile底層是以HFile的格式儲存,HFile是HBase中KeyValue資料的儲存格式。
我們寫資料的時候是先寫到記憶體的,為了防止機器宕機,記憶體的資料沒刷到磁碟中就掛了。我們在寫Mem store的時候還會寫一份HLog
MySQL
MySQL我們用得最多的InnoDB引擎是怎麼儲存的呢?它有redo log來支撐持久化的功能。
MySQL引入了redo log,記憶體寫完了,然後會寫一份redo log,這份redo log記載著這次在某個頁上做了什麼修改。
總結
看完上面常見的中介軟體/元件的持久化方式,應該就不用我多說了吧?思想幾乎都是一樣的,只是他們記錄“log”的名字不一樣而已。
先寫buffer,然後順序IO寫Log。防止buffer的資料還沒刷到磁碟,宕機導致資料丟失。
對於Log檔案,中介軟體也不會放任它們一直膨脹,導致體積很大:
在Redis裡邊,會對AOF檔案進行重寫
在HDFS裡邊,editlog會定時生成fsimage
在Elasticsearch裡邊,translog會根據閾值觸發commit操作
.....