正文前先来一波福利推荐:
福利一:
百万年薪架构师视频,该视频可以学到很多东西,是本人花钱买的VIP课程,学习消化了一年,为了支持一下女朋友公众号也方便大家学习,共享给大家。
福利二:
毕业答辩以及工作上各种答辩,平时积累了不少精品PPT,现在共享给大家,大大小小加起来有几千套,总有适合你的一款,很多是网上是下载不到。
获取方式:
微信关注 精品3分钟 ,id为 jingpin3mins,关注后回复 百万年薪架构师 ,精品收藏PPT 获取云盘链接,谢谢大家支持!
------------------------正文开始---------------------------
kafka升级方案
为什么进行kafka升级
一、修改unclean.leader.election.enabled默认值
Kafka社区终于下定决心要把这个参数的默认值改成false,即不再允许出现unclean leader选举的情况,在正确性和高可用性之间选择了前者。如果依然要启用它,用户需要显式地在server.properties中设置这个参数=true
二、确保offsets.topic.replication.factor参数被正确应用
__consumer_offsets这个topic是Kafka自动创建的,在创建的时候如果集群broker数<offsets.topic.replication.factor,原先的版本取其小者,但这会违背用户设置该参数的初衷。因此在0.11版本中这个参数会被强制遵守,如果不满足该参数设定的值,会抛出GROUP_COORDINATOR_NOT_AVAILABLE。
三、优化了对Snappy压缩的支持
之前由于源代码中硬编码了block size,使得producer使用Snappy时的表现比LZ4相差很多,但其实Snappy和LZ4两者之差距不应该很大。故此0.11版本中对Snappy的默认block size做了调整。不过这一点需要详尽的性能测试报告来证明此改动是有效的。
四、消息增加头部信息(Header)
Record增加了Header,每个header是一个KV存储。具体的header设计参见KIP-82
五、空消费者组延时rebalance
为了缩短多consumer首次rebalance的时间,增加了“group.initial.rebalance.delay.ms”用于设置group开启rebalance的延时时间。这段延时期间允许更多的consumer加入组,避免不必要的JoinGroup与SyncGroup之间的切换。当然凡事都是trade-off,引入这个必然带来消费延时。
六、消息格式变更
增加最新的magic值:2,还增加了header信息。同时为了支持幂等producer和EOS,增加一些与事务相关的字段,使得单个record数据结构体积增加。但因为优化了RecordBatch使得整个batch所占体积反而减少,进一步降低了网络IO开销。
七、新的分配算法:StickyAssignor
比range和round-robin更加平衡的分配算法。指定partition.assignment.strategy = org.apache.kafka.clients.consumer.StickyAssignor可以尝尝鲜。不过根据我的经验,分配不均匀的情况通常发生在每个consumer订阅topic差别很大的时候。比如consumer1订阅topic1, topic2, topic4, consumer2订阅topic3, topic4这种情况
八、controller重设计
Controller原来的设计非常复杂,使得社区里面的人几乎不敢改动controller代码。老版本controller的主要问题在我看来有2个:1. controller需要执行1,2,3,4,5,6步操作,倘若第3步出错了,无法回滚前两步的操作;2. 多线程访问,多个线程同时访问Controller上下文信息。0.11版本部分重构了controller,采用了单线程+基于事件队列的方式。具体效果咱们拭目以待吧~~
九、支持EOS
0.11最重要的功能,没有之一!EOS是流式处理实现正确性的基石。主流的流式处理框架基本都支持EOS(如Storm Trident, Spark Streaming, Flink),Kafka streams肯定也要支持的。0.11版本通过3个大的改动支持EOS:1.幂等的producer(这也是千呼万唤始出来的功能);2. 支持事务;3. 支持EOS的流式处理(保证读-处理-写全链路的EOS)
方案一:
接受停机升级,关闭0.9.0.1版本的kafka,然后按照正常步骤启动kafka0.11.0.3
版本,然后升级后台所有涉及kafka的模块;
优点:过程简单,无突发异常,只有正常启动新版本即可使用;
不足:关闭老版本,启动新版本的过程中,存在部分线上数据丢失的情况,此种情况推荐在凌晨数据量少的时候使用;
方案二:
使用滚动升级方案,方案步骤如下:
![升级步骤.png](https://upload-images.jianshu.io/upload_images/5304063-a800216b840bcce8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
注意:由于引入了新的协议,要在升级客户端之前先升级kafka集群(即,0.10.1.x仅支持 0.10.1.x或更高版本的broker,但是0.10.1.x的broker向下支持旧版本的客户端)
第一步:
先把新版安装包拷贝到对应机器上,并解压。
第二步:
更新所有broker(新版本)上的配置文件config/server.properties
inter.broker.protocol.version=0.9.0.1 (旧版本号)
log.message.format.version=0.9.0.1 (现正在使用client端版本号)
其他配置保持不变,特别是数据存储目录,没改变,注意对应修改broker id号、ip、zookeeper
第三步:
先停一台旧版本broker,更改环境变量指向新版,启动新版broker
第四步:
循环执行第三步,直到集群中所有有borker都更新到新版。
注意:替换新版broker后,注意查看新版broker是否已经注册到zookeeper,所在机器上的的副本是否已经可用。确定可用之后再更新下一台broker。
第五步:
确定上诉步骤已经执行完毕,并且集群一切正常后,修改所有新版配置文件server.properties
inter.broker.protocol.version=0.11.0.3 (新版本号)
log.message.format.version=0.9.0.1 (现正在使用client端版本号)
注意:log.message.format.version这里要等client端的版本升级后再做修改。如果之前的消息格式是0.10.0,则将log.message.format.version更改为0.10.1(这无影响,因为0.10.0和0.10.1的消息格式是相同的)。 如果之前的消息格式版本低于.10.0,还不能更改log.message.format.version - 一旦所有的消费者都已升级到 0.10.0.0 或更高版本时,才能更改此参数。
第六步:
逐个重启borker。
如果log.message.format.version低于0.10.0,请等待,知道所有消费者升级到0.10.0或更新的版本,然后将每个broker的log.message.format.version更改为0.10.1。然后逐个重启。
注意:变换协议版本和重启启动可以在broker升级完成后的任何时间去做,不必马上做。
方案二过程示例:
启动0.9.0.1版本
![guxiaoyong1.png](https://upload-images.jianshu.io/upload_images/5304063-5c42f737f59dd7a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![guxiaoyong2.png](https://upload-images.jianshu.io/upload_images/5304063-88e41ab410cf837d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![guxiaoyong3.png](https://upload-images.jianshu.io/upload_images/5304063-fb8119d0d6526f8b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
创建topc,生产者,消费者,观察收发情况:
在guxiaoyong3创建topic
![topic.png](https://upload-images.jianshu.io/upload_images/5304063-7365d80339f708e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在 guxiaoyong3创建生产者
![生产者.png](https://upload-images.jianshu.io/upload_images/5304063-513691e0378cb9f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![发送消息.png](https://upload-images.jianshu.io/upload_images/5304063-4f29330dfee57571.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
guxiaoyong1和guxiaoyong2上进行消费;
![消费 topic.png](https://upload-images.jianshu.io/upload_images/5304063-a39b20e33b95f446.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![消费topic.png](https://upload-images.jianshu.io/upload_images/5304063-31b4246854c6abe1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以看到收发正常,现在进行guxiaoyong1上进行版本升级,修改service.conf协议版本:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-6f77fc4431bd925a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
关闭之前的旧版本kafka,启动新的kafka:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-96b9d73870e0a0e6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-4873a08547c6708d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
测试其他的两个kafka是收发正常的:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-fe9cff6d859021a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-c438a4168293a46b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
升级guxiaoyong2的kafka:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-361386092530998a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-85c858acad6e3fa3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
测试guxiaoyong1 guxiaoyong2是否收发正常
![image.png](https://upload-images.jianshu.io/upload_images/5304063-9c27409c33f1a0ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-1de6f3ebe0237c00.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-3a6e2a7f152ad34e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
更新guxiaoyong3,检测收发是否正常:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-97d2fe4630b2777b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-bd472a12c11a4e4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-e33d07c7425c7cb1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以看到全部收到正常;
接下来更改所有配置文件中的inter.broker.protocol.version=0.11.0.3,依次重启kafka,完成升级;
![image.png](https://upload-images.jianshu.io/upload_images/5304063-0614a931b93ea7b6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-0478e8ebb00992a6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/5304063-e2554fea5576fe4e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以看到所有的消息收到正常;
接下来,把项目项目代码中的消费者更新到0.11.0.3,进行项目灰度发布,然后重新修改kafka配置文件中log.message.format.version=0.9.0.1,进行依次重启。完成最终升级。
项目代码修改
修改客户端的版本:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-b97c2700ff761afa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
注意spring与kafka版本的关联关系:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-3f03b4eb3c613184.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
修改代码中部分配置:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-00074ba070264065.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
验证是否开启了压缩功能:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-9bf173def64f8d1c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
还可以使用DumpLogSegments工具,并替换您的目录位置/日志文件名称;
使用
./kafka-run-class.sh kafka.tools.DumpLogSegments -files ../../kafkalogs/risk_api_msg_test-2/00000000000000000000.log -print-data-log
查看topic下的数据属性:
![image.png](https://upload-images.jianshu.io/upload_images/5304063-abb0965cf47eb704.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)