ActiveMQ的持久化机制

为什么要进行持久化?

为了避免MQ服务器意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制。

ActiveMQ持久化的方式哪几种?

ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB, 无论使用哪种持久化方式,消息的存储逻辑都是一致的。

就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等再试图将消息发送给接收者,成功则将消息从存储中删除,失败则继续尝试发送。

消息中心启动以后首先要检查指定的存储位置,如果有未发送成功的消息,则需要把消息发送出去。

1.AMQ Message Store(已经被淘汰)

AMQ Message Store是ActiveMQ5. 0缺省的持久化存储,它是一个基于文件、事务存储设计为快速消息存储的一一个结构,该结构是以流的形式来进行消息交互的。这种方式中,Messages被 保存到data logs中,同时被reference st ore进行索引以提高存取速度。Date logs由一些单独的data 1og文件组成,缺省的文件大小是32M,如果某个消息的大小超过了data log文件的大小,那么可以修改配置以增加data log文件的大小。如果某个data log文件中所有的消息都被成功消费了,那么这

个datalog文件将会被标记,以便在下一轮的清理中被删除或者归档。

2.kahadb(ActiveMQ 5.3以后默认使用)

我们是怎么知道他是当前官方默认推荐的方式呢?

在ActiveMQ的安装目录,conf/activemq.xml中可以看到下面这样一个节点

 其中的${activemq.data}代表的是安装目录下的data目录,保存的数据都在这里边

KahaDB是目前默认的存储方式,可用于任何场景提高了性能和恢复能力。
消息存储使用一个事务日志和仅仅用一个索引文件来存储它所有的地址。

KahaDB是一个专门针对消息持久化的解决方案,它对典型的消息使用模式进行了优化。数据被追加到data logs中。当不再需要log文件中的数据的时候,log文件会被丢弃。

kahadb在消息保存目录中只有4类文件和一个lock,跟ActiveMQ的其他几种文件存储引擎相比这就非常简洁了。

 那我们就分别来说说这些4类文件都是什么作用

1.db-(Number).log  KahaDB将消息存储到预定定义大小的数据记录文件之中,当数据文件已满时,就会紧接着创建一个新的文件,number的数值也会随之递增,。当不在有引用到数据文件中的任何消息时,文件会被删除或归档。

2.db.data 此文件包含了持久化的BTree索引,索引了消息数据记录中的消息,它就是消息的索引文件,本质是B-Tree(B树),使用B-tree作为索引指向db-(Number).log里面存储的消息。

3.db.free 当前db.data文件里那些页面是空闲的,文件具体内容是所有空闲页的ID

4.db.redo  用来进行消息恢复,当KahaDB消息存储在强制退出后启动,用于恢复BTree索引

5.lock 文件锁,表示当前获得kahadb读写权限的broker

3.LevelDB(暂不推荐使用)

这种文件系统是从ActiveMQ5.8之后引进的,它和KahaDB非常相似,也是基于文件的本地数据库储存形式,但是它提供比KahaDB更快的持久性。但它不使用自定义B-Tree实现来索引预写日志,而是使用基于LevelDB的索引,需要和Zookeeper一起使用

配置如下:

< persistenceAdapter >
< levelDBdirectory = "activemq-data" />
</persistenceAdapter >

4.JDBC消息存储

第一步:将mysql的jar文件mysql-connector-java-5.1.38.jar放置到ActiveMQ安装目录的lib目录

先看一下安装目录

第二步:修改ActiveMQ的安装目录,conf/activemq.xml文件中的<persistenceAdapter>节点,也就是默认的 持久化方式

将上图中的节点进行注释,添加新的节点

 <persistenceAdapter>
  <!-- 持久化远程数据库 -->
     <jdbcPersistenceAdapter dataSource="#mysql-ds"  createTablesOnStartup="true"/> 
</persistenceAdapter>

createTables0nStartup星否在启动的时候创建数据表,默认值是true,这样每次启动都会去创建数据表了,一般是第一次启动的时候设置为true之后改成false

第三步:配置数据源

在</broker>标签之后,<import>标签之前添加数据源的配置,数据源的类型使用默认的dbcp2,如要更改需要引入相对应的Jar文件

<!-- 数据源 -->
 <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.118.1:3306/activemq?relaxAutoCommit=true"/>
    <property name="username" value="root"/>
     <property name="password" value="123"/>
     <property name="poolPreparedStatements" value="true"/>
  </bean>

为保证能够连接到MySQL服务器成功,你的mysql必须可以从远程登陆

这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"localhost"改称"%",然后重启MYSQL服务

之上的步骤操作无误的话,重新启动ActiveMQ的服务,就会在你的数据库下生成了三张表

activemq_msgs

activemq_acks

 activemq_lock

JDBC message store with activemq journal(基于JDBC调优)

这种方式克服了JDBC Store的不足,JDBC每次消息过来,都需要去写库和读库。ActiveMQ Journal,使用高速缓存写入技术,大大提高了性能。当消费者的消费速度能够及时跟上生产者消息的生产速度时,journal文件能够大大减少需要写入到DB中的消息。举个例子,生产者生产了1000条消息,这1000条消息会保存到journal文件,如果消费者的消费速度很快的情况下,在journal文件还没有同步到DB之前,消费者已经消费了90%的以上的消息,那么这个时候只需要同步剩余的10%的消息到DB。如果消费者的消费速度很慢,这个时候journal文件可以使消息以批量方式写到DB。

使用快速的缓存写入技术,大大提高了性能。配置实例如下:将之前配置的

 <persistenceAdapter>
  <!-- 持久化远程数据库 -->
     <jdbcPersistenceAdapter dataSource="#mysql-ds"  createTablesOnStartup="true"/> 
</persistenceAdapter>

注释掉,替换为如下配置

<persistenceFactory>
    <journalPersistenceAdapterFactory 
        journalLogFiles="4" 
        journalLogFileSize="32768" 
        useJournal="true" 
        useQuickJournal="true"
        dataSource="#mysql-ds"
        dataDirectory="activemq-data"/>
</persistenceFactory>

猜你喜欢

转载自www.cnblogs.com/yjc1605961523/p/11995908.html
今日推荐