作者:vivo 互联网服务器团队-Luo Mingbo

一、Kafka 集群部署架构

为了让读者能与小编在后续的问题分析中有更好的共鸣,小编先与各位读者朋友对齐一下我们 Kafka 集群的部署架构及服务接入 Kafka 集群的流程。

为了避免超大集群我们按照业务维度将整个每天负责十万亿级消息的 Kafka 集群拆分成了多个 Kafka 集群。拆分粒度太粗会导致单一集群过大,容易由于流量突变、资源隔离、限速等原因导致集群稳定性和可用性受到影响,拆分粒度太细又会因为集群太多不易维护,集群内资源较少应对突发情况的抗风险能力较弱。

由于 Kafka 数据存储和服务在同一节点上导致集群扩缩容周期较长,遇到突发流量时不能快速实现集群扩容扛住业务压力,因此我们按照业务维度和数据的重要程度及是否影响商业化等维度进行 Kafka 集群的拆分,同时在 Kafka 集群内添加一层逻辑概念“资源组”,资源组内的 Node 节点共享,资源组与资源组之间的节点资源相互隔离,确保故障发生时不会带来雪崩效应。

二、业务接入 Kafka 集群流程

  1. 在 Kafka 平台注册业务项目。

  2. 若项目的业务数据较为重要或直接影响商业化,用户需申请创建项目独立的资源组,若项目数据量较小且对数据的完整性要求不那么高可以直接使用集群提供的公共资源组无需申请资源组。

  3. 项目与逻辑概念资源组绑定。

  4. 创建 topic,创建 topic 时使用 Kafka 平台提供的接口进行创建,严格遵守 topic 的分区分布只能在项目绑定的资源组管理的 broker 节点上。

  5. 授权对 topic 的读写操作。

通过上述的架构部署介绍及接入流程接入介绍相信大家有很多相关知识点都与小编对齐了。

从部署架构图我们可以清晰的了解到我们这套集群部署在服务端最小的资源隔离单元为“资源组”即在同一个资源组下的多个broker节点之间会有影响,不同的资源组下的broker节点做了逻辑隔离。

上述的相关知识点对齐后我们将开启我们的故障排查之旅。

三、故障情况介绍

故障发生时,故障节点所在资源组的多个 topic 流量几乎全部掉零,生产环境我们对 Kafka 集群的磁盘指标READ、WRITE、IO.UTIL、AVG.WAIT、READ.REQ、WRITE.REQ做了告警监控,由于故障发生在凌晨,整个故障的处理过程持续实践较长,导致了业务方长时间的topic流量整体掉零对业务造成不小的影响。

四、监控指标介绍

4.1 流量监控情况

1、故障节点在故障发生时网络空闲率出现短暂的掉零情况,且与生产流量监控指标一致。一旦生产流量上升故障节点的网络空闲率就同步掉零。

2、Grafana 监控指标中topic生产流量几乎全部掉零。

3、Kafka 平台项目监控中也体现了当前项目的多个topic生产流量指标掉零。

4.2 磁盘指标监控

SDF 盘的IO.UTIL指标达到100%, 80%左右我们认为是服务可稳定运行的指标阈值。

SDF 盘的AVG.WAIT指标达到分钟级等待,一般400ms左右的延迟我们认为是服务可稳定运行的阈值。

4.3 Kafka 服务端日志及系统日志情况

Kafka集群controller节点的日志中出现Input/Output error的错误日志。

Linux 系统日志中出现Buffer I/O error 的错误日志

五、故障猜想及分析

从上述的指标监控中很明显的可以得出结论,故障原因是由于 Kafka broker节点的sdf盘磁盘故障导致的,只需在对应的 Kafka broker 节点上将sdf盘踢掉重启即可恢复。那这样就结束了吗 ?of course not。

对 Kafka 有一定认识的小伙伴应该都知道,创建topic时topic的分区是均匀分布到集群内的不同broker节点上的,即使内部某一台broker节点故障,其他分区应该能正常进行生产消费,如果其他分区能进行正常的生产和消费就不应该出现整个topic的流量几乎全掉零的情况。

如上图所示,topicA 的三个分区分别分布在 brokerA、brokerB、brokerC三个物理主机节点上。

生产者producer向TopicA发送消息时会分别与brokerA、brokerB、brokerC三个物理主机节点建立长链接进行消息的发送,此时若 brokerB 节点发生故障无法向外部提供服务时按照我们的猜想应该不会影响到brokerA和brokerC两个节点继续向producer提供接收消息的服务。

但从监控指标的数据展示来分析当brokerB节点出现故障后topic整体流量掉零与我们的猜想大相径庭。

既然是出现类似了服务雪崩的效应导致了部分topic的整体流量几乎掉零那么我们在猜想问题发生的原因时就可以往资源隔离的方向去思考,看看在整个过程中还有哪些地方涉及到资源隔离的环节进行猜想。

Kafka 服务端我们按照资源组的方式做了 Kafka broker的逻辑隔离且从Grafana监控上可以看出有一些topic的流量并没有严重掉零的情况,那么我们暂时将分析问题的目光转移到 Kafka  client端,去分析 Kafka  producer的发送消息的过程是否存在有资源隔离地方没有做隔离导致了整体的雪崩效应。

六、Kafka 默认分区器的分区规则

对 Kafka 生产流程流程有一定了解的同学肯定知道,Kafka 作为了大数据生态中海量数据的消息中间件,为了解决海量数据的并发问题 Kafka  在设计之初就采用了客户端缓冲消息,当消息达到一定批量时再进行批量消息的发送。

通过一次网络IO将批量的数据发送到 Kafka 服务端。关于Kafka producer客户端缓冲区的设计小编后续会单独一个篇幅进行深入的探索,鉴于篇幅问题不再此处进行详细分析。

基于此处的分析我们对一批消息发送到一个故障节点时的容错方案可以有以下猜想:

  1. 快速失败,记录故障节点信息。下次进行消息路由时只路由到健康的节点上。快速释放消息缓冲内存。

  2. 快速失败,记录故障节点信息,下次进行消息路由时当消息路由到故障节点上时直接报错,快速释放缓冲区内存。

  3. 等待超时,当次消息等待超时后,下次进行消息路由时依然会出现路由到故障节点上的情况,且每次等待超时时间后才释放占用的资源。

上述猜想中,如果是第一种情况,那么每次消息路由只路由到健康的节点上不会出现雪崩效应耗尽客户端缓冲区资源的情况;

第二种情况,当消息路由到故障节点上时,直接拒绝分配缓冲区资源也不会造成雪崩效应;

第三种情况,每次需要在一个或多个超时时间后才能将故障节点所占用的客户端缓冲区资源释放,在海量消息发送的场景下一个超时时间周期内故障节点上的消息足以将客户端缓冲区资源耗尽,导致其他可用分区无法分配客户端缓冲区资源导致出现雪崩效应。

带着上述的猜想打开kafka client producer的源代码分析下defaultPartitioner的分区规则得到如下的分配逻辑:

  1. 发送消息时是否指定了分区,若指定了分区那消息就直接发往该分区无需重新路由分区。

  2. 消息是否指定了key,若消息指定了key,使用key的hash值与topic的分区数进行模运算,得出消息路由的分区号(对应第三种猜想)。

  3. 消息未指定分区也未指定key,使用自增变量与topic的可用分区进行模运算,得出消息路由的分区号(对应第一种猜想)。

七、总结

  1. 从源码中分析出若发送消息的时候指定了key,并使用的是 Kafka producer默认的分区分配器请款下会出现 Kafka producer 客户端缓冲区资源被耗尽而出现topic所有分区雪崩效应。

  2. 跟业务系统同学了解了他们的发送逻辑确实在消息发送指定了key并使用的是 Kafka producer的默认分区分配器。

  3. 问题得到论证。

八、建议

  1. 若非必要发送消息时不要指定key,否则可能会出现topic所有分区雪崩效应。

  2. 若确实需要发送消息指定key,建议不要使用Kafka producer默认的分区分配器,因为指定key的情况下使用 Kafka producer的默认分区分配器会出现雪崩效应。

九、扩展问题思考

  1. 为什么 Kafka producer提供的默认分区分配器要单独将指定key的情况采用topic所有分区进行模运算而在未指定key的采用是自增变量和可用分区进行模运算?

  2. 文章中分析的问题均为客户端缓冲区的粒度是producer实例级别的即一个producer共用一块内存缓冲区是否可以将缓冲区的粒度调整到分区级?

关于这系列的问题思考与分析,我们将在后续的文章中讲述,敬请关注。

Kafka 万亿级消息实践之资源组流量掉零故障排查分析的更多相关文章

  1. Kafka万亿级消息实战

    一.Kafka应用 本文主要总结当Kafka集群流量达到 万亿级记录/天或者十万亿级记录/天  甚至更高后,我们需要具备哪些能力才能保障集群高可用.高可靠.高性能.高吞吐.安全的运行. 这里总结内容主 ...

  2. 腾讯自研万亿级消息中间件TubeMQ为什么要捐赠给Apache?

    导语 | 近日,云+社区技术沙龙“腾讯开源技术”圆满落幕.本次沙龙邀请了多位腾讯技术专家围绕腾讯开源与各位开发者进行探讨,深度揭秘了腾讯开源项目TencentOS tiny.TubeMQ.Kona J ...

  3. 杂文笔记《Redis在万亿级日访问量下的中断优化》

    杂文笔记<Redis在万亿级日访问量下的中断优化> Redis在万亿级日访问量下的中断优化 https://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA= ...

  4. 如何基于MindSpore实现万亿级参数模型算法?

    摘要:近来,增大模型规模成为了提升模型性能的主要手段.特别是NLP领域的自监督预训练语言模型,规模越来越大,从GPT3的1750亿参数,到Switch Transformer的16000亿参数,又是一 ...

  5. 万亿级KV存储架构与实践

    一.KV 存储发展历程 我们第一代的分布式 KV 存储如下图左侧的架构所示,相信很多公司都经历过这个阶段.在客户端内做一致性哈希,在后端部署很多的 Memcached 实例,这样就实现了最基本的 KV ...

  6. 腾讯万亿级分布式消息中间件TubeMQ正式开源

    TubeMQ是腾讯在2013年自研的分布式消息中间件系统,专注服务大数据场景下海量数据的高性能存储和传输,经过近7年上万亿的海量数据沉淀,目前日均接入量超过25万亿条.较之于众多明星的开源MQ组件,T ...

  7. 手机QQ公众号亿级消息实时群发架构

    编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由孙子荀分享.转载请注明来自高可用架构公众号 ArchNotes.   孙子荀,2009 年在华为从事内核和分布式系统的开发工作:2011 ...

  8. 万亿级日志与行为数据存储查询技术剖析(续)——Tindex是改造的lucene和druid

    五.Tindex 数果智能根据开源的方案自研了一套数据存储的解决方案,该方案的索引层通过改造Lucene实现,数据查询和索引写入框架通过扩展Druid实现.既保证了数据的实时性和指标自由定义的问题,又 ...

  9. 【HBase调优】Hbase万亿级存储性能优化总结

    背景:HBase主集群在生产环境已稳定运行有1年半时间,最大的单表region数已达7200多个,每天新增入库量就有百亿条,对HBase的认识经历了懵懂到熟的过程.为了应对业务数据的压力,HBase入 ...

随机推荐

  1. VueJs单页应用实现微信网页授权及微信分享功能

    在实际开发中,无论是做PC端.WebApp端还是微信公众号等类型的项目的时候,或多或少都会涉及到微信相关的开发,最近公司项目要求实现微信网页授权,并获取微信用户基本信息的功能及微信分享的功能,现在总算 ...

  2. HTML5 & CSS3 内容收集(1)

    1. HTML发展历史介绍 2. 浏览器支持 2.1 新增标签支持 在html5 中新增了很多的标签,其中包括8个新增语义结构标签.header, section, footer, aside, na ...

  3. java中方法重载是什么, 实际中到底有什么意义, 用处?请举例

    7.3 方法重载(overload)  当几个方法有相同的方法名,但参数个数不同或参数类型不同时,就涉及方法重载 方法重载有什么意义呢?在公司里编程,有时候一个方法名,要用到很多次,而且每次跟每次的参 ...

  4. for 循环打印直角三角形、正三角形、棱形

    学习目标: 熟练掌握 for 循环的使用 例题: 1.需求:打印直角三角形 代码如下: // 左直角 for(int i = 0; i < 5; i++) { for(int j = 0; j ...

  5. JavaScript实现带正则表达式的表单校验(校验成功后跳转)

    运行结果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...

  6. Java-GUI编程之事件处理

    事件处理 前面介绍了如何放置各种组件,从而得到了丰富多彩的图形界面,但这些界面还不能响应用户的任何操作.比如单击前面所有窗口右上角的"X"按钮,但窗口依然不会关闭.因为在 AWT ...

  7. C++---初识C++

    C和C++的关系 C语言是结构化和模块化的语言, 面向过程. C++是在C语言的基础上, 增加了面向对象的机制, 并对C语言的功能进行了扩充. 变量的定义可以出现在程序中的任何行 提供了标准输入输出流 ...

  8. Mybatis-sql语句的抽取

    1.抽取之前的UserMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  9. drf的JWT认证

    JWT认证(5星) token发展史 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token(本质就是tok ...

  10. typescript使用入门及react+ts实战

    ts介绍 TypeScript是一种由微软开发的自由和开源的编程语言.它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程. 与js关系 ts与js区 ...