ActiveMQ in Action-5.3 The AMQ message store- 高飞网

5.3 The AMQ message store

2016-05-24 06:51:43.0

5.3 AMQ消息存储

    AMQ消息存储,就像KahaDB,综合了可靠的持久化(系统崩溃时仍可存活)业务日志和高性能索引的特性,对那些以消息产能为主要需求的应用来说,该存储成为的最好选择!但由于它为每个索引使用两个独立的文件,每种目标(destination)使用一个索引,因此,若你打算在每个服务端使用数以千计的队列时,就不要使用AMQ消息存储了。如果服务端未正常关闭,再次启动时恢复将非常缓慢。这是因为所有的索引都需要重建,这需要服务端再次将所有的数据日志重新建立索引。下面,将解释AMQ存储的内部实现,与KahaDB组件类似。


5.3.1 AMQ存储的内部实现

    AMQ存储的内部组件与KahaDB存储类似,包括缓存,消息数据记录,为顺序访问数据记录的引用库。图5.5演示了一个AMQ消息存储的高级预览,该图提供了AMQ的三个独立部分的视图:


 数据记录:作为消息日志
         缓存:在数据写入数据记录以后,为快速从内存中查询而保留消息。
         引用库:保持了由消息ID索引的日志中的消息的引用

理解ActiveMQ的AMQ消息存储使用的基于文件的目录结构是重要的。这将有助于配置和使用过程中的问题定位。


5.3.2 AMQ消息存储的目录结构

    当启动配置了AMQ消息存储的ActiveMQ时,一个目录会被自动创建,其中保存了持久化的消息。AMQ消息存储目录包含了为运行在机器上的所有服务端的子目录。因为这个,强烈建议每个服务端使用唯一的名字。在ActiveMQ默认的配置中,broker name是localhost,需要修改为一个唯一的名称。在图5.6中展示了AMQ消息存储的目录结构。


    在ActiveMQ服务端的data目录中可以看到下面的目录和文件:

    lock文件:确保在任一时刻,只有一个服务端可以访问这个数据。在同一个系统中多个名称相同的服务端,通常出于热备目的而使用这个lock文件。

    临时存储目录:用于存储非持久化消息,这些消息可能不再存储在服务端内存中。这些消息通常是正等待发送到一些运行缓慢的消费者的客户端上。

    kr库:部分AMQ消息存储,引用(索引)的目录结构。默认情况下使用Kaha引用库(Kaha是ActiveMQ核心库的一部分)去索引和存储数据日志中消息的引用。kr库中有两个独立的部分:

        * 数据目录:包含了索引和指向数据记录中保存的信息引用的集合。如果服务端没有完全关闭时,这个数据目录是恢复时删除并重建的一部分。你可以在启动服务端之前通过手工删除这个目录强制恢复。

        * 状态目录:保存了持久topic消费者的信息。日志本身不包含消费者信息,所以当它需要恢复时,它首先要查询持久订阅者的信息才能准确地重建它的数据库。

    日志目录:包含了数据记录的数据文件,数据控制文件包含了一些元数据。数据文件有引用计数,所以当所有的消息都已传递完成时,该数据文件可能被删除或归档

    归档目录:只有当归档开关启用时才存在.它的默认位置可以在下一个日志中看到。使用一个独立的分区或磁盘是有道理的。归档用于存储来自于日志目录中数据,这些数据移动到这里而不再是被直接删除掉。使日后从归档中重提取消息成为可能。重提取消息时,会移动归档数据记录(或一个子集)到一个新的日志目录当中,然后启动一个新的服务端指向这个新目录。它会自动地从这个日志目录中读取消息。

    到现在为止,AMQ消息存储已经全讲到了,下一步看一下它的配置方法。

5.3.3 配置AMQ消息存储

    AMQ消息存储的配置,运行用户修改索引的基本行为,检查站时间间隔,和日志数据文件的大小。这些选项和其他的项都可以通过使用属性文件自定义。AMQ的关键属性查看5.2表

表 5.2 AMQ的配置属性 16

属性名
默认值
描述
directory
activemq-data
AMQ消除存储使用的目录路径
useNIO
true
NIO提供对磁盘的更快的直接写入
syncOnWrite
false
每次写入磁盘都同步
syncOnTransaction
true
每次事务都同步
maxFileLength
32mb
新文件使用前消息日志数据文件的最大大小
persistentIndex
true
使用持久化索引。如果设置为false, 会使用内存中的HashMap
maxCheckpointMessageAddSize
4kb
写入磁盘前事务使用的最大内存
cleanupInterval
3000(ms)
检测那个日志数据文件仍旧需要前的时间
checkpointInterval
20000(ms)
移动缓存消息ID到引用库索引前的时间
indexBinSize
1024
索引使用的哈希表初始化桶数量
indexMaxBinSize
16384
使用的哈希表桶的最大值
directoryArchive
archive
AMQ消息存储放置归档日志文件的目录路径
archiveDataLogs
false
如果为true,日志文件会被归档而不会被删除
recoverReferenceStore
true
如果服务端没有完全关闭完成,恢复引用库,另外这种错误要格外消息
forceRecoverReferenceStore
false
强制引用库的恢复

    下面是在ActiveMQ配置文件中使用了表5.2的示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<broker xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter>
<amqPersistenceAdapter
directory="target/Broker2-data/activemq-data"
syncOnWrite="true"
indexPageSize="16kb"
indexMaxBinSize="100"
maxFileLength="10mb" />
</persistenceAdapter>
</broker>
</beans>

    这个是个AMQ存储的使用可用属性自定义配置的小例子。

    AMQ存储,就像KahaDB存储一样,使用户可以快速的使用并运行起来,因为它也没有依赖其他的数据库。但当你想使用关系型数据库运行ActiveMQ时,你应使用JDBC消息存储。


实验:

译者按照书中的描述配置了amq数据存储,但没有成功。具体如下:

a)复制一个配置文件,命名为:activemq_amq.xml,关键处配置如下:

<persistenceAdapter>
	<amqPersistenceAdapter directory="${activemq.base}/activemq-data" maxFileLength="32mb"/>
</persistenceAdapter>

b)启动服务:

bin\activemq.bat start xbean:d:/software/apache-activemq-5.13.2/conf/activemq_amq.xml

c)然后报错:

ERROR: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 83 in XML document from file [d:\software\apache-activemq-5.13.2\conf\activemq_amq.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 83; columnNumber: 96; cvc-complex-type.2.4.a: 发现了以元素 'amqPersistenceAdapter' 开头的无效内容。应以 '{"http://activem
q.apache.org/schema/core":jdbcPersistenceAdapter, "http://activemq.apache.org/schema/core":journalPersistenceAdapter, "http://activemq.apache.org/schema/core":kahaDB, "http://activemq.apache.org/schema/core":levelDB, "http://activemq.apache.org/schema/core":mKahaDB, "http://activemq.apache.org/schema/core":memoryPersistenceAdapter, "http://activemq.apache.org/schema/core":replicatedLevelDB, WC[##other:"http://activemq.apache.org/schema/core"]}' 之一开头。

参考:AMQ Message Store