ActiveMQ 笔记(六)ActiveMQ的消息存储和持久化
个人博客网:https://wushaopei.github.io/ (你想要这里多有)
一、持久化机制
1、Activemq持久化
1.1 什么是持久化:
1.2 持久化的作用
详情——官网 : http://activemq.apache.org/persistence
1.3 ActiveMQ 支持的消息持久化机制:
- 为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一半都会采用持久化机制。
- ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式,消息的存储逻辑都是一致的。
- 就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等。再试图将消息发给接收者,成功则将消息从存储中删除,失败则继续尝试尝试发送。
- 消息中心启动以后,要先检查指定的存储位置是否有未成功发送的消息,如果有,则会先把存储位置中的消息发出去。
注意:一句话:ActiveMQ宕机了,消息不会丢失的机制。
二、持久化方式
1、Activemq的持久化方式有几种
1.1 AMQ Mesage Store(了解)
注意:基于文件的存储方式,是以前的默认消息存储,现在不用了
1.2 KahaDB消息存储(默认)
KahaDB 的属性配置 : http://activemq.apache.org/kahadb
说明:它使用一个事务日志和 索引文件来存储所有的地址
1.3 JDBC消息存储
1.4 LevelDB消息存储(了解)
它比KahaDB 更快的原因是她不使用BTree 索引,而是使用本身自带的 LeavelDB 索引
这种文件系统是从ActiveMQ5.8之后引进的,它和KahaDB非常相似,也是基于文件的本地数据库存储形式,但是它提供比KahaDB更快的持久性。
但它不使用自定义B-Tree实现来索引独写日志,而是使用基于LevelDB的索引
题外话:为什么LeavelDB 更快,并且5.8 以后就支持,为什么还是默认 KahaDB 引擎,因为 activemq 官网本身没有定论,LeavelDB 之后又出了可复制的LeavelDB 比LeavelDB 更性能更优越,但需要基于 Zookeeper 所以这些官方还没有定论,任就使用 KahaDB
默认配置如下:
1.5 JDBC Message Store with ActiveMQ Journal
2、JDBC存储消息(重点)
①修改配置文件,默认 kahaDB
修改之前:
修改之后:
②在activemq 的lib 目录下添加 jdbc 的jar 包 (connector.jar 我使用5.1.41 版本)
③ 修改配置文件 : activemq.xml 使其连接自己windows 上的数据库,并在本地创建名为activemq 的数据库
④ 让linux 上activemq 可以访问到 mysql ,之后产生消息。
ActiveMQ 启动后会自动在 mysql 的activemq 数据库下创建三张表:activemq_msgs 、activemq_acks、activemq_lock
点对点会在数据库的数据表 ACTIVEMQ_MSGS 中加入消息的数据,且在点对点时,消息被消费就会从数据库中删除
但是对于主题,订阅方式接受到的消息,会在 ACTIVEMQ_MSGS 存储消息,即使MQ 服务器下线,并在 ACTIVEMQ_ACKS 中存储消费者信息 。 并且存储以 activemq 为主,当activemq 中的消息被删除后,数据库中的也会自动被删除。
如果表没生成,可能需要自己创建
坑:
JDBC 改进: 加入高速缓存机制 Journal
高速缓存在 activemq.xml 中的配置:
⑤代码运行验证
一定要开启持久化 : messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
(1)队列Queue:
生产者:
运行结果:
在点对点类型中
- 当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中
- 当DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。
而且点对点类型中消息一旦被Consumer消费,就从数据中删除
消费前的消息,会被存放到数据库
上面的消息被消费后被MQ自动删除
(2)主题Topic
在点对点类型中
- 当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中
- 当DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。
而且点对点类型中消息一旦被Consumer消费,就从数据中删除
消费前的消息,会被存放到数据库
上面的消息被消费后被MQ自动删除
3、JDBC Message store with ActiveMQ Journal(重点)
3.1 定义:
3.2 说明
这种方式克服了JDBC Store的不足,JDBC每次消息过来,都需要去写库读库。
ActiveMQ Journal,使用高速缓存写入技术,大大提高了性能。
当消费者的速度能够及时跟上生产者消息的生产速度时,journal文件能够大大减少需要写入到DB中的消息。
举个例子:
生产者生产了1000条消息,这1000条消息会保存到journal文件,如果消费者的消费速度很快的情况下,在journal文件还没有同步到DB之前,消费者已经消费了90%的以上消息,那么这个时候只需要同步剩余的10%的消息到DB。如果消费者的速度很慢,这个时候journal文件可以使消息以批量方式写到DB。
3.3 配置方式:
原来的配置:
修改的结果:
以前是实时写入mysql,在使用了journal后,数据会被journal处理,如果在一定时间内journal处理(消费)完了,就不写入mysql,如果没消费完,就写入mysql,起到一个缓存的作用
小总结:
- 持久化消息是指:
- MQ 所在的服务器down 了消息也不会丢失
2.持久化机制演化过程:
- 从最初的AMQ Message Store 方案到 ActiveMQ V4版本推出的High performance journal (高性能事务)附件,并且同步推出了关系型数据库的存储方案, ActiveMQ 5.3 版本有推出了KahaDB 的支持,(也是5.4之后的默认持久化方案),后来ActiveMQ 从5.8开始支持LevelDB ,现在5.9 提供了 Zookeeper + LevelDB 的集群化方案。
3. ActiveMQ 消息持久化机制有:
AMQ | 基于日志文件 |
KahaDB | 基于日志文件,5.4 之后的默认持久化 |
JDBC | 基于第三方数据库 |
LevelDB | 基于文件的本地数据库存储,从5.8 之后推出了LevelDB 性能高于 KahaDB |
ReplicatedLevelDB Store |
从5.8之后提供了基于LevelDB 和Zookeeper 的数据复制方式,用于Master-slave方式的首数据复制选方案 但是无论使用哪种持久化方式,消息的存储逻辑都一样 |