ActiveMQ 中的訊息持久化(一)

五柳-先生發表於2015-11-18
為了防止系統意外down機丟失訊息,同時能在系統恢復後能重新傳送原來未傳送的訊息。一般訊息系統都會採用持久化機制。Activemq5.4提供了幾種持久化機制: 
1、KahaDB message store 
2、Journaled JDBC adapter 
3、Non-journaled JDBC adapter 

    為了保持後向相容性,Activemq5.4同樣提供以前版本中的持久化機制。例如:AMQ message store以及 Kaha persistence adapter。5.4中預設的採用KahaDB,KahaDB是一種可嵌入式的事務性的持久化機制。要啟用或禁用持久化可以通過配置檔案中的broker標籤中的persistent屬性設定 
Xml程式碼  收藏程式碼
  1. <broker persistent="false" ...>  
  2.   ...  
  3. </broker>  

true : 啟用持久化 
false : 禁用持久化,即便是在配置檔案中配置了persistence adapter。 

修改配置檔案中的persistenceAdapter或者persistenceFactory可以修改Activemq提供的預設機制。具體可以檢視後面的配置檔案。 

下面詳細介紹KahaDB,主要特性有: 
1、日誌形式儲存訊息。 
2、訊息索引以B-Tree結構儲存,可以快速更新 
3、完全支援JMS事務 
4、支援多種恢復機制 
下面是KahaDB的一段簡短配置: 
Xml程式碼  收藏程式碼
  1. <broker brokerName="broker" persistent="true" useShutdownHook="false">  
  2.   ...  
  3.   <persistenceAdapter>  
  4.     <kahaDB directory="activemq-data" journalMaxFileLength="32mb"/>  
  5.   </persistenceAdapter>  
  6. </broker>  

directory : 指定持久化訊息的儲存目錄 
journalMaxFileLength : 指定儲存訊息的日誌檔案大小,具體根據你的實際應用配置 



    上圖展示的是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提供了兩種觸發同步設定 
1、設定一個閥值,當Metadata cache與Metadata store中的索引不同的數量達到這個閥值時,觸發同步。indexWriteBatchSize 
便是設定這個閥值。 
2、設定一個時間週期,當時間週期到了後,不管Metadata cache與Metadata store是否不同,都觸發同步。 
通過checkpointInterval設定一個時間週期。 

通常為了達到更高的效能,會將indexWriteBatchSize值設定很大。只在到達checkpointInterval時間點時才同步。這樣做的風險就是有可能在系統意外down機時丟失部分metadata資訊。 

相關文章