ActiveMQ系列—ActiveMQ性能优化(下1)(消息存储方案 KahaDB)

来源:互联网 发布:上海铭创软件 编辑:程序博客网 时间:2024/05/16 05:37

序1:存储方案配置

在介绍ActiveMQ的存储方案之前,首先需要明确的是ActiveMQ中的几种“容量”描述:

ActiveMQ的内核是Java编写的,也就是说如果服务端没有Java运行环境ActiveMQ是无法运行的。ActiveMQ启动时,启动脚本使用wrapper包装器来启动JVM。JVM相关的配置信息在启动目录的“wrapper.conf”配置文件中。各位读者可以通过改变其中的配置项,设置JVM的初始内存大小和最大内存大小(当然还可以进行其他和JVM有关的设置,例如开启debug模式),如下:

[root@bogon linux-x86-64]# pwd/usr/local/src/apache-activemq-5.13.2/bin/linux-x86-64[root@bogon linux-x86-64]# lsactivemq  libwrapper.so  wrapper  wrapper.conf[root@bogon linux-x86-64]# vim wrapper.conf......# Initial Java Heap Size (in MB)#wrapper.java.initmemory=3# Maximum Java Heap Size (in MB)wrapper.java.maxmemory=1024......

以上配置项设置JVM的初始内存大小为100MB,设置JVM的最大内存大小为512MB。如果您在更改后使用console参数启动ActiveMQ,那么会看到当前ActiveMQ的JVM设置发生了变化:

这里写图片描述

明确了ActiveMQ的内存区域来源,才好理解后续的设置内容。ActiveMQ每一个服务节点都是一个独立的进程。在ActiveMQ主配置文件中,读者可以找到一个“systemUsage”标记,类似定义如下:

          <!--            The systemUsage controls the maximum amount of space the broker will            use before disabling caching and/or slowing down producers. For more information, see:            http://activemq.apache.org/producer-flow-control.html          -->          <systemUsage>            <systemUsage>                <memoryUsage>                    <memoryUsage percentOfJvmHeap="70" />                </memoryUsage>                <storeUsage>                    <storeUsage limit="100 gb"/>                </storeUsage>                <tempUsage>                    <tempUsage limit="50 gb"/>                </tempUsage>            </systemUsage>        </systemUsage>

systemUsage:该标记用于设置整个ActiveMQ节点在进程级别的各种“容量”的设置情况。其中可设置的属性包括:

  • sendFailIfNoSpaceAfterTimeout:当ActiveMQ收到一条消息时,如果ActiveMQ这时已经没有多余“容量”了,那么就会等待一段时间(这里设置的毫秒数),如果超过这个等待时间ActiveMQ仍然没有可用的容量,那么就拒绝接收这条消息并在消息的发送端抛出javax.jms.ResourceAllocationException异常;

  • sendFailIfNoSpace,当ActiveMQ收到一条消息时,如果ActiveMQ这时已经没有多余“容量”了,就直接拒绝这条消息(不用等待一段时间),并在消息的发送端抛出javax.jms.ResourceAllocationException异常。

memoryUsage:该子标记设置整个ActiveMQ节点的“可用内存限制”。这个值不能超过上文中您设置的JVM maxmemory的值。其中的percentOfJvmHeap属性表示使用“百分数值”进行设置,除了这个属性以外,您还可以使用limit属性进行固定容量授权,例如:limit=”1000 mb”。这些内存容量将供所有队列使用。

storeUsage:该标记设置整个ActiveMQ节点,用于存储“持久化消息”的“可用磁盘空间”。该子标记的limit属性必须要进行设置。在使用后续介绍的KahaDB方案或者LevelDB方案进行PERSISTENT Message持久化存储时,这个storeUsage属性都会起作用;但是如果使用数据库存储方案,这个属性就不会起作用了。

tempUsage:在ActiveMQ 5.X+ 版本中,一旦ActiveMQ服务节点存储的消息达到了memoryUsage的限制,NON_PERSISTENT Message就会被转储到 temp store区域。虽然我们说过NON_PERSISTENT Message不进行持久化存储,但是ActiveMQ为了防止“数据洪峰”出现时NON_PERSISTENT Message大量堆积致使内存耗尽的情况出现,还是会将NON_PERSISTENT Message写入到磁盘的临时区域——temp store。这个子标记就是为了设置这个temp store区域的“可用磁盘空间限制”。最后提醒各位读者storeUsage和tempUsage并不是“最大可用空间”,而是一个阀值。

序2:持久化存储方案的演化

说到ActiveMQ中持久化存储方案的演化问题,如果您仔细阅读ActiveMQ官方文档中关于持久化部分的描述,您就不难发现ActiveMQ的开发团队在针对持久化性能问题的优化上可谓与时俱进。这也符合一款健壮软件的生命周期特征:任何功能特性都在进行不断累计完善:

从最初的AMQ Message Store方案,到ActiveMQ V4版本中推出的High performance journal(高性能事务支持)附件 ,并且同步推出了关于关系型数据库的存储方案。ActiveMQ 5.3版本中又推出了对KahaDB的支持(V5.4版本后称为ActiveMQ默认的持久化方案),后来ActiveMQ V5.8版本开始支持LevelDB,到现在,V5.9+版本提供了标准的Zookeeper+LevelDB集群化方案。下面我们重点介绍一下ActiveMQ中KahaDB、LevelDB和关系型数据库这三种持久化存储方案。并且会和读者一起,使用Zookeeper搭建LevelDB集群存储方案。


9、KahaDB存储方案

9.1、KahaDB基本结构

KahaDB is a file based persistence database that is local to the message broker that is using it. It has been optimised for fast persistence and is the the default storage mechanism from ActiveMQ 5.4 onwards. KahaDB uses less file descriptors and provides faster recovery than its predecessor, the AMQ Message Store.

以上引用自Apache ActiveMQ 官方对KahaDB的定义。首先KahaDB基于文件系统,其次KahaDB支持事务。在ActiveMQ V5.4版本及后续版本KahaDB都是ActiveMQ的默认持久化存储方案。最后Apache ActiveMQ官方表示它用来替换之前的AMQ Message Store存储方案。

KahaDB主要元素包括:一个内存Metadata Cache用来在内存中检索消息的存储位置、若干用于记录消息内容的Data log文件、一个在磁盘上检索消息存储位置的Metadata Store、还有一个用于在系统异常关闭后恢复Btree结构的redo文件。如下图所示(官网引用):

这里写图片描述

以下是KahaDB在磁盘文件上的现实展示。注意,可能您查看自己测试实例中所运行的KahaDB,看到的效果和本文中给出的效果不完全一致。例如您的data log文件可能叫db-1.log,也有可能会多出一个db.free的文件,但是这些都不影响我们对文件结构的分析:

[root@bogon kahadb]# pwd/usr/local/src/apache-activemq-5.13.2/data/kahadb[root@bogon kahadb]# ll -h总用量 3.2M-rw-r--r-- 1 root root 32M 9月  21 08:13 db-1.log-rw-r--r-- 1 root root 32K 9月  21 08:13 db.data-rw-r--r-- 1 root root 33K 9月  21 08:13 db.redo-rw-r--r-- 1 root root   8 9月  21 08:10 lock
  • db-3.log:这个文件就是我们上文提到的Data log文件。一个KahaDB中,可能同时存在多个Data log文件,他们存储了每一条持久化消息的真正内容。这些Data log文件统一采用db-*.log的格式进行命名,并且每个Data log文件默认的大小都是32M(当然是可以进行设置的)。当一个Data log文件中的所有消息全部被成功消息后,这个Data log文件会在Metadata Cache中被标记为删除,并在下个checkpoint周期进行删除操作

  • 各位读者可能已经注意到一个现象:为什么db-3.log的默认占用大小就是32M,但是目录显示的“总用量”却只有29M呢?在这个文件夹中,除了db-3.log文件本身,加上其他几个文件所占用的大小,已经远远超过了32M!这是因为,为了加快写文件的性能,Data log文件采用顺序写的方式进行操作,为了保证文件使用的扇区在物理上是连续的,所以Data log文件需要预占这些扇区(这个和Hadoop中每一个block大小都是固定的原因相似)。虽然您看到Data log文件占用的32M的磁盘空间,但是这些磁盘空间并没有全部使用;

  • 为了更快的找到某个具体消息在Data log文件中的具体位置。消息的位置索引采用BTree的结构被存储在内存中,这个内存区域就是上文提到的Metadata Cache(大小也是可以设置的)。要知道Mysql的Innodb 存储引擎也是采用BTree结构构造索引结构(用了都说快哦~~)。所以一般情况下,只要某个队列有活动的消费者存在,消息的定位、读取操作是可以很快完成的;

  • 内存中没有被处理的消息索引会以一定的周期(或者一定的数量规模)为依据,同步(checkpoint)到Metadata Store中,这就是我们在上文中看到的“db.data”文件。当然db.redo文件也会被更新,以便在ActiveMQ服务节点在重启后对Metadata Cache进行恢复。最后,消息同步(checkpoint)依据,可以在ActiveMQ的主配置文件中进行设置。

9.2、在ActiveMQ中配置KahaDB

由于在ActiveMQ V5.4+的版本中,KahaDB是默认的持久化存储方案。所以即使您不配置任何的KahaDB参数信息,ActiveMQ也会启动KahaDB。这种情况下,KahaDB文件所在位置是您的ActiveMQ安装路径下的/data/broker.Name/KahaDB{broker.Name}代表这个ActiveMQ服务节点的名称。

正式的生产环境还是建议您在主配置文件中明确设置KahaDB的工作参数。如下所示:

......<broker xmlns="http://activemq.apache.org/schema/core"  brokerName="localhost" dataDirectory="${activemq.data}">    ......    <persistenceAdapter>        <kahaDB directory="${activemq.data}/kahadb"/>    </persistenceAdapter>    ......</broker>......

以上配置项设置使用kahaDB为持久化存储方法,并且设置kahaDB的工作目录为ActiveMQ安装路劲下/data/kahadb目录。如果您需要重新设置Data log文件默认的32M的大小,可以使用journalMaxFileLength属性进行设置,如下所示:

......<broker xmlns="http://activemq.apache.org/schema/core"  brokerName="localhost" dataDirectory="${activemq.data}">    ......    <persistenceAdapter>        <kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="64mb"/>    </persistenceAdapter>    ......</broker>......

您还可以设置为:当Metadata Cache中和Metadata Store中不同的索引条数达到500条时,就进行checkpoint同步。如下所示:

......<broker xmlns="http://activemq.apache.org/schema/core"  brokerName="localhost" dataDirectory="${activemq.data}">    ......    <persistenceAdapter>        <kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="64mb" indexWriteBatchSize="500"/>    </persistenceAdapter>    ......</broker>......

以下表格为读者示例了KahaDB中所有的配置选项和其含义(引用自网络,加“*”部分是笔者认为重要的配置选项):

property name default value Comments *directory activemq-data 消息文件和日志的存储目录 *indexWriteBatchSize 1000 当Metadata cache区域和Metadata store区域不同的索引数量达到这个值后,Metadata cache将会发起checkpoint同步 *indexCacheSize 10000 内存中,索引的页大小。超过这个大小Metadata cache将会发起checkpoint同步 *enableIndexWriteAsync false 索引是否异步写到消息文件中,将以不要设置为true *journalMaxFileLength 32mb 一个消息文件的大小 *enableJournalDiskSyncs true 如果为true,保证使用同步写入的方式持久化消息到journal文件中 *cleanupInterval 30000 清除(清除或归档)不再使用的db-*.log文件的时间周期(毫秒)。 *checkpointInterval 5000 写入索引信息到metadata store中的时间周期(毫秒) ignoreMissingJournalfiles false 是否忽略丢失的journal文件。如果为false,当丢失了journal文件时,broker启动时会抛异常并关闭 checkForCorruptJournalFiles false 检查消息文件是否损坏,true,检查发现损坏会尝试修复 checksumJournalFiles false 产生一个checksum,以便能够检测journal文件是否损坏。



5.4版本之后有效的属性:

property name default value Comments *archiveDataLogs false 当为true时,归档的消息文件被移到directoryArchive,而不是直接删除 *directoryArchive null 存储被归档的消息文件目录 databaseLockedWaitDelay 10000 在使用负载时,等待获得文件锁的延迟时间,单位ms maxAsyncJobs 10000 等待写入journal文件的任务队列的最大数量。应该大于或等于最大并发producer的数量。配合并行存储转发属性使用。 concurrentStoreAndDispatchTopics false 如果为true,转发消息的时候同时提交事务 concurrentStoreAndDispatchQueues true 如果为true,转发Topic消息的时候同时存储消息的message store中



5.6版本之后有效的属性:

property name default value Comments archiveCorruptedIndex false 是否归档错误的索引到Archive文件夹下



5.10版本之后有效的属性:

property name default value Comments IndexDirectory 单独设置KahaDB中,db.data文件的存储位置。如果不进行设置,db.data文件的存储位置还是将以directory属性设置的值为准
阅读全文
0 0