ActiveMQ消息持久化

什麼是消息持久化

在發送者將消息發送出去後,消息中心首先將消息存儲到本地數據文件、內存數據庫或者遠程數據庫等,而後試圖將消息發送給接收者,發送成功則將消息從存儲中刪除,失敗則繼續嘗試。
 
消息中心啓動之後首先要檢查制定的存儲位置,若是有未發送成功的消息,則須要把消息發送出去。    
 

ActiveMQ持久化方式

AMQ、KahaDB、JDBC、LevelDB。

AMQ

AMQ是一種文件存儲形式,它具備寫入速度快和容易恢復的特色。消息存儲在一個個文件中,文件的默認大小爲32M,若是一條消息的大小超過了32M,那麼這個值必須設置大一點。當一個存儲文件中的消息已經所有被消費,那麼這個文件將被標識爲可刪除,在下一個清除階段,這個文件被刪除。AMQ適用於ActiveMQ5.3以前的版本。

KahaDB

KahaDB是基於 文件的本地數據庫儲存形式,雖然沒有AMQ的速度快,可是它具備強擴展性,恢復的時間比AMQ短,從5.4版本以後KahaDB作爲默認的持久化方式。
KahaDB是一種 可嵌入式的事務性的持久化機制
 
KahaDB,主要特性有: 
一、日誌形式存儲消息。 
二、消息索引以B-Tree結構存儲,能夠快速更新 
三、徹底支持JMS事務
四、支持多種恢復機制
 
 
 
        上圖展現的是KahaDB的結構圖。消息存儲在 基於文件的數據日誌中。若是消息發送成功,變 標記爲可刪除的。
        系統會週期性的清除或者歸檔日誌文件。
        消息文件的位置索引存儲在內存中,這樣能快速定位到。按期將內存中的 消息索引保存到metadata store中,避免大量消息未發送時,消息索引佔用過多內存空間。
 
Data logs 
        數據日誌中保存着消息以及目的地、訂閱、事務等相關信息。這些信息在日誌文件中並未按照一個特定的格式來保存,因此就須要索引各種信息,以便能快速定位到。 
Metadata cache 
        在 內存中保存日誌文件中各種信息的索引,索引信息包含一個 MessageId與消息在日誌文件中的偏移量的對應關係。
全部索引以B-Tree結構存在內存中,便於在一個有序的list上快速的查找,插入以及刪除。內存中的消息索引會按期的保存到Metadata store中。具體時間週期能夠設置checkpointInterval屬性。理想狀況下Metadata cache越大愈好,這樣在定位消息的時候就不盡可能少的去Metadata store中獲取索引了。實際能夠參考db.data文件的大小來設置。indexCacheSize 即是設置緩存的大小。 
Metadata store 
        在db.data文件中保存消息日誌中 消息的元數據,也是以B-Tree結構存儲的,定時從Metadata cache更新數據。同時,Metadata store中也會備份一些在消息日誌中存在的信息,這樣可讓Broker實例快速啓動。即使metadata store文件被破壞或者誤刪除了。broker能夠讀取Data logs恢復過來,只是速度會相對較慢些。 
 
Metadata cache與Metadata store同步 
KahaDB提供了兩種觸發同步設置 
一、設定一個閥值,當Metadata cache與Metadata store中的索引不一樣的數量達到這個閥值時,觸發同步。indexWriteBatchSize 
即是設置這個閥值。 
二、設置一個時間週期,當時間週期到了後,無論Metadata cache與Metadata store是否不一樣,都觸發同步。 
經過checkpointInterval設置一個時間週期。 
 
一般爲了達到更高的性能,會將indexWriteBatchSize值設置很大。只在到達checkpointInterval時間點時才同步。這樣作的風險就是有可能在系統意外down機時丟失部分metadata信息。 

JDBC

能夠將消息存儲到數據庫中,例如:Mysql、SQL Server、Oracle、DB2。
dataSource指定持久化數據庫的bean,createTablesOnStartup是否在啓動的時候建立數據表,默認值是true,這樣每次啓動都會去建立數據表了,通常是第一次啓動的時候設置爲true,以後改爲false。
 

LevelDB

這種文件系統是從ActiveMQ5.8以後引進的,它和KahaDB很是類似,也是基於 文件的本地數據庫儲存形式,可是它提供比KahaDB更快的持久性。
與KahaDB不一樣的是,它 不是使用傳統的B-樹來實現對日誌數據的提早寫,而是使用基於索引的LevelDB
 
 
 

與Kafka持久化對比

Kafka的存儲佈局很是簡單。話題的每一個分區對應一個邏輯日誌。物理上,一個日誌爲相同大小的一組分段文件。每次生產者發佈消息到一個分區,代理就將消息追加到最後一個段文件中。當發佈的消息數量達到設定值或者通過必定的時間後,段文件真正寫入磁盤中。寫入完成後,消息公開給消費者。
 
與傳統的消息系統不一樣,Kafka系統中存儲的消息沒有明確的消息Id。
 
消息經過 日誌中的邏輯偏移量(只存儲位置信息)來公開。這樣就避免了維護配套密集尋址,用於映射消息ID到實際消息地址的隨機存取索引結構的開銷。消息ID是增量的,但不連續。要計算下一消息的ID,能夠在其邏輯偏移的基礎上加上當前消息的長度。
 
消費者始終從特定分區順序地獲取消息,若是消費者知道特定消息的偏移量,也就說明消費者已經消費了以前的全部消息。消費者向代理髮出異步拉請求,準備字節緩衝區用於消費。每一個異步拉請求都包含要消費的消息偏移量。Kafka利用sendfile API高效地從代理的日誌段文件中分發字節給消費者。
相關文章
相關標籤/搜索