系统整体的可用性取决于系统中最容易出现故障,或者性能最低的组件。
系统中的各个组件要进行高可用设计,防止单点故障
消息队列高可用手段
分布式系统的高可用依赖副本技术
当出现某个节点宕机时,能够快速地进行替换
提升系统整体可靠性,防止数据丢失
消息队列在系统中承担了数据存储和数据传输的功能
消息队列的高可用设计,比数据库,文件索引等持久化存储要复杂
Kafka 的副本机制
Kafka 的高可用实现主要依赖副本机制
Kafka 的 Broker 和 Partition 的关系机制
一个 Broker 可以容纳多个 Topic
Kafka 为了实现可扩展性,将一个 Topic 分散到多个 Partition 中
Partition 是一段连续的存储,如果是在同一个 Broker 中,不能挂载到多个磁盘
一个 Broker 可以有多个 Topic ,对应多个 Partition
Partition 可以细分为一个或者多个 Segment
每个 Segment 都对应一个 index 索引文件,以及一个 log 数据文件
Replication 之间如何同步数据
如果没有副本,当某个 Kafka Broker 挂掉,或者某台服务器宕机(可能部署了多个 Broker)
存储在其上的消息就不能被正常消费,导致系统可用性降低,或者出现数据丢失
配置参数 replication-factor (副本因子) —— 调整对应分区下副本的数量
注意副本因子数包含原来的 Partition
如果需要有 2 个副本,则要配置为 3
假设现在有一个订单的 Topic ,配置分区数为3,如果配置 replication-factor 为 3
那么对应的有三个分区,每个分区都有3个副本
在有多个副本的情况下,不同副本之间如何分工呢?
每个分区下配置多个副本,必须有一定的同步机制
Kafka 中同一个分区下的不同副本:Leader Replication 和 Follower Replication
- Leader —— 处理所有的 Producer,Consumer 的请求,进行读写处理
-
Follower—— 数据备份,不处理来自客户端的请求
使用 GIt 进行版本管理的 fetch 命令,会为数据同步开辟一个单独的线程称为 ReplicaFetcherThread 该线程会主动从 Leader 批量拉取数据
Replication 分配有哪些约定
- 为了更好的做负载均衡,Kafka 会将所有的 Partition 均匀地分配到整个集群上
- 为了提高 Kafka 的系统容错能力,一个 Partition 的副本,也要分散到不同的 Broker 上
Kafka 的分区和副本分配遵循的原则
一个 Topic 的 Partition 数量大于 Broker 的数量,使得 Partition 尽量均匀分配到整个集群上
同一个分区,所有的副本要尽量均匀分配到集群中的多台 Broker 上
尽可能保证同一个分区下的主从副本,分配到不同的 Broker 上
Leader Replication 如何选举
引入 Replication 机制之后,同一个 Partition 可能会有多个副本
如果 Leader 挂掉,需要在这些副本之间选出一个新的 Leader
Kafka 数据同步中有一个 ISR (In-Sync Replicas,副本同步队列) 的概念
Leader 节点在返回 ACK 响应时,会关注 ISR 中节点的同步状态
队列里的所有副本,都和 Leader 保持一致
Kafka 的 ISR 依赖 Zookeeper 进行管理,ISR 副本同步队列中的节点,拥有优先选举的权利
如果某个 Broker 挂掉,Kafka 会从 ISR 列表中选择一个分区作为新的 Leader 副本
如果 ISR 列表是空的
- 直接抛出 NoReplicaOnlineException 异常,保证一致性
- 从其他副本中选择一个作为 Leader ,则可能会丢失数据
所有的副本都挂了怎么办?
Kafka 需要等待某个副本恢复服务:
等待 ISR 中的某个副本恢复正常,作为新的 Leader
(会保证数据不丢失,但是如果全部的 ISR 节点都彻底宕机,对应的分区会彻底不可用)等任意一个副本恢复正常,作为新的 Leader
(可能存在数据丢失,不能保证已经包含全部 Commit 的信息)