Kafka入门
消息引擎系统:
- 开源的消息引擎系统,实现松耦合的异步式数据传递
- 常见传输协议:点对点;发布/订阅模型
- 作用:削峰填谷
Kafka相关术语
- 消息record:kafka处理的对象
- 主题topic:承载消息的容器
- 分区partition:有序不变的消息序列,每个主题下可以有多个分区
- 消息位移offset:表示分区中每条消息的位置信息
- 副本replica:一条消息被拷贝到多个地方提供数据冗余,分类:领导者副本和追随者副本
- 生产者producer:想主题发布新消息的应用程序
- 消费者consumer:从主题订阅新消息的应用程序
- 消费者位移consumer offset:表征消费者消费进度,每个消费者都有自己的消费者位移
- 消费者组consumer group :多个消费实例共同组成一个组,同时消费多个分区以实现高吞吐
- 重平衡rebalance:消费者组内某个消费者实习挂掉后,其他消费着实例自动重新分配订阅主题分区的过程。
Kafka只是消息引擎系统嘛?
- 提供三个方面的特性:提供一套API实现生产者和消费者;降低网络传输和磁盘存储开销;实现高伸缩性架构
- 作为流处理平台:优点是更容易实现端到端的正确性
- kafka是消息引擎系统,也是分布式流处理平台
Kafka基本使用
Kafka线上集群部署
集群参数配置
- 与存储信息相关参数:log.dirs、log.dir
- 与zookeeper相关参数:zookeeper.connect
- 与broker相关参数:listensers 、host.name/port
- 与topic有关的参数:retention.ms-规定了该topic消息被保存的时长、retention.bytes-规定了要为该topic预留多大的磁盘空间;max.message.bytes-决定了kafka broker能正常接受该topic的最大消息大小
Kafka客户端实践以及原理剖析
生产者消息分区机制原理剖析
- kafka详细组织方式:
- 三级结构 : 主题-分区-消息
- 每条消息只会保存在某一个分区
- 分区是实现负载均衡以及高吞吐量的关键
- 比较常见的分区策略:
- 轮询策略(默认)
- 随机策略
- 俺消息键保存策略
生产者压缩算法
- 压缩算法肯恩发生在两个地方:生产者端和broker端
- broker重新压缩消息的两种例外情况:
- broker端制定了和producer端不同的压缩算法
- broker端发生了消息格式转换
- pruducer端压缩,broker端保持,consumer端解压缩
- 常用压缩算法:LZ4、Snappy、zst、GZIP
无消息丢失配置
- 使用producer.send(msg,callback)
- 设置acks = all(认为所有broker都要接受消息)
- 设置retries为一个较大的值(应对网络抖动,自动重新消息发送,避免消息丢失)
- 设置unclean.leader.election.enable == false
- 设置 replication.factor>=3(多增加几个分区保存数据)
- 设置min.insync.replicas>1(多保存几个副本)
- 确保replication.factor min.insync.replicas
- 确保消息消费完成后在提交
Java生产者管理TCP连接
- Kafka社区选择采用tcp的原因
- 在开发客户端时,可以利用tcp提供的一些高级功能,比如多路复用请求、轮询多个连接等
- 目前已知的http库在编程语言中略显简陋
- tcp连接时在创建kafkaproducer实例时建立的,但tcp连接还可能在其他两个地方被创建
- 更新元数据后
- 发送消息时
- producer关闭tcp连接的方式有两种
- 用户主动关闭
- kafka自动关闭
kafka消息交付可靠性保障以及精确处理一次语义的实现
- 消息交付可靠性保障:指kafka对producer和consumer要处理的消息提供什么样的承诺,常见的有三种
- 最多一次: 消息可能会丢失,但绝不会被重新发送(默认)
- 至少一次:消息不回丢失,但有可能被重新发送
- 精确一次:消息不会丢失,也不会重新发送(通过幂等性和事务机制来实现)
- 幂等性只能保证单分区上的幂等性
- 事务性能够保证将消息原子性地写入多个分区中,而且不惧进程的重启
kafka消费者组–可扩展且具有容错性的消费机制
- 三个特性
- consumer group 下可以有一个或者多个consumer实例
- 在一个集群中,group ID 标识唯一的一个组
- consumer group 下所有实习订阅的主题的单个分区,只能分配给组内的某个consumer
- 同时实现了传统消息引擎的两大模型
- 如果所有实例都同属于一个group,那么它实现的是消息队列模型
- 如果所有的实例分别属于不同的group,那么他的实现就是发布订阅模型
位移主题–consumer_offsets
- 位移管理机制:将consumer的位移作为一条普通的kafka消息,提交到__consumer_offsets中,其主要作用是保存kafka消费者的位移信息
- 位移主题是一个普通的kafka主题,但消息格式是kafka自己定义的,不能修改
- kafka集群中的第一个consumer启动时,kafka会自动创建位移主题
- kafka使用compact策略来删除位移主题中的过期消息,避免该主题无限膨胀
重平衡–Rebalance
- Rebalance的三个弊端
- 影响consumer的tps
- 很慢
- 效率不高
- 2类非必要的rebalance
- 因为consumer没及时发送心跳请求,导致被“踢出”group引发
- consumer消费时间过长导致
位移提交方法
- 自动提交位移:参数enable.auto.commit设置为true或者压根不设置
- 手动提交位移:
- 同步提交:把参数enable.auto.commit设置为false,调用相应API-commitSync()
- 异步提交:调用commitAsync()
Kafka Java Consumer设计原理
- kafka的kafkaConsumer是单线程设计的,0.10.1.0版本开始变成双线程,用户主线程和心跳线程,但实际消息的获取仍然是在用户主线程中
- kafkaConsumer不是线程安全的,制定两套方案来实现多线程消费
- 消费者程序启动多个线程,每个线程维护专属的kafkaConsunmer实例,负责完整的消息获取、消息处理流程
- 消费者程序使用单或多线程获取消息,同时创建多个消费者线程执行消息处理逻辑
Java消费者管理TCP连接
- tcp连接创建的三个时机
- 发起findcoordinator请求时
- 连接协调者时
- 消费数据时
- 消费者程序创建三类tcp连接
- 确定协调者和获取集群元数据
- 连接协调者,令其执行组成员管理操作
- 执行实际的消息获取
消费者消费进度监控
- 滞后程度:消费者当前落后于生产者的程度
- 三种监控方法:
- 使用kafka自带的命令行工具:kafka-consumer-groups脚本
- 使用kafka java consumer api编程
- 使用kafka自带的JMX监控指标
- 建议:真实环境中优先考虑方法3
深入kafka内核
kafka副本机制
- 含义:指通过分布式系统在多台网络互联的机器上保存有相同的数据拷贝
- 三个好处
- 提供数据冗余(实际只能实现这一个)
- 提供高伸缩性
- 改善数据局部性
- kafka追随者副本不对外提供服务的两个好处
- 方便实现Read-yours-writes
- 方便实现单调读
- 判断follower是否于leader同步的标准,看broler端参数replica.lag.time.max.ms参数值:含义是追随者副本落后leader副本的最长时间间隔
kafka请求处理
- reactor模式:事件驱动架构的一种实现方式。适合应用于处理多个客户端并发向服务器端发送请求的场景
- kafka的broker端有一个socketserver组件,对应的有一个acceptor线程和一个网络线程池,该线程池默认值是3
- acceptor线程采用轮询的方式将请求分发到网络线程中
- 异步线程池的处理
- 将请求放入共享请求队列
- broker中的io线程池负责从该队列中取出请求
- 如果是生产请求则将消息写入底层的磁盘日志
- 如果是fetch请求,则从磁盘或页缓存中读取消息
- 请求队列是所有网络线程共享的,响应队列则是每逢网络线程专属的
消费者组重平衡
- 重平衡3个触发条件
- 组成员数量发生变化
- 订阅主题数发生变化
- 订阅主题的分区数发生变化
- 消费者的5种状态
- empty
- dead
- preparingrebalance
- completingrebalance
- stable
- 消费者端重平衡2个步骤
- 加入组(joingroup请求)
- 等待领导者消费者分配方案(syncgroup请求)
- 协调者处理重平衡的4个场景
- 新成员加入组
- 组成员主动离组
- 组成员崩溃离组
- 重平衡时协调者对组内成员提交位移的处理
转自:
https://www.cnblogs.com/lyjps/p/17010437.html