复制 LevelDB 存储
警告
LevelDB 存储已弃用,不再支持或推荐使用。推荐的存储是 KahaDB
概要
复制 LevelDB 存储使用 Apache ZooKeeper 从一组配置为复制 LevelDB 存储的代理节点中选出一个主节点。然后将所有从属 LevelDB 存储与主节点同步,并通过复制主节点的所有更新来保持它们最新。
复制 LevelDB 存储使用与 LevelDB 存储相同的数据文件,因此您可以随时在复制和非复制之间切换代理配置。
版本兼容性
从 ActiveMQ Classic 5.9.0 开始可用。
工作原理。
它使用 Apache ZooKeeper 来协调集群中哪个节点成为主节点。选定的主代理节点启动并接受客户端连接。其他节点进入从属模式并连接到主节点,并将它们的持久状态与其同步。从属节点不接受客户端连接。所有持久操作都将复制到连接的从属节点。如果主节点死亡,拥有最新更新的从属节点将被提升为主节点。失败的节点随后可以重新联机,并且它将进入从属模式。
所有需要同步到磁盘的消息操作将在更新复制到节点的仲裁数之前完成。因此,如果您将存储配置为 replicas="3"
,那么仲裁大小为 (3/2+1)=2
。主节点将在本地存储更新,并等待另一个从属节点存储更新,然后报告成功。另一种思考方式是,存储将对复制节点的仲裁数执行同步复制,并对任何其他节点执行异步复制。
当选出新的主节点时,您还需要至少有仲裁数的节点联机才能找到具有最新更新的节点。拥有最新更新的节点将成为新的主节点。因此,建议您运行至少 3 个副本节点,以便您可以在不影响服务中断的情况下将其中的一个关闭。
部署技巧
客户端应使用 故障转移传输 连接到复制集群中的代理节点。例如,使用类似以下的 URL
failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
您应该运行至少 3 个 ZooKeeper 服务器节点,以确保 ZooKeeper 服务具有高可用性。不要过度使用您的 ZooKeeper 服务器。过度工作的 ZooKeeper 可能会开始认为实时复制节点由于处理它们的“保持活动”消息的延迟而脱机了。
为了获得最佳效果,请确保您显式地使用主机名或 IP 地址为其他集群成员访问该机器的节点配置 hostname 属性。自动确定的主机名并不总是可以被其他集群成员访问,这会导致从属节点无法与主节点建立复制会话。
配置
您可以配置 ActiveMQ Classic 使用 LevelDB 作为其持久性适配器,如下所示
<broker brokerName="broker" ... >
...
<persistenceAdapter>
<replicatedLevelDB
directory="activemq-data"
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="zoo1.example.org:2181,zoo2.example.org:2181,zoo3.example.org:2181"
zkPassword="password"
zkPath="/activemq/leveldb-stores"
hostname="broker1.example.org"
/>
</persistenceAdapter>
...
</broker>
复制 LevelDB 存储属性
属于同一个复制集的所有代理节点都应该具有匹配的 brokerName
XML 属性。以下配置属性在属于同一个复制集的所有代理节点上应该相同
属性名称 | 默认值 | 注释 |
---|---|---|
replicas |
3 |
集群中将存在的节点数。为了避免服务中断,至少 (replicas/2)+1 个节点必须在线。 |
securityToken |
安全令牌,必须在所有复制节点上匹配,以便它们接受彼此的复制请求。 | |
zkAddress |
127.0.0.1:2181 |
逗号分隔的 ZooKeeper 服务器列表。 |
zkPassword |
连接到 ZooKeeper 服务器时要使用的密码。 | |
zkPath |
/default |
ZooKeeper 目录的路径,主/从选举信息将在其中交换。 |
zkSessionTimeout |
2s |
ZooKeeper 检测节点故障的速度。(在 5.11 之前,这有一个错字 zkSessionTmeout) |
sync |
quorum_mem |
控制更新在被认为完成之前驻留的位置。此设置是一个逗号分隔的以下选项列表:local_mem 、local_disk 、remote_mem 、remote_disk 、quorum_mem 、quorum_disk 。如果您为目标组合两个设置,则使用更强的保证。例如,配置 local_mem, local_disk 与仅使用 local_disk 相同。quorum_mem 与 local_mem, remote_mem 相同,而 quorum_disk 与 local_disk, remote_disk 相同 |
不同的复制集可以共享相同的 zkPath
,只要它们具有不同的 brokerName
。
以下配置属性可以针对每个节点唯一设置
属性名称 | 默认值 | 注释 | |
---|---|---|---|
bind |
tcp://0.0.0.0:61619 |
当此节点成为主节点时,它将绑定配置的地址和端口来为复制协议提供服务。使用动态端口也受支持。只需配置 tcp://0.0.0.0:0 |
|
hostname |
当此节点成为主节点时用于宣传复制服务的机器名。如果未设置,它将自动确定。 | ||
weight |
1 |
拥有最新更新且权重最高的复制节点将成为主节点。用于优先考虑某些节点成为主节点。 |
存储还支持标准 LevelDB 存储 的相同配置属性,但它不支持可插拔存储柜
标准 LevelDB 存储属性
属性名称 | 默认值 | 注释 |
---|---|---|
directory |
LevelDB |
存储将用于保存其数据文件的目录。如果存储不存在,则将创建该目录。 |
readThreads |
10 |
允许的并发 IO 读取线程数。 |
logSize |
104857600 (100 MB) |
每个数据日志文件在日志文件轮换发生之前的最大大小(以字节为单位)。 |
verifyChecksums |
false |
设置为 true 以强制对从文件系统读取的所有数据进行校验和验证。 |
paranoidChecks |
false |
如果存储检测到内部损坏,则尽快使其出错。 |
indexFactory |
org.fusesource.leveldbjni.JniDBFactory, org.iq80.leveldb.impl.Iq80DBFactory |
创建 LevelDB 索引时要使用的工厂类。 |
indexMaxOpenFiles |
1000 |
索引可以使用打开的文件数。 |
indexBlockRestartInterval |
16 |
键之间重新启动点的数量,用于键的增量编码。 |
indexWriteBufferSize |
6291456 (6 MB) |
在将索引数据转换为磁盘上的排序文件之前,要在内存中构建的索引数据量。 |
indexBlockSize |
4096 (4 K) |
每个块中打包的索引数据大小。 |
indexCacheSize |
268435456 (256 MB) |
用于缓存索引块的堆外内存的最大量。 |
indexCompression |
snappy |
要应用于索引块的压缩类型。可以是 snappy 或 none。 |
logCompression |
none |
要应用于日志记录的压缩类型。可以是 snappy 或 none。 |
注意事项
LevelDB 存储尚不支持存储与 延迟和计划消息传递 相关联的数据。这些数据存储在单独的非复制 KahaDB 数据文件中。如果您将 延迟和计划消息传递 与复制的 leveldb 存储一起使用,则会发生意外结果,因为当主节点故障转移到从属节点时,该数据将不再存在。