对于一个复杂的分布式系统,如果没有丰富的经验和牛逼的架构能力,很难把系统做得简单易维护,我们都知道,一个软件的生命周期中,后期维护占了70%,所以系统的可维护性是极其重要的, kafka 能成为大数据领域的事实标准,很大原因是因为运维起来很方便简单,今天我们来看下 kafka 是怎么来简化运维操作的。

kafka 使用多副本来保证消息不丢失,多副本就涉及到kafka的复制机制,在一个超大规模的集群中,时不时地这个点磁盘坏了,那个点cpu负载高了,出现各种各样的问题,多个副本之间的复制,如果想完全自动化容错,就要做一些考量和取舍了。我们举个例子说明下运维中面对的复杂性,我们都知道 kafka 有个 ISR集合,我先说明下这个概念:

kafka不是完全同步,也不是完全异步,是一种ISR机制:

1. leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护

2. 如果一个follower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除

3. 当ISR中所有Replica都向Leader发送ACK时,leader才commit,这时候producer才能认为一个请求中的消息都commit了。

在这种机制下,如果一个  producer 一个请求发送的消息条数太多,导致flower瞬间落后leader太多怎么办?如果 follower不停的移入移出 ISR 会不会影响性能?如果对这种情况加了报警,就有可能造成告警轰炸,如果我们不加报警,如果是broker 挂掉或者 broker 因为IO性能或者GC问题夯住的情况导致落后leader太多,这种真正需要报警情况怎么办呢?今天我们来看下 kafka 是怎么在设计上让我们完全避免这种运维中头疼的问题的。

kafka的复制机制

kafka 每个分区都是由顺序追加的不可变的消息序列组成,每条消息都一个唯一的offset 来标记位置。

kafka中的副本机制是以分区粒度进行复制的,我们在kafka中创建 topic的时候,都可以设置一个复制因子,这个复制因子决定着分区副本的个数,如果leader 挂掉了,kafka 会把分区主节点failover到其他副本节点,这样就能保证这个分区的消息是可用的。leader节点负责接收producer 打过来的消息,其他副本节点(follower)从主节点上拷贝消息。

kakfa 日志复制算法提供的保证是当一条消息在 producer 端认为已经 committed的之后,如果leader 节点挂掉了,其他节点被选举成为了 leader 节点后,这条消息同样是可以被消费到的。

这样的话,leader 选举的时候,只能从 ISR集合中选举,集合中的每个点都必须是和leader消息同步的,也就是没有延迟,分区的leader 维护ISR 集合列表,如果某个点落后太多,就从 ISR集合中踢出去。 producer 发送一条消息到leader节点后, 只有当ISR中所有Replica都向Leader发送ACK确认这条消息时,leader才commit,这时候producer才能认为这条消息commit了,正是因为如此,kafka客户端的写性能取决于ISR集合中的最慢的一个broker的接收消息的性能,如果一个点性能太差,就必须尽快的识别出来,然后从ISR集合中踢出去,以免造成性能问题。kafka 复制机制详情参考  https://kafka.apache.org/documentation.html#replication

一个副本怎么才算是跟得上leader的副本

一个副本不能 “caught up” leader 节点,就有可能被从 ISR集合中踢出去,我们举个例子来说明,什么才是真正的 “caught up” —— 跟leader节点消息同步。

kafka 中的一个单分区的 topic — foo,复制因子为 3 ,分区分布和 leader 和 follower 如下图,现在broker 2和3 是 follower 而且都在 ISR 集合中。我们设置 replica.lag.max.messages 为4,只要 follower 只要不落后leader 大于3条消息,就然后是跟得上leader的节点,就不会被踢出去, 设置  replica.lag.time.max.ms 为 500ms, 意味着只要 follower 在每 500ms内发送fetch请求,就不会被认为已经dead ,不会从ISR集合中踢出去。

现在 producer 发送一条消息,offset 为3, 这时候 broker 3 发生了 GC, 入下图:

因为 broker 3 现在在 ISR 集合中, 所以要么 broker 3  拉取同步上这条 offset 为3 的消息,要么 3 被从 ISR集合中踢出去,不然这条消息就不会 committed, 因为 replica.lag.max.messages=4 为4, broker 3 只落后一条消息,不会从ISR集合中踢出去, broker 3 如果这时候 GC  100ms, GC 结束,然后拉取到 offset 为3的消息,就再次跟 leader 保持完全同步,整个过程一直在 ISR集合中,如下图:

什么时候一个副本才会从ISR集合中踢出去

一个副本被踢出 ISR集合的几种原因:

  • 一个副本在一段时间内都没有跟得上 leader 节点,也就是跟leader节点的差距大于 replica.lag.max.messages, 通常情况是 IO性能跟不上,或者CPU 负载太高,导致 broker 在磁盘上追加消息的速度低于接收leader 消息的速度。

  • 一个 broker 在很长时间内(大于 replica.lag.time.max.ms )都没有向 leader 发送fetch 请求,  可能是因为 broker 发生了 full GC, 或者因为别的原因挂掉了。

  • 一个新 的 broker 节点,比如同一个 broker id, 磁盘坏掉,新换了一台机器,或者一个分区 reassign 到一个新的broker 节点上,都会从分区leader 上现存的最老的消息开始同步。

所以说 kafka 0.8 版本后设置了两个参数  , replica.lag.max.messages 用来识别性能一直很慢的节点, replica.lag.time.max.ms 用来识别卡住的节点。

一个节点在什么情况下真正处于落后状态

从上面的情况来看,两个参数看似已经足够了,如果一个副本超过 replica.lag.time.max.ms还没有发送fetch同步请求, 可以认为这个副本节点卡住了,然后踢出去,但是还有一种比较特殊的情况没有考虑到,我们上文中设置 replica.lag.max.messages 为4,之所以设置为 4, 是我们已经知道 producer 每次请求打过来的消息数都在 4 以下,如果我们的参数是作用于多个 topic 的情况,那么这个 producer 最大打过来的消息数目就不好估计了,或者说在经常出现流量抖动的情况下,就会出现一个什么情况呢,我们还是使用例子说明:

如果我们的 topic — foo  的 producer 因为流量抖动打过来一个 包含 4条消息的请求,我们设置的 replica.lag.max.messages 还是为4, 这个时候,所有的 follower 都会因为超出落后条数被踢出 ISR集合:

然后,因为 follower 是正常的,所以下一次 fetch 请求就会又追上 leader, 这时候就会再次加入 ISR 集合,如果经常性的抖动,就会不断的移入移出ISR集合,会造成令人头疼的 告警轰炸。

这里的核心问题是,在海量的 topic 情况下,或者经常性的流量抖动情况下,我们不能对 topic 的producer 每次打过来的消息数目做任何假设,所以就不太好定出来一个 合适的 eplica.lag.max.messages 

一个配置全部搞定

其实只有两种情况是异常的,一种就是卡住,另外一种是follower 性能慢,如果我们只根据 follower 落后 leader 多少来判断是否应该把 follower 提出ISR集合,就必须要对流量进行预测估计,怎么才能避免这种不靠谱的估计呢,kafka 给出的方案是这样的,对 replica.lag.time.max.ms 这个配置的含义做了增强,和之前一样,如果 follower 卡住超过这个时间不发送fetch请求, 会被踢出ISR集合,新的增强逻辑是,在 follower 落后 leader 超过 eplica.lag.max.messages 条消息的时候,不会立马踢出ISR 集合,而是持续落后超过  replica.lag.time.max.ms 时间,才会被踢出,这样就能避免流量抖动造成的运维问题,因为follower 在下一次fetch的时候就会跟上leader, 这样就也不用对 topic 的写入速度做任何的估计喽。

面试|图解kafka的高可用机制相关推荐

  1. Hystrix面试 - 用 Hystrix 构建高可用服务架构

    Hystrix面试 - 用 Hystrix 构建高可用服务架构 Hystrix 是什么? 在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也 ...

  2. HA:HADOOP高可用机制

    课程大纲(HADOOP高可用机制) HA运作机制 什么是HA HADOOP如何实现HA HDFS-HA详解 HA集群搭建 目标: 掌握分布式系统中HA机制的思想 掌握HADOOP内置HA的运作机制 掌 ...

  3. 2021年大数据Hadoop(十四):HDFS的高可用机制

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 HDFS的高可用机制 HDFS高可用介绍 组件介绍 Nam ...

  4. 我的架构梦:(九十九)消息中间件之RocketMQ的高可用机制——消息消费高可用

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 一.前言 在前两篇我们介绍了 我的架构梦:(九十七)消息中间件之Ro ...

  5. 我的架构梦:(九十八)消息中间件之RocketMQ的高可用机制——消息发送高可用

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 一.前言 在上一篇我们介绍了 我的架构梦:(九十七)消息中间件之Ro ...

  6. RocketMQ高可用机制----同步刷盘、异步刷盘和同步复制、异步复制

    RocketMQ高可用机制----同步刷盘.异步刷盘和同步复制.异步复制 同步刷盘.异步刷盘 RocketMQ的消息是存储到磁盘上的,这样既能保证断电后恢复,又可以让存储的消息量超出内存的限制. Ro ...

  7. rocketmq 高可用机制

    高可用机制 RocketMQ分布式集群是通过Master和Slave的配合达到高可用性 Master和Slave的区别:在Broker的配置文件中,参数brokerId的值为0表明这个Brocker是 ...

  8. Kafka高可用机制入门

    概念 在Kafka在0.8以前的版本中,是没有Replication的,一旦某一个Broker宕机,则其上所有的Partition数据都不可被消费,这与Kafka数据持久性及Delivery Guar ...

  9. Kafka学习之路 (三)Kafka的高可用

    一.高可用的由来 1.1 为何需要Replication 在Kafka在0.8以前的版本中,是没有Replication的,一旦某一个Broker宕机,则其上所有的Partition数据都不可被消费, ...

最新文章

  1. 阿尔法特磁悬浮制冷机组荣获“2016年度中国数据中心优秀节能产品”殊荣
  2. Squid代理服务器基本配置(三)
  3. 成绩差的同学为何大多当老板?
  4. 设计模式(八): 从“小弟”中来类比外观模式(Facade Pattern)
  5. Android RaingBar评分条的使用
  6. arcgis js 地图打印_Arcgis在国土空间规划编制中的应用
  7. 学习笔记之awk用法
  8. 【论文写作】2021毕业论文写作选题技巧,建议收藏!
  9. windows 10卸载(注销)WSL,注销(卸载)当前安装的Linux的Windows子系统
  10. spark生成DataFrame
  11. thinkphp实现文章访问量计数器
  12. OSError: [WinError 126] module could not be found(OSError: [WinError 126] 找不到指定的模块)
  13. 1160. 不容易系列之二
  14. ES2015 for of 循环
  15. python爬虫爬取今日头条_爬取今日头条头条号文章数据
  16. 雷达的发展历史及性能指标
  17. 使用STM32f103点亮led灯——库函数版本
  18. Vue点击选中(多选)选中右上角有三角形
  19. PyCharm 安装 jieba 显示“No module named jieba”解决方法
  20. 它被称为“蓝领”的编程语言!90%的财富500强公司都在使用!

热门文章

  1. 如何在 CentOS 7 上生成 SSL 证书为 Nginx 加密
  2. sed实例(持续更新)
  3. C# Combobox联动
  4. 数据库多个表内容合并
  5. Attention To, Convert To Capped Collection
  6. 你真的了解实时计算吗?
  7. 购买使用vps建站(3)
  8. 解决media player内部应用程序错误
  9. 双边滤波(bilateral filter)彩色图 matlab实现代码
  10. windows下ffmpeg使用dxva2加速硬件解码