ActiveMQ消息持久化

本文详细介绍了ActiveMQ的消息存储方式,包括Queue和Topic消息模型,以及KahaDB、AMQ存储、JDBC存储和内存存储的特性、配置和工作原理。重点讨论了KahaDB作为默认持久化方式的存储结构和恢复机制。
消息的存储方式
Queue消息模型

​ 采用存储采用先进先出(FIFO),一个消息只能被一个消费者消费,当消息被确认消费之后才会被删除。

Topic消息模型

​ 每个订阅者获取的消息实际是消息的一个副本,只有一个消息副本会被存储,MQ 提供了一个指针来指向消息存储并且分发消息副本到订阅者,消息直到所有的持久化订阅者都被接收才能被删除。

持久化存储
  • KahaDB消息存储
  • AMQ消息存储
  • JDBC消息存储
  • 内存消息存储
KahaDB

​ 默认的持久化方式,KahaDB存储是一个基于文件的快速存储消息,所有的消息顺序的添加到一个日志文件中,同时有另一个索引文件记录执行这些日志到存储地址,还有一个事务日志用于消息的恢复操作。

特性
  • 日志形式存储消息;
  • 消息索引以B-Tree结果存储,可以快速更新;
  • 完全支持JMS事务;
  • 支持多种恢复机制,kahadb可以限制每个数据文件的大小。
配置

​ 在activemq.xml中配置如下:

<broker brokerName="broker" persistent="true" useShutdownHook="false">
  <persistenceAdapter>
    <!--directory:保存数据的目录;journalMaxFileLength:保存消息的文件大小 -->
    <kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="16mb"/>
  </persistenceAdapter>
</broker>
目录结构

在这里插入图片描述

​ 当有消费者时,缓存用于临时存储,消息会被发送给消费者,同时将安排存储。如果消息被很快确认,就不需要写入磁盘。如果消息已经写入磁盘,后续有消费者成功消费了此消息,将其标记为可删除,系统会周期性的清除或者归档日志文件。

  • db.data:存放B-Tree indexs;
  • db.redo:存放redo file,用于恢复B-Tree indexs;
  • db log files:用于存储消息,当log日志到了指定的大小,会创建一个新的,当log日志中的消息都被删除,改日志文件将会删除;
存储原理

在这里插入图片描述

  • Cache:用于临时存储,消息会被发送给消费者,同时将安排存储。如果消息被很快确认,就不需要写入磁盘。
  • BTree Indexes:保存在磁盘上,称为Metadata Store,对应的是db.data文件。它是对Data Logs以B树的形式索引。消息服务器可以通过此文件快速的重启恢复,因为它是消息的索引,可以恢复出每条消息的location。
  • Data Logs:对应文件db-XX.log,以日志的形象存储生产者生产的消息。
  • Redo log:对应db.redo,用于在非正常关机情况下维护索引完整性。

Metadata Store和Metadata Cache需要保证同步,同步的过程叫做check point

AMQ存储

​ 和KahaDB一样,AMQ 也是一个文件型数据库,消息信息最终是存储在文件中。内存中也会有缓存数据。

​ 为了提升性能,创建消息的主键索引,进一步提升性能。同时由于AMQ回味每一个Destination创建一个索引,如果使用大量的Queue,索引文件将占用很多磁盘空间,同时Broker奔溃,索引重建的过程非常慢。所以,Destination的数量较少,消息吞吐量是应用程序的主要需求时可以选用此方式存储。

配置

​ 配置方式 conf/activemq.xml:

<persistenceAdapter>
  <!--AMQ directory:数据存储路径 syncOnWrite:是否同步写入  maxFileLength:日志文件大小 -->
  <amqPersistenceAdapter
                         directory="${activemq.data}/kahadb"
                         syncOnWrite="true"
                         maxFileLength="10mb" />
</persistenceAdapter>

​ 虽然 AMQ 性能略高于 Kaha DB 方式,但是由于其重建索引时间过长,而且索引文件 占用磁盘空间过大,所以已经不推荐使用。

JDBC存储

​ 支持通过 JDBC 将消息存储到关系数据库,性能上不如文件存储,能通过关系型数据库查询到消息的信息。

​ 数据库默认会创建3个表,每个表的作用:

  • activemq_msgs:queue和topic的消息都存在这个表中
  • activemq_acks:用于存储订阅关系。如果是持久化Topic,订阅者和服务器的订阅关系在这个表保存
  • activemq_lock:跟kahadb的lock文件类似,确保数据库在某一时刻只有一个broker在访问(集群环境中才有用)
配置方式

​ 配置文件的Beans标签中添加:

<!--配置数据源-->
<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://localhost/activemq?relaxAutoCommit=true"/> 
  <property name="username" value="username"/>
  <property name="password" value="password"/>
  <property name="maxActive" value="200"/>
  <property name="poolPreparedStatements" value="true"/> 
</bean>
<!--dataSource 指定持久化数据库的 bean,createTablesOnStartup 是否在启动的时候创建数据表,默认值是 true,这样每次启动都会去创建数据表了,一般是第一次启动的时候设置为 true,之后改成 false。-->
<persistenceAdapter>
    <jdbcPersistenceAdapter dataSource="#mysql-ds"  createTablesOnStartup="false"/>
</persistenceAdapter> 
内存存储

​ 基于内存的消息存储,就是消息存储在内存中。必须注意JVM使用情况以及内存限制,适用于一些能快速消费的数据量不大的小消息,当MQ关闭或者宕机,未被消费的内存消息会被清空。

​ 配置方式 设置 broker属性值 persistent=“false”:表示不设置持久化存储,直接存储到内存中在broker标签处设置.

<broker brokerName="test-broker" persistent="false" xmlns="http://activemq.apache.org/schema/core">
  <transportConnectors>
    <transportConnector uri="tcp://localhost:61635"/>
  </transportConnectors>
</broker>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值