Activemq持久化之kahadb特性


介紹
數據的持久化是很多系統都會涉及到的一個問題,尤其是redis,activemq這些數據主要是存儲在內存中的。既然存在內存中,就會面臨宕機時數據丟失的風險。這一問題的解決方案就是通過某種方式將數據寫到磁盤上,也就是所謂的持久化。

activemq提供了三種持久化方式,分別基於jdbc, kahadb和leveldb. 目前官方最推薦的是基於kahadb的持久化。 jdbc是activemq最早提供的一種持久化方式,但是用數據庫去做持久化確實不合適,畢竟性能有瓶頸,而且只是需要簡單的讀寫數據,不需要數據庫各種強大的功能。現在去看文檔的話,連基本的配置都被埋的很深,所以這種方式我們也就不細說了。

正是由於基於jdbc的方式存在的種種問題,activemq后來就接連提供了基於kahabd和leveldb的持久化方式.leveldb 是google開源的一個KV磁盤存儲系統,應用很廣,kahadb沒找着源頭,應該就是activemq團隊開發的,也是一種基於磁盤的存儲系統。按理說,leveldb的性能是要好一些的,之前無論是activemq的默認配置,還是文檔里的推薦使用方法,都是首選leveldb. 但是有一天這個基於leveldb的持久化方式就突然被activemq廢棄了,主要原因是leveldb是一個第三方系統,維護起來不如kahadb那么方便。到當前最新版本,leveldb持久化還存在不少嚴重問題,功能也不如kahadb完善。所以目前來說,最推薦的持久化方式就是kahadb. 接下來介紹一下基本配置。

基本配置

基本配置很簡單,看默認配置里的就可以,打開activemq.xml

<persistenceAdapter>
            <kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

這樣數據會自動同步到kahadb目錄下。可以去目錄下看一下kahadb的文件結構,文件存儲的主體是一系列的.log文件,每條需要持久化的數據會一次寫入,一個log文件到達一定大小后,會新建一個新的。當一個文件內的所有消息都已經被消費完畢后,這個文件會被刪除。

相關參數

具體相關參數可以參閱官方文檔:http://activemq.apache.org/kahadb.html

常見且幾個比較有用的:

  • cleanupInterval 定期檢查哪些文件需要清理的時間間隔,默認為30秒
  • journalMaxFileLength 每個log文件的最大大小,默認32m
  • journalDiskSyncInterval, journalDiskSyncStrategy, journalMaxFileLength: 異步寫磁盤相關的一些參數。異步寫磁盤能夠提升效率,但是會有可能丟失數據

一些使用建議

1.關於日志,可以把kahadb的trace級別的日志打開,在log4j里添加org.apache.activemq.store.kahadb.MessageDatabase這個logger的配置就可以,例如

log4j.appender.kahadb=org.apache.log4j.RollingFileAppender
log4j.appender.kahadb.file=${activemq.base}/data/kahadb.log
log4j.appender.kahadb.maxFileSize=1024KB
log4j.appender.kahadb.maxBackupIndex=5
log4j.appender.kahadb.append=true
log4j.appender.kahadb.layout=org.apache.log4j.PatternLayout
log4j.appender.kahadb.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
log4j.logger.org.apache.activemq.store.kahadb.MessageDatabase=TRACE, kahadb

2.為每個隊列單獨配置存儲目錄

<persistenceAdapter>
  <mKahaDB directory="${activemq.base}/data/kahadb">
    <filteredPersistenceAdapters>
      <!-- kahaDB per destinations -->
      <filteredKahaDB perDestination="true">
        <persistenceAdapter>
          <kahaDB journalMaxFileLength="32mb"/>
        </persistenceAdapter>
      </filteredKahaDB>
    </filteredPersistenceAdapters>
  </mKahaDB>
 </persistenceAdapter>

這樣做的原因還是和存儲空間有關,kahadb寫文件時是按消息順序依次寫入的,刪文件時則要等到這個文件內的所有消息被消費完畢。也就是說,即使這個文件里只有一條消息沒被消費掉,也需要占用完整的空間。如果本身隊列特別多,恰好有一個隊列消費沒跟上,可能它本身占用空間非常小,但是會占用大量磁盤空間無法釋放。給每個隊列分別配置的話就可以大大緩解這一情況。

參考鏈接:http://lichuanyang.top/posts/31044/ 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM