前腾讯T3架构师分享:记一次 Kafka 集群线上扩容

AI驱动的云原生落地实践:多云、边缘与Serverless工程指南 云原生已从概念走向生产核心,其本质是围绕业务连续性重构基础设施能力。理解容器编排、服务网格、声明式API等基础原理,是构建高可用、可观测、低成本系统的前提;而AI正深度融入弹性伸缩、根因分析、安全策略生成等底层环节,成为云的新操作系统;多云不再是架构选择而是治理刚需,需在流量调度、数据同步与成本治理三层建立协同机制;边缘计算则重新定义了实时性边界,推动‘云边端’时空分离处理范式落地;本文聚焦真实项目中的Serverless ETL、混合云灾备、AI服务化、可观测性栈等可复用方案,直击企业上云过程中的性能、安 阅读详情

本文转载自:前腾讯T3架构师分享:记一次 Kafka 集群线上扩容


前段时间收到某个 Kafka 集群的生产客户端反馈发送消息耗时很高,于是花了一段时间去排查这个问题,最后该集群进行扩容,由于某些主题的当前数据量实在太大,在对这些主题迁移过程中花费了很长一段时间,不过这个过程还算顺利,因为在迁移过程中也做足了各方面的调研,包括分区重平衡过程中对客户端的影响,以及对整个集群的性能影响等,特此将这个过程总结一下,也为双十一打了一剂强心剂。

一、排查问题与分析

接到用户的反馈后,我用脚本测试了一遍,并对比了另外一个正常的 Kafka 集群,发现耗时确实很高,接下来

经过排查,发现有客户端在频繁断开与集群节点的连接,发现日志频繁打印如下内容:

Attempting to send response via channel for which there is no open connection, connection id xxx(kafka.network.Processor)

定位到源码位置:

kafka.network.Processor#sendResponse:

看源码注释,是远程连接关闭了或者空闲时间太长了的意思,找到具体客户端负责人,经询问后,这是大数据 Spark 集群的节点。

从以上日志看出,Spark 集群的某个消费组 OrderDeliveryTypeCnt,竟然发生了近 4 万次重平衡操作,这显然就是一个不正常的事件,Kafka 消费组发生重平衡的条件有以下几个:

  1. 消费组成员发生变更,有新消费者加入或者离开,或者有消费者崩溃;
  2. 消费组订阅的主题数量发生变更;
  3. 消费组订阅的分区数发生变更。

很显然第 2、3 点都没有发生,那么可以断定,这是 Spark集群节点频繁断开与kafka的连接导致消费组成员发生变更,导致消费组发生重平滑。

那为什么 Spark 集群会产生频繁断开重连呢?

查看 Spark 集群用的 Kafka 版本还是 0.10.1.1 版本,而 Kafka 集群的版本为 2.2.1,一开始以为是版本兼容问题,接着数据智能部的小伙伴将 Spark 集群连接到某个版本为 0.11.1.1 的 Kafka 集群,使用 8 个 Spark 任务消费进行消费,同样发现了连接断开的问题。说明此问题是由于 Spark 内部消费 Kafka 机制导致的,和 kafka 版本关系不大。

经过几番跟大数据的人员讨论,这个频繁重平衡貌似是 Spark 2.3 版本内部机制导致的,Spark 2.4 版本没有这个问题存在。

由于这个频繁断开重连,并不是开发人员开发过程中导致的,考虑到双十一临近,不能贸然升级改动项目,那么现在最好的方案就是对集群进行水平扩展,增加集群的负载能力,并对专门的主题进行分区重分配。

二、分区重分配方案的分析

目前集群一共有 6 个节点,扩容以 50% 为基准,那么需要在准备 3 个节点,在运维准备好机器并且将其加入到集群中后,接下来就要准备对主题进行分区重分配的策略文件了。

在执行分区重分配的过程中,对集群的影响主要有两点:

  1. 分区重分配主要是对主题数据进行 Broker 间的迁移,因此会占用集群的带宽资源;
  2. 分区重分配会改变分区 Leader 所在的 Broker,因此会影响客户端。

针对以上两点,第 1 点可以在晚间进行(太苦逼了,记得有个主题数据迁移进行了将近5小时),针对第二点,我想到了两个方案:

  1. 整个分配方案分成两个步骤:1)手动生成分配方案,对原有的分区 Leader 位置不改变,只对副本进行分区重分配;2)等待数据迁移完成后,再手动更改分区分配方案,目的是均衡 Leader。
  2. 直接用 Kafka 提供的 API 生成 分区重分配方案,直接执行分区重分配。

第一个方案理论上是对客户端影响最小的,把整个分配方案分成了两个步骤,也就是将对集群的带宽资源与客户端的影响分开了,对过程可控性更高了,但问题来了,集群中的某些主题,有 64 个分区,副本因子为 3,副本一共有 192 个,你需要保持原有分区 Leader 位置不变的情况下,去手动均衡其余副本,这个考验难度真的太大了,稍微有一点偏差,就会造成副本不均衡。

因此我特意去看了分区重分配的源码,并对其过程进行了进一步分析,发现分配重分配的步骤是将分区原有的副本与新分配的副本的集合,组成一个分区副本集合,新分配的副本努力追上 Leader 的位移,最终加入 ISR,待全部副本都加入 ISR 之后,就会进行分区 Leader 选举,选举完后就会将原有的副本删除,具体细节我会单独写一篇文章。

根据以上重分配的步骤,意味着在数据进行过程中不会发生客户端阻塞,因为期间 Leader 并没有发生变更,在数据迁移完成进行 Leader 选举时才会,但影响不大,针对这点影响我特意用脚本测试了一下:

可以发现,在发送过程中,如果 Leader 发生了变更,生产者会及时拉取最新的元数据,并重新进行消息发送。

针对以上的分析与测试,我们决定采取第二种方案,具体步骤如下:

  1. 对每个主题生成分配分区分配策略:执行时间段(10:00-17:00),并对分配策略进行检查,并保存执行的 topic1_partition_reassignment.json 文件,并把原来的方案保存到topic1_partition_reassignment_rollback.json文件中,以备后续的 rollback 操作;
  2. 执行分配策略:执行时间段(00:30-02:30),准备好的 topic1_partition_reassignment.json文件,执行完再验证并查看副本分配情况,每执行一个分配策略都要查看 ISR 收缩扩张状况、消息流转状况,确定没问题后再执行下一个分配策略;3.由于集群 broker 端的参数 auto.leader.rebalance.enable=true,因此会自动执行 Preferred Leader 选举,默认时间间隔为 300 秒,期间需要观察 Preferred Leader 选举状况。

三、分区重分配

对于新增的 Broker,Kafka 是不会自动地分配已有主题的负载,即不会将主题的分区分配到新增的 Broker,但我们可以通过 Kafka 提供的 API 对主题分区进行重分配操作,具体操作如下:

1.生成需要执行分区重分配的主题列表 json 文件:

echo '{"version":1,"topics":[{"topic":"sjzn_spark_binlog_order_topic"}]}' > sjzn_spark_binlog_order_topic.json

2.生成主题的分配方案:

bin/kafka-reassign-partitions.sh  --zookeeper  --zookeeper xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181 --topics-to-move-json-file sjzn_spark_binlog_order_topic.json --broker-list "0,1,2,3,4,5,6,7,8" --generate

由于主题的有64个分区,每个分区3个副本,生成的分配数据还是挺大的,这里就不一一贴出来了

3.将分配方案保存到一个 json 文件中:

echo '{"version":1,"partitions":[{"topic":"sjzn_spark_binlog_order_topic","partition":59,"replicas":[4,8,0],"log_dirs":["any","any","any"]} ......' > sjzn_spark_binlog_order_topic_reassignment.json

4.执行分区重分配:

 bin/kafka-reassign-partitions.sh   --zookeeper xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181 --reassignment-json-file sjzn_spark_binlog_order_topic_reassignment.json --execute

5.验证分区重分配是否执行成功:

bin/kafka-reassign-partitions.sh  --zookeeper xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181,xxx.xxx.xx.xxx:2181 --reassignment-json-file sjzn_spark_order_unique_topic_resign.json --verify

由于该主题存在的数据量特别大,整个重分配过程需要维持了好几个小时:

在它进行数据迁移过程中,我特意去 kafka-manage 控制台观察了各分区数据的变动情况:

从控制台可看出,各分区的副本数目基本都增加了,这也印证了分区当前的副本数等于原有的副本加上新分配的副本的集合,新分配的副本集合目前还没追上 Leader 的位移,因此没有加入 ISR 列表。

有没有注意到一点,此时各分区的 Leader 都不在 Preferred Leader 中,因此后续等待新分配的副本追上 ISR 后,会进行新一轮的 Preferred Leader 选举,选举的细节实现我会单独写一篇文章去分析,敬请期待。

过一段时间后,发现位移已经改变了:

从这点也印证了在分区重分配过程中,只要 Leader 没有发生变更,客户端是可以持续发送消息给分区 Leader 的。

从上图可看出,新分配的副本追上 Leader 的位移后,就会加入 ISR 列表中。

现在去看看集群带宽负载情况:

从上图中可看出,在迁移过程中,新分配的副本不断地从 Leader 拉取数据,占用了集群带宽。

主题各分区重分配完成后的副本情况:

从以上图中可看出,各分区的新分配的副本都已经全部在 ISR 列表中了,并且将旧分配的副本删除,经过 Preferred Leader 选举之后,各分区新分配副本的 Preferred Leader 大多数成为了该分区 leader。


本文转载自:前腾讯T3架构师分享:记一次 Kafka 集群线上扩容

【kafka】WARN Attempting to send response via channel for which there is no open connection 我们原来6台服务器,扩容了3台服务器,在做topic的迁移中出现的这个问题。 阅读详情

相关推荐

H3C-V7防火墙配置SSL VPN IP资源典型案例(华三)

H3C-V7防火墙配置SSL VPN IP资源典型案例(华三)

m0_68265458的博客 5163

记一次 Kafka 集群线上扩容

前段时间收到某个 Kafka 集群的生产客户端反馈发送消息耗时很高,于是花了一段时间去排查这个问题,最后该集群进行扩容,由于某些主题的当前数据量实在太大,在对这些主题迁移...

后端进阶 5824

Python库CloudScraper详细使用(绕过 Cloudflare 的反机器人页面的 Python 模块)

CloudScraper是一个专门用于绕过Cloudflare反机器人保护的Python库,它基于requests库构建,能够处理Cloudflare的5秒盾、WAF和人机验证等防护机制。

数据知道的博客 1万+

Kafka服务不可用(宕机)问题踩坑记

背景 某线上日志收集服务报警,打开域名报502错误码。 收集服务由2台netty HA服务器组成,netty服务器将客户端投递来的protobuf日志解析并发送到kafka,打开其中一个应用的日志,发现如下报错: org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) 在排除了netty服务的错...

7400

Bert+CNN文本分类(含代码实现)

一、什么是CNN? CNN的特点: (1)特定特征位移不变性 (2)特征缩放不变性 2. CNN模型构造过程 2.1 Convolution(卷积) (1)获取关键特征(减少参数) (2)共享权重(再次减少参数) 2.2 Max Pooling(池化) 2.3 Flatten 向量转换为如图所示可以进入全连接层的向量模式 3. TextCNN 上图可理解为: 通过不同的size(如上图2、3、4等),上图红色代表 size=2,黄色...

Python,数据分析,机器学习,深度学习 1万+

数据科学助力大数据领域的航空安全分析

随着航空业的快速发展,航班数量不断增加,航空安全问题日益受到关注。大数据时代的到来,使得航空领域积累了大量的数据,包括飞行数据、维护数据、气象数据等。本文章的目的在于探讨如何运用数据科学的方法和技术,对这些大数据进行分析,以提高航空安全水平。范围涵盖了从数据收集、预处理到数据分析、模型构建和应用的整个流程。本文将按照以下结构进行组织:首先介绍数据科学和航空安全分析的核心概念以及它们之间的联系;接着阐述核心算法原理和具体操作步骤,并使用Python源代码进行详细说明;

软件工程实践的博客 1292

kafka问题的一次不负责任排查

2022的第一篇文章,分享总结下一个kafka问题的排查过程。【问题现象】元旦前,某测试环境因为网络不稳定,出现了kafka与zookeeper连接断开后,没有重连。【问题定位】初步查看了...

hncscwc的博客 3079

【WorkBuddy专栏40】从「帮你干活」到「帮你创造」——WorkBuddy设计创意功能深度拆解

【WorkBuddy专栏40】从「帮你干活」到「帮你创造」——WorkBuddy设计创意功能深度拆解

AI人人懂 1294

阿里P7架构师的面试自述,短短一个春招面了字节,美团,腾讯阿里等大厂,这或许就是大佬的自我修养

微盟 一面: 项目 怎么优化数据库 索引的结构是什么 aop怎么用的 aop的底层怎么实现 反转字符串 社招第一场面试,还是比较紧张的,项目那块说的不太好。算法题感觉就是走个过场。。 多益 一面: 大部分是围绕项目来问的,感觉是技术面里面最水的。。而且一面通过之后还需要网申和IQ测评,特别麻烦。 字节 抖音电商 一面: 后序和中序,确定一棵树 口述算法:n的平方根 2T的文件 加载2G 出现次数top10 线程和进程的区别 进程怎么实现一个阻塞队列 进程间通信方式 反射是什么 类加载机制 ThreadLoc

欢迎您访问我的公众号【前程有光】 395

海康威视嵌入式最全面试题及参考答案(3万字长文)

主营业务:提供包括前端摄像头、后端存储设备、显示控制设备等在内的全方位视频监控解决方案。市场地位:在全球范围内享有较高的市场份额,在安防领域具有较强的竞争力。技术创新:持续投入研发,拥有多项核心技术和专利,特别是在视频处理算法、人工智能等方面取得了显著成果。社会责任:积极参与公共安全项目,为智慧城市、交通管理等领域提供技术支持和服务。国际业务:除了国内市场外,海康威视的产品和服务也销往全球多个国家和地区。面向对象编程。

大模型大数据攻城狮的专栏 1764

AUTOSAR知识点 之 XCP (三):XCP功能描述

记录一下XCP使用时候的功能包含命令时序、错误码表、事件描述以及对规范的记录。XCP的图示如下从上图就可以看出数据流的流向CAN-CANIF-XCP,发送反之。XCP的状态机如下。

梦想技术家 3075

腾讯AI新底座磐石:面向生产的模型可编排与治理实践

大模型工程化正从‘能跑’迈向‘稳用’,核心挑战在于模型生命周期管理、推理可靠性保障与数据可信溯源。AI原生基础设施(AI-Native Infrastructure)通过模型编排、推理治理和数据契约三大控制平面,实现对模型版本灰度、链路熔断、血缘追踪等关键能力的标准化封装。它不依赖堆砌参数或算力,而是以声明式CRD、硬编码SLA规则和轻量日志染色等工程手段,解决GPU显存碎片、语义漂移、输入类型错位等高频生产问题。适用于企业级AI平台建设者、MLOps工程师及算法团队技术负责人,尤其关注模型上线周期压缩、M

weixin_34080951的博客 339

微信小程序 - 最新图片组拖拽排序更换位置功能,类似微信朋友圈九宫格图片的拖动排序效果,微信小程序实现九宫格图片拖拽调换位置,小程序详细实现图像拖曳拖动切换位置排序功能(详细示例代码,一键复制开箱即用

微信小程序,wechat,小程序,图片排序,图像排序,九宫格拖拽排序,拖曳,拖动,拖拽,仿微信朋友圈,朋友圈宫格图片排序,微信朋友圈图片拖动排序效果,实现九宫格图片拖拽,图像拖拽排序组件插件,小程序实现拖拽图片切换图片位置,图片拖动互换位置,图像拖拽切换位置,九宫格图片组合拖动排序,交换九宫格图片的位置,小程序上传图片后,如何实现拖拽排序功能,小程序怎么实现图片拖拽排序,微信小程序图片上传,九宫格拖拽组件,选择图片并拖动_微信小程序图片拖拽,微信小程序长按拖拽排序,图像的拖拽移动,多图拖拽排序功能,实现九宫

✅ 精选推荐文章 4453

Kafka服务端源码剖析七 -- 服务端发送响应

上节我们看到响应被写到了ResponseQueue队列中,接下来我们来看看服务端发送响应的准备工作。再次回到Processor的run方法,Processor线程是一个非常重要的线程,可以说所有的事就靠这个线程来完成的。 override def run() { startupComplete() while (isRunning) { try { // setup any new connections that have been queued up

何星平的博客 487

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Kafka请求处理模块(四):SocketServer的 Process 线程

如果说 Acceptor 是做入站连接处理的,那么,Processor 代码则是真正创建连接以及分发请求的地方。 Processor 的重要对象有: private[kafka] class Processor(val id: Int, time: Time, maxRequestSize: Int, requestC

lianggx3的博客 1296

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

kafka重启报错 ERROR Processor got uncaught exception. (kafka.network.Processor)

[2021-11-19 16:00:07,685] ERROR Processor got uncaught exception. (kafka.network.Processor) java.lang.NoClassDefFoundError: Could not initialize class kafka.network.RequestChannel$ at kafka.network.RequestChannelRequest.<init>(RequestChannel.scala:12

weixin_43697701的博客 2845

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

kafka发送消息出现的问题KafKa error java.nio.channels.UnresolvedAddressException

出现以下的错 124  [main] INFO  kafka.utils.VerifiableProperties - Verifying properties 157  [main] INFO  kafka.utils.VerifiableProperties - Property compression.codec is overridden to 1 157  [main] I

zhongbaolin的专栏 1万+

kafka 服务端-网络-processor如何接收和处理请求

Processor.run() override def run() { startupComplete() while (isRunning) { try { // setup any new connections that have been queued up //读取每个SocketChannel,把每个SocketChannel //都往Selector上面注册OP_READ事件。 configure

m0_46449152的博客 584

e盾服务端源码_深入理解Kafka服务端之Processor线程是如何工作的

一、场景分析 在服务端启动的时候,创建并启动了Acceptor线程和Processor线程,每个Acceptor默认管理3个Processor线程对象。在上一篇,分析了Acceptor线程的主要工作:接收客户端连接请求,创建对应的SocketChannel并轮询交给Processor线程处理。那么Processor线程如何处理这些SocketChannel?它的工作流程又是什么?这...

weixin_39644139的博客 415

kafka源码分析一

package kafka import java.util.Properties import joptsimple.OptionParser import kafka.server.{KafkaServer, KafkaServerStartable} import kafka.utils.{CommandLineUtils, Logging} import org.apache.kafk

yjh314的专栏 2768

kafka消息阻塞

1,processor组件 2,Proactor模式   hi all:         大家都很关心kafka消息阻塞的情况(感谢RoctetMQ给我们的教训)。Kafka上线也有一段时间了,确实有出现过消息阻塞的情况,虽然不影响业务而且用临时办法解决了,但是我觉得可以跟大家总结一下。为了不引起大家的恐慌,我决定先把结论写出来:comsumer 非正常的rebalancing(重新分配分...

lusic01的专栏 1万+

response获取响应内容_Kafka源码深度剖析系列(三十七)——服务端发送响应的准备工作...

- 本次目标 -上次课我们看到响应被写到了ResponseQueue队列中,接下来我们来看看服务端发送响应的准备工作。- 源码剖析 -我们再次回到Processor的run方法,Processor线程是一个非常重要的线程,可以说所有的事就靠这个线程来完成的。override def run() { startupComplete() while...

weixin_39589693的博客 341

expect 使用说明

EXPECT(1) General Commands Manual EXPECT(1) NAME expect - programmed dialogue with interactive programs, Versi...

yibaifei的专栏 1845

HRESULT错误码

Return value/code Description 0x00030200 STG_S_CONVERTED The underlying file was converted to compound file format. 0x00030201 STG_S_B...

如鹿渴慕泉水的专栏 1万+

Kafka源码解析之Producer发送数据流程(三)

1. Kakfa生产者examples public class Producer extends Thread { private final KafkaProducer<Integer, String> producer; private final String topic; private final Boolean isAsync; /** * 构造方法,初始化生产者对象 * @param topic * @param i

百看不如一RUN 2265
上一篇: 阿里P7架构师的独家分享——SpringCloud 微服务实战笔记
下一篇: 阿里巴巴最新JVM面试解析——运行结构(附测试题)
Java_supermanNO1
博客等级 码龄7年 1170粉丝 329原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值