ActiveMQ 消息存储和持久化

  • 官方链接:http://activemq.apache.org/persistence
  • 之前已经简单地聊过了在代码层面,如何选择是否消息持久化链接,而在这一篇,将着眼于ActiveMQ的持久化的底层实现的选择。

1. 概述

  • 持久化,就是将消息存储在本地数据文件或者数据库当中,实现关机、掉电数据也不会损失的技术。
  • 而针对ActiveMQ 来说,有几种常见的技术:
    • AMQ Message Store
    • kahaDB
    • JDBC消息存储
    • LevelDB消息存储
    • JDBC Message Store with ActiveMQ Journal

2. AMQ Message Store

  • 基于文件的存储机制,是以前的默认机制,现在不再使用。
  • AMQ是一种文件存储形式,它具有写入速度快和容易恢复的特点。消息存储再一个个文件中文件的默认大小为32M,当一个文件中的消息已经全部被消费,那么这个文件将被标识为可删除,在下一个清除阶段,这个文件被删除。AMQ适用于ActiveMQ5.3之前的版本

3. kahaDB

  • 官方文档:http://activemq.aache.org/kahadb
  • 该存储机制,自ActiveMQ 5.4开始是默认的持久化插件。
  • 在配置文件中,可以看出,目前使用的的确是这个。
    在这里插入图片描述
  • 而kahaDB的文件,存储在data文件夹中
    在这里插入图片描述
  • 上面几个文件实现了保存所有持久化消息。
    • db-1.log:真实保存所有数据的地方,当一个文件满了之后,就会开第二个,db-2.log以此类推。当不再有引用到数据文件中的任何消息时,文件会被删除或归档。
    • db.data:索引文件,底层就是BTree,提高查找的能力。
    • db.free:当前db.data文件里哪些页面是空闲的,文件具体内容是所有空闲页的ID
    • db.redo:用来做消息恢复,恢复BTree索引。
    • lock:表示当前获得kahadb读写权限的broker

4. JDBC消息存储

在这里插入图片描述

  • 其实就是将数据持久化到数据库中。

4.1 修改成JDBC消息存储

  • 首先导包,需要在lib文件夹中,加入mysql的java驱动文件,比如说mysql-connector-java-5.1.47.jar
  • 然后,修改配置文件,之前默认使用的是kahaDB,现在把它注释掉,然后修改成jdbc的。注意,千万别加createTableOnStartup="true"这个属性,不然跑的时候就会报错,很坑爹!!
    <persistenceAdapter>  
    	<jdbcPersistenceAdapter dataSource="#mysql-ds"/> 
    </persistenceAdapter>
    
  • 那个配置文件实际上就是Spring的配置文件,现在在里面选择使用JDBC的持久化方式,给了它一个数据库连接池的参数mysql-ds,因此我们还需要在后面将数据库连接池注入到IOC容器中。
    ...
    </broker>
    
    <bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://192.168.233.1/activemq?relaxAutoCommit=true"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="poolPreparedStatements" value="true"/>
    </bean>
    
    <import resource="jetty.xml"/>
    

    在这个文件里,建议将数据库声明在broker下面,import上面

  • 数据库新建一个库,叫做activemq,因为上面的连接已经确定了,登录activemq的数据库。
    create database activemq;
    
  • 重启服务器,如果没有意外的话,数据库上面会多出几个表
    在这里插入图片描述
    • activemq_msgs:用于存储所有持久化的消息(包括queue和topic)
      在这里插入图片描述
    • activemq_acks:用于存储订阅的主题的相关信息。也就是在topic持久化的时候,订阅者一开始在activemq注册确认的那些信息。在这里插入图片描述
    • activemq_lock:在集群的时候有用,用于记录哪个Broker是当前的Master Broker。
      在这里插入图片描述

4.2 测试

4.3 持久化的Queue消息

  • 只有activemq_msgs会发生改变,会将所有消息存储到该表中。
  • 当有消费者消费该消息之后,数据库的消息会直接删除。

4.4 持久化的Topic消息

  • 如果是第一次持久化订阅,则会首先在activemq_acks中保存订阅的相关信息
  • 之后,如果有该主题相关的消息,就会将消息持久化到activemq_msgs中。
  • 值得一提的是,消息会持久的存储在数据库中,即使有订阅者接受了,还是会存储,并不会删掉。
  • 持久化的topic大量数据后可能导致性能下降。

4.3 分析

  • 频繁地读写数据库,反而会拉低MQ服务器自身的性能。违背了MQ本来就是来异步、削峰、解耦的。
  • 而且有一些Queue消息是很快就可以被消费掉然后删除的,其实是没必要存储在数据库的。
  • 因此,就有一种新的策略出现。

5. JDBC Message Store with ActiveMQ Journal

  • 就像缓存和数据库之间的关系,通过缓存可以挡掉很大部分的数据库读写。
  • ActiveMQ也有策略可以挡掉大部分的数据库读写。那就是在读写数据库之前,加一层缓存文件ActiveMQ Journal。
  • 这是一个高速缓存写入技术,当生产者生产消息之后,先存储在journal文件中,如果在这段时间内有消费者消费了该消息,则将该消息从journal文件中删除。那些在journal文件存储较长时间的消息才会存储到数据库中。

5.1 配置

  • 又需要修改配置文件了。将上面设置的持久化方式注释掉,改成这样的。
    <persistenceFactory>
    	<journalPersistenceAdapterFactory 
    		journalLogFiles="5"
    		journalLogFileSize="32768"
    		useJournal="true"
    		useQuickJournal="true"
    		dataSource="#mysql-ds"
    		dataDirectory="${activemq.data}/a-j-data" /> 
    </persistenceFactory>
    
  • 修改完直接运行就好了。可以尝试测试,发消息之后,查看数据库一开始并没有消息,只有过了一会之后,才会有消息真正持久化到数据库中。

6. levelDB

官方文档

  • 这种文件系统是从ActiveMQ5.8之后引进的,它和KahaDB非常相似,也是基于文件的本地数据库存储形式,但是它提供比KahaDB更快的持久性。
  • 但它不使用自定义B-Tree实现来索引独写日志,而是使用基于LevelDB的索引
  • 但是,由于该技术的成熟度还不够,因此一般还是使用kahaDB

6.1 配置方式

<persistenceAdapter>
      <levelDB directory="activemq-data"/>
</persistenceAdapter>

7. 总结

  • 演变过程:从最初的AMQ Message Store方案到ActiveMQ V4版本退出的High Performance Journal(高性能事务支持)附件,并且同步推出了关于关系型数据库的存储方案。ActiveMQ5.3版本又推出了对KahaDB的支持(5.4版本后被作为默认的持久化方案),后来ActiveMQ 5.8版本开始支持LevelDB,到现在5.9提供了标准的Zookeeper+LevelDB集群化方案。
    在这里插入图片描述
  • 无论使用哪一种持久化方式,消息存储的逻辑都是一致的。
  • 下一章,将会详细描述通过LevelDB+Zookeeper实现Master-Slaver的数据备份方式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值