消息的持久化策略分析mysql
- 消息持久性對於可靠消息傳遞來講是一種比較好的方法,
- 即時發送者和接受者不是同時在線或者消息中心在發送者發送消息後宕機了,在消息中心重啓後仍然能夠將消息發送出去。
- 消息持久性的原理很簡單,
- 就是在發送消息出去後,消息中心首先將消息存儲在本地文件、內存或者遠程數據庫,
- 而後把消息發送給接受者,
- 發送成功後再把消息從存儲中刪除,失敗則繼續嘗試。
- 接下來咱們來了解一下消息在broker上的持久化存儲實現方式
持久化存儲支持類型sql
- ActiveMQ支持多種不一樣的持久化方式,主要有如下幾種,不過,不管使用哪一種持久化方式,消息的存儲邏輯都是一致的。
- Ø KahaDB存儲(默認存儲方式)
- Ø JDBC存儲
- Ø Memory存儲
- Ø LevelDB存儲
- Ø JDBC With ActiveMQ Journal
KahaDB存儲數據庫
- KahaDB是目前默認的存儲方式,可用於任何場景,提升了性能和恢復能力。
- 消息存儲使用一個事務日誌和僅僅用一個索引文件來存儲它全部的地址。
- KahaDB是一個專門針對消息持久化的解決方案,它對典型的消息使用模式進行了優化。
- 在Kaha中,數據被追加到data logs中。
- 當再也不須要log文件中的數據的時候,log文件會被丟棄。
KahaDB的配置方式apache
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
KahaDB的存儲原理緩存
- 在data/kahadb這個目錄下,會生成四個文件:
Ø db.data 它是消息的索引文件,本質上是B-Tree(B樹),使用B-Tree做爲索引指向db-*.log裏面存儲的消息
Ø db.redo 用來進行消息恢復
Ø db-*.log 存儲消息內容。tcp
- 新的數據以APPEND的方式追加到日誌文件末尾。
- 屬於順序寫入,所以消息存儲是比較快的。
- 默認是32M,達到閥值會自動遞增
Ø lock文件 鎖,表示當前得到kahadb讀寫權限的broker性能
JDBC存儲優化
- 使用JDBC持久化方式,數據庫會建立3個表:activemq_msgs,activemq_acks和activemq_lock。
- ACTIVEMQ_MSGS 消息表,queue和topic都存在這個表中
- ACTIVEMQ_ACKS 存儲持久訂閱的信息和最後一個持久訂閱接收的消息ID
- ACTIVEMQ_LOCKS 鎖表,用來確保某一時刻,只能有一個ActiveMQ broker實例來訪問數據庫
JDBC存儲實踐url
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="# MySQL-DS " createTablesOnStartup="true" />
</persistenceAdapter>
- dataSource指定持久化數據庫的bean,
- createTablesOnStartup是否在啓動的時候建立數據表,默認值是true,
- 這樣每次啓動都會去建立數據表了,
- 通常是第一次啓動的時候設置爲true,以後改爲false
Mysql持久化Bean配置日誌
<bean id="Mysql-DS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.11.156:3306/activemq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
添加Jar包依賴

LevelDB存儲
- LevelDB持久化性能高於KahaDB,雖然目前默認的持久化方式仍然是KahaDB。
- 而且,在ActiveMQ 5.9版本提供了基於LevelDB和Zookeeper的數據複製方式,用於Master-slave方式的首選數據複製方案。
- 不過,據ActiveMQ官網對LevelDB的表述:LevelDB官方建議使用以及再也不支持,推薦使用的是KahaDB
<persistenceAdapter>
<levelDBdirectory="activemq-data"/>
</persistenceAdapter>
Memory 消息存儲
- 基於內存的消息存儲,內存消息存儲主要是存儲全部的持久化的消息在內存中。
- persistent=」false」,表示不設置持久化存儲,直接存儲到內存中
<beans>
<broker brokerName="test-broker"
persistent="false"xmlns="http://activemq.apache.org/schema/core">
<transportConnectors>
<transportConnector uri="tcp://localhost:61635"/>
</transportConnectors>
</broker>
</beans>
JDBC Message store with ActiveMQ Journal
- 這種方式克服了JDBC Store的不足,JDBC每次消息過來,都須要去寫庫和讀庫。
- ActiveMQ Journal,使用高速緩存寫入技術,大大提升了性能。
- 當消費者的消費速度可以及時跟上生產者消息的生產速度時,journal文件可以大大減小須要寫入到DB中的消息。
- 舉個例子,生產者生產了1000條消息,這1000條消息會保存到journal文件,
- 若是消費者的消費速度很快的狀況下,在journal文件尚未同步到DB以前,消費者已經消費了90%的以上的消息,
- 那麼這個時候只須要同步剩餘的10%的消息到DB。
- 若是消費者的消費速度很慢,這個時候journal文件可使消息以批量方式寫到DB。
- Ø 將原來的標籤註釋掉
- Ø 添加以下標籤
- Ø 在服務端循環發送消息。能夠看到數據是延遲同步到數據庫的
<persistenceFactory>
<journalPersistenceAdapterFactory dataSource="#Mysql-DS" dataDirectory="activemqdata"/>
</persistenceFactory>