kafka 设计概要
吞吐量/延时
消息持久化
负载均衡和故障转移
伸缩性
一些常用命令
通过GetOffsetShell 工具类查看 topic 分区消息
./kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.2.52:9092 --topic test
查看当前topic 当前对应的信息
./kafka-topics.sh --zookeeper 192.168.2.52:2181 --describe --topic test1
Topic: test1 Partition: 0 Leader: 0 Replicas: 0 Isr: 0
Topic: test1 Partition: 1 Leader: 0 Replicas: 0 Isr: 0
修改kafka分区个数
./kafka-topics.sh -alter --zookeeper 192.168.2.52:2181 --partitions 2 --topic test
给现有topic 添加新的配置 添加压实配置
./kafka-configs.sh --zookeeper 192.168.2.52:2181 --alter --entity-type topics --entity-name test --add-config cleanup.policy=compact
查看当前topic 的配置
./kafka-configs.sh --zookeeper 192.168.2.52:2181 --describe --entity-type topics --entity-name test
对topic 进行生产者消息测试
./kafka-producer-perf-test.sh --topic topic1 --throughput -1 --num-records 50000 --record-size 100 --producer-props bootstrap.servers=192.168.2.52:9092 acks=1
查看当前存在的消费者组
./kafka-consumer-groups.sh --bootstrap-server 192.168.2.52:9092 --list
查看当前消费者组的信息
./kafka-consumer-groups.sh --bootstrap-server 192.168.2.52:9092 --describe --group topic1group
重置当前消费者组的offset
./kafka-consumer-groups.sh --bootstrap-server 192.168.2.52:9092 --group topic1group --reset-off sets --all-topics --to-earliest --execute
kafka rebalance 触发条件
消费者新增或者 移除
topic 分区的新增或减少
Kafka多线程消费两种方式
1 每个线程维护一个kafkaConsumer
2 单个kafkaConsumer 实例 一个线程对应一个分区
两种方式的优缺点
方法1 (每个线程维护专属 Ka fkaConsumer )
实现简单;速度较快,因为无线程 间交互开销:方便位移管理;易于 维护分区间的消息消费顺序
Socket连接开销大;consumer数受限于topic分区 数,扩展性差;broker端处理负载高(因为发往 broker的请求数多);rebalance可能性增大
方法2 (全局consumer多 worker 线程)
消息获取与处理解耦:可独立扩展 consumer数和woricer数,伸缩性 好
实现负载:难于维护分区内的消息顺序;处理链路 变长,导致位移管理困难;worker线程异常可能导 致消费数据丢失
写入消息的时候, 什么情况下 导致HW 会和LEO 不同步呢
follwer请求速度追不上,leader的接受消息的速度, 可能原因 follwer 副本所在的broker 的网络I/O开销过大导致备份消息的速度满于 leader处获取的消息速度
进程卡住: follwer在一段时间内无法向leader 请求数据, 比如之前提到的频繁gc 或者程序bug
LEO log end offset 日志末端唯一, 代表kafka 当前分区存了多少条数据, 12代表存在11条数据
HW 高水印 代表 这个kafka consumer 可见的 ,当前能够读取的 最大offset , 8 代表kafka消费者最多可以获取到7条数据
HW 必须小于或者等于 LEO 代表所有消息,已提交,或者已备份
分区中的HW 为 ISR 中所有副本LEO 的最小值
log compaction 日志压实(必须设置key) 确保kafka topic 每个分区中,具有相同的key的消息, 至少会保存最新的value 的消息
_consumer_offsets 就使用了日志压实的策略, 最会保存(groupId + topic + 分区号)最新的
broker 中的controller 的作用
更新集群元数据信息
创建topic 删除topic 分区重新分配
prefered leader 副本选举
topic 分区扩展, broker 加入集群 , broker 崩溃
受控关闭, controller leader 选举
生产者如何实现,消息的精确一次处理的语义呢, 从kafka 0.11.0.0后 kafka提供了幂等性, enable.idempotence=true
kafka调优方向
1 吞吐量
2 延时
3 持久性
4 可用性
OS 级别的错误
connection refused
too many open files
address in use connect
解决方案 ,基础设置
1 禁止atime(最新的访问时间) 更新 可以使用 mount -o noatime
2 可以通过禁止记日志操作, 的方式来提高写的速度,
commit=N_secs 该选项是 没N秒 同步一次数据和元数据 , 默认是5秒。 如果该值设的比较小,
可以减少崩溃发生时带来的数据丢失, 但若设置的较大, 则会提升整体的吞吐量,以及降低延时, 生产环境 推荐用户设置一个较大的值 1-2分钟
swapiness 设置
2 设置swapiness linux 默认为 60 s 一般建议设置为 0 禁用来提升 内存的使用率,
这里存在一个问题, 当内存用完后, linux OOM Killer 回去杀掉一个进程, 这样可能会导致数据丢失,
坐着建议, 设置为 1-10 之间,
jvm 设置
由于kafka 并没有大量使用堆上内存 所以堆内存设置为 6G,差不多可以满足
-Xmx6g -Xms6g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize—128m -XX:+UseG1GC
-XX:MaxGCPauseMillis— 20 -XX: InitiatingHeapOccupancyPercent 35 -XX:
GlHeapRegionSize—16M -XX: MinMetaspaceFreeRatio—50 -XX:
MaxMetaspaceFreeRatio=85
设置 单个jvm 最大支持的线程数 vm.max_map_count 65530
调优吞吐量,
1producer 设置 batch.size 和linger.ms 通常情况下, 会提升producer 端的TPS
会增加了 消息的延时性,
2合理设置分区个数, 分区的增大到某个数值,后由于锁竞争,和内存占用过多 降低tps, 在实际中,
可以用两倍数来逐步测试 ,直到性能拐点
3设置compression.type 对数据进行压缩,降低I/O的方式来提高tps ,压缩的话主要时针对batch的,
kafka 支持的压缩格式又, gzip ,snappy,lz4 相比来说,lz4组合的性能最好,
4 设置acks 参数, 当参数为1 代表leaderx写入底层文件系统即返回,无须等待follower 响应,acks=0,
表示 producer 端不理会 broker 端的响应, 会提升tps 但是牺牲了消息的持久化,
5 当 producer 端 retries 参数设置的值,进行指定次数的重试,如果消息能够忍受偶尔的数据丢失, 可以将
retries 设置为0 , tps 会有提升, 但是 消息发生失败后, 就不会重试,
6 max.block.ms 当producer 端的缓冲区被填满后, producer 将会进入阻塞状态, 最大的阻塞时长,
一旦超过, producer 就会抛出 TimeoutException 因此,设置 buffer.memeory(默认32MB) 的值 能使
producer 使得阻塞的情况得到缓解,
consumer 端 fetch.min.bytes 的作用, 设置leader 副本没错返回 consumer 的最小字节数,
通过增加该参数 fafka 会为每个fetch 请求的response 填入更多的数据, 减少网络开销, 提升TPS, 另一方面,
会导致延时的增加,
broker ,num。replica.fetchers 的值, 该值控制follower 从leader 副本中,获取的最大线程数, 默认使1 表示
follower 只有一个线程去实时拉去leader 的最新消息, 当 acks=all 的 producer 而言, 主要的延时可能都耽误在follower于leader 同步的过程,
增加 该值能够缩短同步的实际间隔, 提升producer的tps
参数总结
broker 端
•适当增加num.replica.fetchers,但不要超过CPU核数。
•调优GC避免经常性的Full GC。
producer 端
•适当增加batch.size,比如100-512KB。
•适当增加linger.ms,比如10-00毫秒。
•设置 compression.type=lz4。
• acks=0 或 1
• retries=0
•若多线程共享producer或分区数很多,增加buffer.memory。 consumer 端
•采用多consumer实例。
•增加 fetch.min.bytes,比如 100000。
调优延时, 大体和调优吞吐量相反,
broker 端
• 适 度 增 加 num.replica.fetchers。
•避 免 创 建 过 多 topic分 区 。
producer 端
•设 置 linger.ms=0
• 设 置 compression.type=none
•设 置 acks=l或 0
consumer 端
设 置 fetch.min.bytes=l
调优持久性
broker 端 调优持久性, 有两个重要的参数可以调节,log.flush.interval.ms 和 log.flush.interval.message,
默认情况下, log.flush.interval.ms=0, log.flush.interval.message=long.max_value,一般不需要调节
broker 端
•设置 unclean.leader.election.enable=false (0.1 丨 .0.0之前版本)《
•设置 auto.create.topics.enable=false。
•设置 replicat丨 on.factor = 3, min.insync.replicas = replication.factor - 1»
•设置 default.replication.factor = 3。
•设 置 brokcr.rack属性分散分区数据到不同机架。
•设置丨 og.flush.interval.message 和 丨 og.flush.interval.ms 为一个较小的值
producer 端
•设置 acks=all。
•设 罝 retries为一个较大的值,比如 10-30。
•设置 max.in.flight.requesls.per.connection=l
•设置 enabIe.idempotence=true 启用幂等性。
consumer 端
•设置 auto.commit.enable=false。
•消息消费成功后调用commitSync提交位移。
调优可用性
broker 端
避 免 创 建 过 多 分
设 置 unclean.leader.election.enable=true。
设 置 min.insync.replicas=l。
设 置 num.recovery.threads.per.data.dir=brolcer 端 参 数 log.dirs 中 设 置 的 目 录 数 9
producer 端
•设 罝 acks=l,若一定要设置为all,则遵循h面broker端的min.insyn.replicas配置。
consumer 端
•设 置 session.timeout.ms为 较 低 的 值 , 比 如 10000。
• (0.丨0.1.0及之后版本)设罝max.poll.imerva丨.ms为比消息平均处理时间稍大的值。
• (0.10.1.0 之前版本)设置 max.poll.records 和 max.partition.fetch.bytes 减少 consumer 处理 消 息 的 总 时 长 , 避 免 频 繁 rebalance。
笔记来源于 胡夕的apache kafka实战, 有兴趣的可以去看看那本书,