kafka原理_Kafka动态配置实现原理解析
总 第19篇
2019年 第15篇
一、问题导读Apache Kafka在全球各个领域各大公司获得广泛使用,得益于它强大的功能和不断完善的生态。其中Kafka动态配置是一个比较高频好用的功能,下面我们就来一探究竟。
- 动态配置是如何设计的?
- 动态配置优先级是怎样的?
- Broker初始化是如何读取配置的?
- 动态配置支持哪些特性功能?
- 动态配置如何使用呢?
二、前言介绍
Kafka初始开源的几个版本,当broker初始化启动时,所有配置信息只能从server.properties静态文件读取,以后不再发生任何更改,随着Kafka逐步迭代,在线业务对稳定性和个性化要求越来越突出,需要能支持在线修改功能动态生效的需求应运而生。例如:按照topic维度清理数据,依据clientid限流,根据用户名称进行访问权限控制等等。目前Kafka最新版本支持以下几类动态配置。
三、发展历程
特性 |
版本 |
可配置字段 |
备注 |
---|---|---|---|
增加topic级别配置特性支持 | 0.8.1 |
以下属性列表,后续迭代不断丰富topic.log.file.sizetopic.log.retention.hourstopic.log.retention.size...... |
对log的修改 |
增加client级别配置特性支持 | 0.9.0.0 |
producer_byte_rateconsumer_byte_rate..... |
每秒生产/消费的byte数目大小 |
增加user级别配置特性支持 | 0.10.1.0 |
用户访问权限管理和资源控制 users + clients 组合粒度配置 |
|
增加broker级别配置特性支持 | 0.10.1.0 |
以下属性列表,后续迭代不断丰富leader.replication.throttled.ratefollower.replication.throttled.rate...... |
对broker有效 |
动态配置文件发展历程:
kafka在0.8.0对topic的管理功能分布在三个shell中,它们分别是kafka-list-topic.sh、kafka-create-topic.sh、kafka-delete-topic.sh、kafka-add-partitions.sh,后来社区考虑到topic管理功能过于分散,到了0.8.1版本有关topic所有功能收敛到kafka-topics.sh中。0.8.0中只有topic的创建、删除和列表及添加分区功能,到了0.8.1开始支持topics动态配置了。
0.9.0.0开始支持client(producer和consumer)客户端配额限流支持,确保不因为某个或少数几个topic的客户端占满了broker带宽资源和磁盘IO资源,影响其他客户端的正常读写,导致集群内主从同步也受到影响。这个功能对确保系统SLA大有好处,通过服务降级,保证写/生产不受影响,降低或暂停读/消费流量更容易解决系统资源瓶颈。
0.9.0版本动态配置与topic管理分离,为了保持向下兼容kafka-topics.sh依然包含操作topic动态配置功能,新增kafka-configs.sh支持clients和topics动态配置功能,所以kafka-topics.sh和kafka-configs.sh任意一个都可以修改topic动态配置
0.10.1.0版本新增支持users和brokers动态配置功能,user动态配置用于访问资源的权限控制,提升集群的访问和数据安全性,例如:用户对读/写/创建/删除等操作和API、topic、group资源访问控制。broker动态配置,在不用重启及影响服务运行情况下,broker级别功能实现动态生效,例如:副本注册复制速率、磁盘内挂载点间数据迁移速率、网络请求的线程数、处理请求的I/O线程数等等全局参数等等。
0.10.1.0~2.3.1版本都支持topics、clients、users、brokers四类型动态配置的11种粒度配置对象,只是配置模块和属性字段有增减与调整。
四、动态配置设计原理
用户使用kafka-configs.sh脚本,根据格式和参数规范要求,ConfigCommand类进行相关逻辑处理、json格式和内容校验,生成notification json,写入到序列化持久节点上,zk路径为
xxx/config/changes/config_change_seqNo,
节点名称为config_change_seqNo,其中seqNo从1开始的自增序号。kafka集群中所有broker通过监听zk上xxx/config/changes的children变化,每次获得比当前内存中last_seqNo大的seqNo的json内容,从中读取entity_type/entity_name相对路径,由此判断如何从xxx/config/topics|clients|users|brokers四种类型中读取哪个配置路径。同一个Broker在操作过程中任何时刻只能串行读写一种类型的配置,多种配置需要串行操作。
各个角色的作用:
kafka-config.sh: 负责写dynamic config和notification,写顺序上图有先后标识。broker:负责监听xxx/config/changes子节点变化和读取entity_type/entity_name路径节点上内容zk:负责存储notification和dynamic config及下发配置给相应的brokernotification json内容:V1 0.10.0.1及以前版本有效:
{ "version": 1, "entity_type": "topics", "entity_name": "finalTest"}
V2 0.10.1.0~2.3.1 当前最新版本都有效
{ "version": 2, "entity_path": "topics/finalTest"}
以上不管是version 1还是version2,本质上没有变化。都是通过entity_type/entity_name获得entity_path的zk相对路径,全路径为xxx/config/entityType/entityName,具体请看如下详图
entity_type=topics | clients | users | brokersentity_name=topicName | clientId | userId | (brokerId | )当entity_type为brokers时,brokerId为broker编号与自己的server.properties对应,只对某个broker生效。“”指对所有broker生效。而entity_type为topics | clients | users对所有broker都生效。通过以上entity_type/entity_name六种组合成六个zk相对路径。topics和clients组合原理一样,但users和brokers却略有不同,他们各自有2个组合,除了普通组合还有复合组合,两种类型组合在一起,例如users有users与clients组合,zk路径为users//clients/;brokers动态配置非常实用,不需要重启就能动态更改任意数量brokers配置,更改所有brokers为xxx/brokers/四类动态配置11种zk相对路径,根据11种zk相对路径可以读取11种粒度配置对象dynamic config。说明:某种类型下所有作用域生效,例如xxx/clients/和xxx/brokers/就是集群内所有All clients和集群内所有All brokers配置都会生效,其他同理。
dynamic config内容示例:
entity_type/entity_name=topics/=topics/finalTest
{ "version": 1, "config": { "retention.bytes": "102400000", "flush.ms": "5000", "cleanup.policy": "compact", "flush.messages", ... }}
entity_type/entity_name=clients/=clients/camusall
{ "version": 1, "config": { "producer_byte_rate": "20971520", "consumer_byte_rate": "20971520" }}
entity_type/entity_name=brokers/all brokers=brokers/
{ "version": 1, "config": { "leader.replication.throttled.rate": "5000", "follower.replication.throttled.rate": "60000", "replica.alter.log.dirs.io.max.bytes.per.second": "5000", "log.retention.hours": "24", "log.flush.interval.messages": "5000", "min.insync.replicas": "2", ... }}
entity_type/entity_name=brokers/brokerId 与all brokers的配置形成完全一样,只是作用域范围不同而已,此处省略。
写配置格式校验
如果写入配置不进行规范校验,broker就会读取处理过程中,就会卡住或阻塞,影响服务运行稳定性。所以配置校验至关重要,校验规则如下:
配置项格式必须合法,否则报错不予接收
输入配置项进行校验,输入参数必须是kafka包含的配置项,否则过滤掉
config_change_seqNo生成规则
kafka-configs.sh脚本每成功执行一次,在zk上就创建一个新的seqNode节点(即/xxx/config/changes/config_change_seqNo)seqNode是zk的持久顺序节点(PERSISTENT_SEQUENTIAL),它的组成是seqNode = seqNodePrefix + seqNodeSuffix,config_change_固定为seqNode的前缀,seqNodeSuffix = seqNo为seqNode的后缀,seqNo是10位数字的序列号,这个序列号后缀是自增的,由zk服务端自动生成和维护,每次事务请求成功就加1,它与MySQL的自增id原理一样。config_change_seqno清除原则
集群经过长期运行积累,xxx/config/changes下会留存大量历史节点,如果不及时清理,会有以下影响:
大量无用的seqNode进行传输,会增加网络带宽负担
占用zk服务端内存及存储资源
Kafka会做大量无效判断和计算
综上所述,因此必须要及时清除无用的seqNode集合,清除公式步骤如下:
当broker监听到notification变化回调时,记录系统时间。
获取xxx/config/changes下所有子节点,读取每个seqNode的创建时间
系统时间减去seqNode创建时间,如果时间差值大于过期时间,即changeExpirationMs,就会被删除
changeExpirationMs默认为15分钟,可由broker配置。
config_change_seqno判断处理
前面提到每当触发回调处理,seqNode节点创建时间过期15分钟会被删除,删除条件是触发才会被执行,如果长时间不创建就可能有少数几个seqNode一直保留。如果短时间内(15分钟内)创建大量seqNode,又不会立即被删除,只有等到下次触发达到条件才行,那怎么判断哪些会被处理呢?broker缓存中维护一个变量lastExecutedSeqNo,它负责保存执行历史中seqNode最大顺序号,所以每当触发回调获取seqNodeSet列表时,都能轻易判断出哪些需要处理计算,也会同步更新lastExecutedSeqNo。
notification作用
- 通知broker有新的动态配置产生,读取相应的动态配置
- 不用监听大量四种类型配置下子节点,每个broker只需要监听一个notification节点即可,高效且性能也高
- 大大减少broker监听数量,如果像controller监听/xxx/partitions/[0-N]/state一样,监听数量就是四种类型配置zk路径乘以broker数量了
静态与动态的配置及优先级
静态与动态区别。静态配置是Broker内置默认配置和静态配置文件server.properties,broker启动前可以任意修改,启动后不可修改。动态配置是broker启动运行后,可以在线更新生效,偷偷说一句离线也可以改,就是不生效而已。
配置优先级。以上4个图包含4类型配置既有动态也有静态,那优先级如何呢?动态配置优先级高于静态配置。如上图1、2、4,环越小优先级越高,对于动态配置来说修改配置作用域范围越小优先级越高,反之亦然。优先级最高的,会逐级覆盖相同配置参数。
当broker启动时。读取顺序依次为broker内置默认配置,broker静态配置文件,动态配置。当配置参数相同时,高优先级覆盖次优先的,其他依次类推
图示说明:上图1、2、3、4中,其中图1、2、4中环数字表示配置优先级关系,数字从1~5表示优先级从高到低。图3为两级关联。Users和Clients组合实现配置管理,这两者组合用于客户端配额限流,Users与Clients就像两级目录一样,一个User可以包含一个、多个clientId或所有clientId。图4中既有优先级关系也有配置参数包含关系,topics类型配置是brokers类型配置的子集,brokers除了包含topic配置外还有DynamicThreadPool、DynamicListenerConfig、DynamicConnectionQuota、LogCleaner配置。
五、如何使用动态配置
- 使用脚本kafka-configs.sh和kafka-topics.sh,kafka-configs.sh支持四种类型,kafka-topics.sh仅支持topics类型
- 使用Apache-kafka官方提供的java版本客户端API调用
- 直接写zk实现,具体遵循如上写notification和dynamic_config规范
如想更深入了解kafka-configs.sh用法,请查看脚本用法解析相关文章
六、总结
- Kafka配置参数分为静态配置和动态配置,静态分为内置默认与外置用户配置,用户配置优先于内置配置
- 动态配置为4类型11个zk相对路径,即11种粒度配置对象生效,同类型作用域范围越小优先级越高
- 动态配置优先级比静态配置优先级高,动态配置中Users与Clients可以组合配置
- 从设计原理中了解config_change_seqNo生成规则
- 写上文中理解了写Notification的作用,从而理解什么场景会适合使用zk中持久顺序节点(PERSISTENT_SEQUENTIAL)
七、参考资料
https://www.cnblogs.com/lizherui/p/12056893.html
扫码关注
kafka原理_Kafka动态配置实现原理解析相关推荐
- 【kafka】Kafka中的动态配置源码分析
1.概述 2.源码分析 Broker启动加载动态配置 KafkaServer.startup 启动加载动态配置总流程 2.1 动态配置初始化 config.dynamicConfig.initiali ...
- Nacos的动态配置源码解析
文章目录 1. 如何使用 2. 原理详解 2.1 采用延迟线程池定时执行"监听"文件是否有修改 2.2 通过长轮询的方式获得修改过的文件及其内容 2.3 拿到配置后通过applic ...
- 动态磅是怎么原理_动态地磅的原理及发展
动态地磅的原理及发展 发布时间:17/12/28 来源: 访问次数:4954 文章介绍了动态地磅的结构和工作原理,针对动态地磅的分类做了全面的概述,分别对不同的动态地磅做了对比 及详细的阐述,说明选择 ...
- python列表实现原理_Python动态类型实现原理及过程解析
在python中,我们使用变量时,并没有声明变量的存在和类型.类型是在运行过程中自动决定的. a = 3 python将会执行三步去完成上面这个请求. 1.创建一个对象代表3 2.创建一个变量a,如果 ...
- mysql主原理_mysql 主从配置实现原理
MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之间的复制延迟,但是 今天碰到了一个场景,发现 Seconds_Behind ...
- Kafka启用SASL_PLAINTEXT动态配置JAAS文件的几种方式
Kafka是广泛使用消息服务,很多情况下关于认证部分我都是默认的配置,也就是不需要用户名/密码,也不配置证书.在内网或者在项目组内部可以,但是设计的跨部门时一般处于安全考虑都需要加上认证,防止kafk ...
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建
为什么80%的码农都做不了架构师?>>> kafka入门:简介.使用场景.设计原理.主要配置及集群搭建(转) 问题导读: 1.zookeeper在kafka的作用是什么? 2. ...
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建--转载
问题导读: 1.zookeeper在kafka的作用是什么? 2.kafka中几乎不允许对消息进行"随机读写"的原因是什么? 3.kafka集群consumer和producer状 ...
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
问题导读: 1.zookeeper在kafka的作用是什么? 2.kafka中几乎不允许对消息进行"随机读写"的原因是什么? 3.kafka集群consumer和producer状 ...
最新文章
- FlycoTabLayout使用
- Python Django jsonpickle序列化隐藏部分字段代码示例
- srwebsocket 服务器过段时间会关闭_Minecraft 开启服务器后必须做的一些事情
- 《c语言从入门到精通》看书笔记——第3章 数据类型
- 有关 php __autoload 自动加载类函数的用法
- String Start!
- ios服务器需要开启ipv6的支持,针对iOS审核要求为应用兼容IPv6
- 一次关于使用status作为变量引发的bug及思考
- PB通过VDN实现Http上传、下载
- 基于ASP.NET的企业进销存管理系统
- FreebuF黑客专访系列之吴翰清(刺):接下来几年,有两样东西必定会火
- 回归中的相关度和R平方值——学习笔记
- 内网渗透之域内信息收集
- 抖音上线“冬季山货节”,不声不响把拼多多老家“偷了”?
- matlab外推法确定搜索区间的程序,《机械优化设计》复习题
- 字符串转utf8编码
- 2021年第十二届蓝桥杯省赛+国三C/C++B组参赛经历分享
- Gym 100712G Heavy Coins
- JWT授权为啥要在 Authorization标头里加个Bearer 呢
- 半自动微信消息定时发送
热门文章
- 京东物流基于Doris的亿级数据自助探索应用
- 某程序员吐槽:潮汕女朋友狮子大开口要18万8彩礼,而且只能男友父母出,不能男友出!...
- 一口气带你踩完五个 List 的大坑,真的是处处坑啊!
- 害怕离职,侧面说明大多数是离职了没人要的废物?
- 熬夜精心整理的一线大厂大数据、人工智能全套教程下载(含视频+源码)!!...
- 玩转飞书日历,体验高效办公!
- 站长新手入门:从0开始搭建微信小程序商城,不会代码也能开商城(附带源码)
- 种子之父--布莱恩-科恩
- TF (transform) in ROS
- t6文件服务器怎么设置,t6 修改文件服务器地址