KahaDB
KahaDB 是一个基于文件的持久化数据库,它位于使用它的消息代理的本地。它针对快速持久化进行了优化。它是自 **ActiveMQ Classic 5.4** 以来默认的存储机制。KahaDB 使用更少的 文件描述符,并且与它的前身 AMQ 消息存储 相比,提供了更快的恢复速度。
配置
要使用 KahaDB 作为代理的持久化适配器,请按如下方式配置 ActiveMQ Classic(示例)
<broker brokerName="broker">
<persistenceAdapter>
<kahaDB directory="activemq-data" journalMaxFileLength="32mb"/>
</persistenceAdapter>
</broker>
KahaDB 属性
属性 | 默认值 | 注释 |
---|---|---|
archiveCorruptedIndex |
false |
如果 true ,则在启动时发现的损坏索引将被存档(不会被删除)。 |
archiveDataLogs |
false |
如果 true ,将把消息数据日志移动到存档目录,而不是删除它。 |
checkForCorruptJournalFiles |
false |
如果 true ,将在启动时检查是否存在损坏的日志文件,并尝试恢复它们。 |
checkpointInterval |
5000 |
在对日志进行检查点之前的时间(毫秒)。 |
checksumJournalFiles |
true |
为日志文件创建校验和。持久化适配器需要校验和才能检测到损坏的日志文件。在 **ActiveMQ Classic 5.9.0** 之前:默认值为 false 。 |
cleanupInterval |
30000 |
连续检查之间的间隔(以毫秒计),这些检查确定哪些日志文件(如果有)有资格从消息存储中删除。符合条件的日志文件是没有未完成引用的日志文件。 |
compactAcksAfterNoGC |
10 |
从 **ActiveMQ Classic 5.14.0** 开始:当启用确认压缩功能时,此值控制在没有其他文件被清理的情况下,必须完成多少个存储 GC 周期才能触发压缩逻辑,以将可能跨日志文件分布的旧确认压缩到一个新的日志文件中。设置的值越低,压缩可能发生的越快,如果它运行的太频繁,可能会影响性能。 |
compactAcksIgnoresStoreGrowth |
false |
从 **ActiveMQ Classic 5.14.0** 开始:当启用确认压缩功能时,此值控制在存储仍在增长时是否运行压缩,或者它是否应该只在存储停止增长时运行(由于空闲或存储限制已达到)。如果启用,则压缩将不顾存储还有空间或是否处于活动状态而运行,这可以减少总体性能,但可以更快地回收空间。 |
concurrentStoreAndDispatchQueues |
true |
启用将队列消息分派给感兴趣的客户端与消息存储同时发生。 |
concurrentStoreAndDispatchTopics |
false |
启用将主题消息分派给感兴趣的客户端与消息存储同时发生。**不建议启用此属性。** |
directory |
activemq-data |
用于存储消息存储数据和日志文件的目录的路径。 |
directoryArchive |
null |
定义要将数据日志移动到的目录,当它们包含的所有消息都被使用时。 |
enableAckCompaction |
true |
从 **ActiveMQ Classic 5.14.0** 开始:此设置控制存储是否将定期压缩仅包含消息确认的旧日志文件。通过将这些旧确认压缩到新的日志文件中,可以删除旧文件,释放空间并允许消息存储继续运行而不会遇到存储大小限制。 |
enableIndexWriteAsync |
false |
如果 true ,则异步更新索引。 |
enableJournalDiskSyncs |
true |
确保每次日志写入后都进行磁盘同步(JMS 持久性要求)。从 **ActiveMQ Classic** **5.14.0** 开始,此属性已弃用。从 **ActiveMQ Classic** **5.14.0** 开始:参见 journalDiskSyncStrategy 。 |
ignoreMissingJournalfiles |
false |
如果 true ,则忽略有关丢失日志文件的报告。 |
indexCacheSize |
10000 |
内存中缓存的索引页数。 |
indexDirectory |
从 **ActiveMQ Classic 5.10.0** 开始:如果设置,则配置 KahaDB 索引文件 (db.data 和 db.redo ) 将存储在何处。如果未设置,则索引文件将存储在由 directory 属性指定的目录中。 |
|
indexWriteBatchSize |
1000 |
批量写入的索引数量。 |
journalDiskSyncInterval |
1000 |
当 journalDiskSyncStrategy=periodic 时,执行磁盘同步的间隔(毫秒)。只有在自上次磁盘同步以来或在日志翻转到新的日志文件时发生了写入操作,才会执行同步。 |
journalDiskSyncStrategy |
always |
从 **ActiveMQ Classic 5.14.0** 开始:此设置配置磁盘同步策略。可用的同步策略列表(按安全性降低、性能提高的顺序):always 确保每次日志写入后都进行磁盘同步(JMS 持久性要求)。这是最安全的选项,但也是最慢的,因为它需要在每次消息写入后进行同步。这等同于设置已弃用的属性 enableJournalDiskSyncs=true 。periodic 磁盘将在设定的间隔(如果发生了写入操作)进行同步,而不是在每次日志写入后进行同步,这将减少磁盘负载并应该提高吞吐量。在翻转到新的日志文件时,磁盘也将进行同步。默认间隔为 1 秒。默认间隔提供非常好的性能,同时比 never 磁盘同步更安全,因为数据丢失仅限于最多 1 秒的 worth。参见 journalDiskSyncInterval 来更改磁盘同步的频率。never 不会显式调用同步,并将由操作系统负责刷新到磁盘。这等同于设置已弃用的属性 enableJournalDiskSyncs=false 。这是最快的选项,但最不安全,因为无法保证何时将数据刷新到磁盘。因此,在代理发生故障时,可能会发生消息丢失。 |
journalMaxFileLength |
32mb |
设置消息数据日志最大大小的提示。 |
maxAsyncJobs |
10000 |
等待存储的异步消息的最大数量(应与并发 MessageProducers 的数量相同)。 |
preallocationScope |
entire_journal |
从 **ActiveMQ Classic 5.14.0** 开始:此设置配置如何预分配日志数据文件。默认策略在第一次使用时使用附加线程预分配日志文件。 entire_journal_async 将提前在单独的线程中预分配。 none 禁用预分配。在 SSD 上,使用 entire_journal_async 可以避免在第一次使用时延迟写入,直到预分配完成。**注意**:在 HDD 上,磁盘的额外线程竞争会产生负面影响。因此,请使用默认值。 |
preallocationStrategy |
sparse_file |
从 **ActiveMQ Classic 5.12.0** 开始:此设置配置代理在需要新的日志文件时如何尝试预分配日志文件。 sparse_file - 设置文件长度,但不填充任何数据。 os_kernel_copy - 将预分配委托给操作系统。 zeros - 每个预分配的日志文件只包含 0x00 。 |
storeOpenWireVersion |
11 |
确定被封送到 KahaDB 日志的 OpenWire 命令的版本。在 **ActiveMQ Classic 5.12.0** 之前:默认值为 6 。代理的一些功能依赖于存储在来自较新协议修订版 的 OpenWire 命令中的信息,如果存储版本设置为较低的值,这些功能可能无法正常工作。KahaDB 存储来自大于 5.9.0 的代理版本在很多情况下仍然可以被代理读取,但会导致代理继续使用较旧的存储版本,这意味着较新的功能可能无法按预期工作。对于在 **ActiveMQ Classic 5.9.0** 之前创建的 KahaDB 存储,需要手动设置 storeOpenWireVersion="6" ,才能启动代理,否则会报错。 |
有关调整锁定属性,请参见 可插拔存储锁 中列出的选项。
慢速文件系统访问诊断日志记录
您可以为数据库更新配置一个非零阈值(以毫秒计)。如果数据库操作比该阈值慢(例如,如果您将其设置为 500
),您可能会看到以下消息:
Slow KahaDB access: cleanup took 1277 | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Classic Journal Checkpoint Worker
您可以使用系统属性配置一个用于记录这些消息的阈值,并根据磁盘速度进行调整,以便您可以轻松地发现运行时异常。
-Dorg.apache.activemq.store.kahadb.LOG_SLOW_ACCESS_TIME=1500
Multi(m) kahaDB 持久化适配器
从 **ActiveMQ Classic 5.6** 开始:可以将目标存储分布在多个 kahdb 持久化适配器中。您什么时候会这样做?如果您有一个快速生产者/消费者目标,另一个具有不规则批量消费的定期生产者目标,那么由于未消费的消息分布在多个日志文件中,磁盘使用量可能会失控。为每个目标使用单独的日志可以确保最少的日志使用量。此外,某些目标可能是关键的,需要磁盘同步,而其他目标则可能不需要。在这种情况下,您可以使用 mKahaDB
持久化适配器,并使用通配符过滤目标,就像使用目标策略条目一样。
事务
如果目标是分布式的,则事务可以跨多个日志进行。这意味着需要进行两阶段提交,这确实会对记录提交结果造成性能(额外的磁盘同步)损失。只有当多个日志参与事务时,才会造成这种损失。
配置
每个 kahaDB
实例都可以独立配置。如果不对 filteredKahaDB
提供任何目标,则隐式默认值将匹配任何目标、队列或主题。这是一种方便的通用方式。如果找不到匹配的持久化适配器,则创建目标将失败并出现异常。 filteredKahaDB
与 每个目标策略 共享其通配符匹配规则。
从 ActiveMQ Classic 5.15 开始, filteredKahaDB
支持一个名为 usage
的 StoreUsage 属性。这允许对匹配的队列施加单独的磁盘限制。
<broker brokerName="broker">
<persistenceAdapter>
<mKahaDB directory="${activemq.base}/data/kahadb">
<filteredPersistenceAdapters>
<!-- match all queues -->
<filteredKahaDB queue=">">
<usage>
<storeUsage limit="1g" />
</usage>
<persistenceAdapter>
<kahaDB journalMaxFileLength="32mb"/>
</persistenceAdapter>
</filteredKahaDB>
<!-- match all destinations -->
<filteredKahaDB>
<persistenceAdapter>
<kahaDB enableJournalDiskSyncs="false"/>
</persistenceAdapter>
</filteredKahaDB>
</filteredPersistenceAdapters>
</mKahaDB>
</persistenceAdapter>
</broker>
自动每个目标持久化适配器
在通用情况下(即未设置显式目标时)将 perDestination="true"
设置为 filteredKahaDB
条目。每个匹配的目标将被分配自己的 kahaDB
实例。
<broker brokerName="broker">
<persistenceAdapter>
<mKahaDB directory="${activemq.base}/data/kahadb">
<filteredPersistenceAdapters>
<!-- kahaDB per destinations -->
<filteredKahaDB perDestination="true">
<persistenceAdapter>
<kahaDB journalMaxFileLength="32mb"/>
</persistenceAdapter>
</filteredKahaDB>
</filteredPersistenceAdapters>
</mKahaDB>
</persistenceAdapter>
</broker>
在同一个
filteredKahaDB
条目中同时指定perDestination="true"
和queue=">"
尚未经过测试。它 *可能* 会导致以下异常被抛出。Reason: java.io.IOException: File '/opt/java/apache-activemq-5.9.0/data/mKahaDB/lock' could not be locked as lock is already held for this jvm`