diff --git a/2024/01/rocketmq-kafka-sharding-replication/index.html b/2024/01/rocketmq-kafka-sharding-replication/index.html index a817b95d..29806a66 100644 --- a/2024/01/rocketmq-kafka-sharding-replication/index.html +++ b/2024/01/rocketmq-kafka-sharding-replication/index.html @@ -34,7 +34,7 @@ - + @@ -456,7 +456,7 @@
3
。复制系数配置为 >= 3 的原因是,允许集群内同时发生一次计划内停机和一次计划外停机,配置为 3
是在避免消息丢失和过度复制之间的常见的权衡选择。HBase(基于 HDFS)和 Cassandra 等分布式存储系统默认的复制系数也是 3
。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移除 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移出 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。acks
,用于控制在确认一个请求发送完成之前需要收到的反馈信息的数量。min.insync.replicas
配置项只有在 acks=all
时才生效。
acks=0
:表示 Producer 不等待 Broker 返回确认消息。Kafka 文档 https://kafka.apachecn.org/ https://kafka.apache.org/36/documentation.html ↩︎
Kafka 文档:4. 设计思想:4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
+Kafka Documentation: 4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
2013-02 Jun Rao: Intra-cluster Replication in Apache Kafka https://engineering.linkedin.com/kafka/intra-cluster-replication-apache-kafka https://www.slideshare.net/junrao/kafka-replication-apachecon2013 ↩︎
MySQL 等传统关系数据库支持表分区(partition),但原生不支持分片(sharding),拆分后的表分区都分布在同一个服务器节点上。为了解决数据库的水平扩展问题,出现很多数据库分片方案。其中一类是基于传统关系数据库的“分库分表”中间件,如 Vitess、ShardingSphere、阿里 TDDL 和 DRDS 等。另外一类是非关系型的 NoSQL 数据库,如 BigTable、Dynamo、HBase、Cassandra 等。以及采用全新架构的 NewSQL 数据库,如 Google Spanner、CockroachDB、TiDB 等;或基于云服务的 NewSQL 数据库,如 Amazon Aurora、阿里 PolarDB 等。
术语分片(shard)或分区(partition),在具体的不同系统下有着不同的称呼,例如它对应于 MongoDB、Elasticsearch 和 SolrCloud 中的 shard
,HBase 中的 region
,Bigtable 中的 tablet
,Cassandra 和 Riak 中的 vnode
,以及 Couchbase 中 的 vBucket
。总体而言,分片和分区使用最普遍。
分布式数据库不是本文关注的主题,不再展开。消息中间件的消息存储系统与分布式数据库系统类似,为了系统可扩展性和可用性,也需要支持数据分片和复制特性。
RocketMQ 和 Kafka 的历史演进时间线:
RocketMQ 的数据分片和复制策略[4]:
autoCreateTopicEnable
开启,会在发送消息时轮询选择其中一台 Master Borker,在该 Borker 上分配消息队列。消息队列数由全局配置项 defaultTopicQueueNums
控制,默认值 4
。mqadmin updateTopic
命令,可以通过命令行参数指定在某个 Master Borker 上分配消息队列。也可以通过命令行参数指定 cluster,在 cluster 下的全部的 Master Borker 上分配消息队列,每个 Borker 的消息队列的数量相同。默认队列数 8
。mqadmin updateTopic
命令,在新的 Broker 节点上分配消息队列。brokerRole
用于配置节点的主从角色和复制模式,默认值为 ASYNC_MASTER
,可配置为 SYNC_MASTER
/ASYNC_MASTER
/SLAVE
。Borker
单点故障情况,若采用主从异步复制,可保证 99% 的消息不丢,但是仍然会有极少量的消息可能丢失。若采用主从同步复制可以完全避免单点,但相对损失影响性能,适合对消息可靠性要求极高的场合。FlushDiskType
用于控制磁盘刷盘方式,可配置为异步刷盘 ASYNC_FLUSH
(默认)和同步刷盘 SYNC_FLUSH
。同步刷盘会损失很多性能,但是也更可靠。slaveReadEnable
用于配置是否允许消息从从节点读取,默认 false
。如果 slaveReadEnable=true
,并且当前消息堆积量超过物理内存 40%(由配置项 accessMessageInMemoryMaxRatio
控制),则建议从 Slave Borker 拉取消息,否则还是从 Master Borker 拉取消息。RocketMQ 架构,以及各个 Borker 下的分区和副本分布示例,如下图所示:
topic1
的分区和分区副本的分布。num.partitions
控制 Topic 的默认分区总数量,默认值 1
。kafka-topics.sh --create
命令,由 --partitions
命令行参数控制该 Topic 的分区总数量。kafka-reassign-partitions.sh
。default.replication.factor
全局控制 Topic 的默认副本个数,默认值 1
。kafka-topics.sh --create
命令,由 --replication-factor
命令行参数控制该 Topic 的分区副本的复制系数。3
。复制系数配置为 >= 3 的原因是,允许集群内同时发生一次计划内停机和一次计划外停机,配置为 3
是在避免消息丢失和过度复制之间的常见的权衡选择。HBase(基于 HDFS)和 Cassandra 等分布式存储系统默认的复制系数也是 3
。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移除 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。acks
,用于控制在确认一个请求发送完成之前需要收到的反馈信息的数量。min.insync.replicas
配置项只有在 acks=all
时才生效。acks=0
:表示 Producer 不等待 Broker 返回确认消息。acks=1
(Kafka < v3.0 默认):表示 leader 节点会将记录写入本地日志,并且在所有 follower 节点反馈之前就先确认成功。acks=all
(Kafka >= v3.0 默认):表示 leader 节点会等待所有同步中的副本(ISR集合)确认之后再确认这条记录是否发送完成。acks=0
或 acks=1
时,相当于异步复制。acks=all
并且 min.insync.replicas
值大于 1
并小于 Broker 节点总数时,相当于半同步复制。acks=all
并且 min.insync.replicas
值等于 Broker 节点总数时,相当于全同步复制。Kafka 在 ZooKeeper 模式下的架构图,以及各个 Borker 下的分区和副本分布示例,如下图所示:
Kafka 在 KRaft 模式下的架构图,如下图所示[18:1]:
2017-11 阿里林清山隆基:阿里消息中间件架构演进之路:notify和metaq https://zhuanlan.zhihu.com/p/302600352 ↩︎
2013-07 淘宝张乐伟韩彰:淘宝消息中间件技术演变:MetaQ 1.0、MetaQ 2.0、MetaQ 3.0(slides, 30p)https://www.modb.pro/doc/109298 ↩︎
2017-03 阿里冯嘉鼬神:Apache RocketMQ背后的设计思路与最佳实践 https://developer.aliyun.com/article/71889 ↩︎
Apache RocketMQ 4.9.x开发者指南 https://github.com/apache/rocketmq/blob/4.9.x/docs/cn ↩︎
2019-03 张乘辉:深度解析RocketMQ Topic的创建机制 https://objcoding.com/2019/03/31/rocketmq-topic/ ↩︎
Apache RocketMQ 4.9.x开发者指南:特性:4 消息可靠性 https://github.com/apache/rocketmq/blob/4.9.x/docs/cn/features.md ↩︎
2016-04 Kafka vs RocketMQ——单机系统可靠性 https://web.archive.org/web/0/http://jm.taobao.org/2016/04/28/kafka-vs-rocktemq-4 ↩︎
2018-12 How much memory should we use for broker and namesrv when using cluster mode? #614 https://github.com/apache/rocketmq/issues/614 ↩︎
2019-09 张乘辉:RocketMQ主从读写分离机制 https://objcoding.com/2019/09/22/rocketmq-read-write-separation/ ↩︎
2019-08 金融通、武文良:RocketMQ 实现高可用多副本架构的关键:DLedger—基于raft协议的commitlog存储库 https://mp.weixin.qq.com/s/0nmWq29FN17vNzt0njRE-Q https://www.infoq.cn/article/7xeJrpDZBa9v*GDZOFS6 ↩︎
2022-09 金融通:RocketMQ 5.0:面向消息与流的云原生高可用架构 https://mp.weixin.qq.com/s/bb6cGUxpsAoU-IqBgmSJHw ↩︎
Kafka 文档 https://kafka.apachecn.org/ https://kafka.apache.org/36/documentation.html ↩︎
Kafka 文档:4. 设计思想:4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
2013-02 Jun Rao: Intra-cluster Replication in Apache Kafka https://engineering.linkedin.com/kafka/intra-cluster-replication-apache-kafka https://www.slideshare.net/junrao/kafka-replication-apachecon2013 ↩︎
Optimize Confluent Cloud Clients for Durability https://docs.confluent.io/cloud/current/client-apps/optimizing/durability.html ↩︎
2019-06 胡夕:Kafka 2.3 核心技术与实战:11 | 无消息丢失配置怎么实现? https://time.geekbang.org/column/article/102931 ↩︎
Kafka Documentation: Application vs. OS Flush Management https://kafka.apache.org/36/documentation.html#appvsosflush ↩︎ ↩︎
2019-08 胡夕:Kafka 2.3 核心技术与实战:26 | 你一定不能错过的Kafka控制器(Controller) https://time.geekbang.org/column/article/111339 ↩︎
2022-04 Jun Rao: The Apache Kafka Control Plane (ZooKeeper vs. KRaft) https://developer.confluent.io/courses/architecture/control-plane/ ↩︎
MySQL 等传统关系数据库支持表分区(partition),但原生不支持分片(sharding),拆分后的表分区都分布在同一个服务器节点上。为了解决数据库的水平扩展问题,出现很多数据库分片方案。其中一类是基于传统关系数据库的“分库分表”中间件,如 Vitess、ShardingSphere、阿里 TDDL 和 DRDS 等。另外一类是非关系型的 NoSQL 数据库,如 BigTable、Dynamo、HBase、Cassandra 等。以及采用全新架构的 NewSQL 数据库,如 Google Spanner、CockroachDB、TiDB 等;或基于云服务的 NewSQL 数据库,如 Amazon Aurora、阿里 PolarDB 等。
术语分片(shard)或分区(partition),在具体的不同系统下有着不同的称呼,例如它对应于 MongoDB、Elasticsearch 和 SolrCloud 中的 shard
,HBase 中的 region
,Bigtable 中的 tablet
,Cassandra 和 Riak 中的 vnode
,以及 Couchbase 中 的 vBucket
。总体而言,分片和分区使用最普遍。
分布式数据库不是本文关注的主题,不再展开。消息中间件的消息存储系统与分布式数据库系统类似,为了系统可扩展性和可用性,也需要支持数据分片和复制特性。
RocketMQ 和 Kafka 的历史演进时间线:
RocketMQ 的数据分片和复制策略[4]:
autoCreateTopicEnable
开启,会在发送消息时轮询选择其中一台 Master Borker,在该 Borker 上分配消息队列。消息队列数由全局配置项 defaultTopicQueueNums
控制,默认值 4
。mqadmin updateTopic
命令,可以通过命令行参数指定在某个 Master Borker 上分配消息队列。也可以通过命令行参数指定 cluster,在 cluster 下的全部的 Master Borker 上分配消息队列,每个 Borker 的消息队列的数量相同。默认队列数 8
。mqadmin updateTopic
命令,在新的 Broker 节点上分配消息队列。brokerRole
用于配置节点的主从角色和复制模式,默认值为 ASYNC_MASTER
,可配置为 SYNC_MASTER
/ASYNC_MASTER
/SLAVE
。Borker
单点故障情况,若采用主从异步复制,可保证 99% 的消息不丢,但是仍然会有极少量的消息可能丢失。若采用主从同步复制可以完全避免单点,但相对损失影响性能,适合对消息可靠性要求极高的场合。FlushDiskType
用于控制磁盘刷盘方式,可配置为异步刷盘 ASYNC_FLUSH
(默认)和同步刷盘 SYNC_FLUSH
。同步刷盘会损失很多性能,但是也更可靠。slaveReadEnable
用于配置是否允许消息从从节点读取,默认 false
。如果 slaveReadEnable=true
,并且当前消息堆积量超过物理内存 40%(由配置项 accessMessageInMemoryMaxRatio
控制),则建议从 Slave Borker 拉取消息,否则还是从 Master Borker 拉取消息。RocketMQ 架构,以及各个 Borker 下的分区和副本分布示例,如下图所示:
topic1
的分区和分区副本的分布。num.partitions
控制 Topic 的默认分区总数量,默认值 1
。kafka-topics.sh --create
命令,由 --partitions
命令行参数控制该 Topic 的分区总数量。kafka-reassign-partitions.sh
。default.replication.factor
全局控制 Topic 的默认副本个数,默认值 1
。kafka-topics.sh --create
命令,由 --replication-factor
命令行参数控制该 Topic 的分区副本的复制系数。3
。复制系数配置为 >= 3 的原因是,允许集群内同时发生一次计划内停机和一次计划外停机,配置为 3
是在避免消息丢失和过度复制之间的常见的权衡选择。HBase(基于 HDFS)和 Cassandra 等分布式存储系统默认的复制系数也是 3
。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移出 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。acks
,用于控制在确认一个请求发送完成之前需要收到的反馈信息的数量。min.insync.replicas
配置项只有在 acks=all
时才生效。acks=0
:表示 Producer 不等待 Broker 返回确认消息。acks=1
(Kafka < v3.0 默认):表示 leader 节点会将记录写入本地日志,并且在所有 follower 节点反馈之前就先确认成功。acks=all
(Kafka >= v3.0 默认):表示 leader 节点会等待所有同步中的副本(ISR集合)确认之后再确认这条记录是否发送完成。acks=0
或 acks=1
时,相当于异步复制。acks=all
并且 min.insync.replicas
值大于 1
并小于 Broker 节点总数时,相当于半同步复制。acks=all
并且 min.insync.replicas
值等于 Broker 节点总数时,相当于全同步复制。Kafka 在 ZooKeeper 模式下的架构图,以及各个 Borker 下的分区和副本分布示例,如下图所示:
Kafka 在 KRaft 模式下的架构图,如下图所示[18:1]:
2017-11 阿里林清山隆基:阿里消息中间件架构演进之路:notify和metaq https://zhuanlan.zhihu.com/p/302600352 ↩︎
2013-07 淘宝张乐伟韩彰:淘宝消息中间件技术演变:MetaQ 1.0、MetaQ 2.0、MetaQ 3.0(slides, 30p)https://www.modb.pro/doc/109298 ↩︎
2017-03 阿里冯嘉鼬神:Apache RocketMQ背后的设计思路与最佳实践 https://developer.aliyun.com/article/71889 ↩︎
Apache RocketMQ 4.9.x开发者指南 https://github.com/apache/rocketmq/blob/4.9.x/docs/cn ↩︎
2019-03 张乘辉:深度解析RocketMQ Topic的创建机制 https://objcoding.com/2019/03/31/rocketmq-topic/ ↩︎
Apache RocketMQ 4.9.x开发者指南:特性:4 消息可靠性 https://github.com/apache/rocketmq/blob/4.9.x/docs/cn/features.md ↩︎
2016-04 Kafka vs RocketMQ——单机系统可靠性 https://web.archive.org/web/0/http://jm.taobao.org/2016/04/28/kafka-vs-rocktemq-4 ↩︎
2018-12 How much memory should we use for broker and namesrv when using cluster mode? #614 https://github.com/apache/rocketmq/issues/614 ↩︎
2019-09 张乘辉:RocketMQ主从读写分离机制 https://objcoding.com/2019/09/22/rocketmq-read-write-separation/ ↩︎
2019-08 金融通、武文良:RocketMQ 实现高可用多副本架构的关键:DLedger—基于raft协议的commitlog存储库 https://mp.weixin.qq.com/s/0nmWq29FN17vNzt0njRE-Q https://www.infoq.cn/article/7xeJrpDZBa9v*GDZOFS6 ↩︎
2022-09 金融通:RocketMQ 5.0:面向消息与流的云原生高可用架构 https://mp.weixin.qq.com/s/bb6cGUxpsAoU-IqBgmSJHw ↩︎
Kafka 文档 https://kafka.apachecn.org/ https://kafka.apache.org/36/documentation.html ↩︎
Kafka Documentation: 4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
2013-02 Jun Rao: Intra-cluster Replication in Apache Kafka https://engineering.linkedin.com/kafka/intra-cluster-replication-apache-kafka https://www.slideshare.net/junrao/kafka-replication-apachecon2013 ↩︎
Optimize Confluent Cloud Clients for Durability https://docs.confluent.io/cloud/current/client-apps/optimizing/durability.html ↩︎
2019-06 胡夕:Kafka 2.3 核心技术与实战:11 | 无消息丢失配置怎么实现? https://time.geekbang.org/column/article/102931 ↩︎
Kafka Documentation: Application vs. OS Flush Management https://kafka.apache.org/36/documentation.html#appvsosflush ↩︎ ↩︎
2019-08 胡夕:Kafka 2.3 核心技术与实战:26 | 你一定不能错过的Kafka控制器(Controller) https://time.geekbang.org/column/article/111339 ↩︎
2022-04 Jun Rao: The Apache Kafka Control Plane (ZooKeeper vs. KRaft) https://developer.confluent.io/courses/architecture/control-plane/ ↩︎
3
。复制系数配置为 >= 3 的原因是,允许集群内同时发生一次计划内停机和一次计划外停机,配置为 3
是在避免消息丢失和过度复制之间的常见的权衡选择。HBase(基于 HDFS)和 Cassandra 等分布式存储系统默认的复制系数也是 3
。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移除 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。replica.lag.time.max.ms
配置值(Kafka 2.5 开始从默认 10 秒改为 30 秒),那么该 follower 副本会被认为是“不同步副本”(out-of-sync replica,OSR),会被移出 ISR 集合。当不同步副本重新同步后,会被加回到 ISR 集合中。当 leader 所在的节点发生崩溃,ISR 集合中的一个 follower 会被 Controller 选举为新 leader。在消息 commit 之前必须保证 ISR 集合中的全部节点都完成同步复制。这种机制确保了只要 ISR 中有一个或者以上的 follower,一条被 commit 的消息就不会丢失。最小 ISR 集合大小由 Broker 端的配置项 min.insync.replicas
控制,默认值 1
,即只需要 leader。如果同步副本小于 min.insync.replicas
,尝试向 Broker 发送数据的生产者会收到 NotEnoughReplicasException
或 NotEnoughReplicasAfterAppendException
异常。acks
,用于控制在确认一个请求发送完成之前需要收到的反馈信息的数量。min.insync.replicas
配置项只有在 acks=all
时才生效。
acks=0
:表示 Producer 不等待 Broker 返回确认消息。Kafka 文档 https://kafka.apachecn.org/ https://kafka.apache.org/36/documentation.html ↩︎
Kafka 文档:4. 设计思想:4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
+Kafka Documentation: 4.7 Replication https://kafka1x.apachecn.org/documentation.html#replication https://kafka.apache.org/36/documentation.html#replication ↩︎
2013-02 Jun Rao: Intra-cluster Replication in Apache Kafka https://engineering.linkedin.com/kafka/intra-cluster-replication-apache-kafka https://www.slideshare.net/junrao/kafka-replication-apachecon2013 ↩︎