-
用途
- 解耦
- 异步通信
- 削峰填谷
-
关系
- topic(主题)
- broker(可以理解为一台物理机)
- record(一条消息)
- parition(分区)
- 总结
kafka中消息是以topic为单位进行处理,topic中的record可以通过轮训或者hash或者取模(%partition数量)或者自定义,放到不同的parition中,同一个分区中消息遵循FIFO,不同分区的消息不能保证,每一个broker都是一个分区的leader,或者其他区分的flower
-
角色划分
- 消费者
- 生产者
-
角色分组
- 消费者组
任何一个消费者都是属于一个customer group的,这个组会把获取的消息均分到组内的消费者消费(即同一个组内的同一条消息,只能有一个消费者消费) 一个topic可以有多个group进行订阅 如果消费者组内的实例数量大于分区数据,那么超出的实例就会空闲
- 消费者组
-
方式
- 点对点
- 发布订阅
-
日志
- 日志的持久化时间默认事168(7 * 24),底层会定期删除以前的
- 日志分区记录消息的唯一的offset,这个事有序不可变的,kafka==集群会记录==每个消费者读取到了那个offset,消费者也可以通过更改offset的值来决定从那进行读取
- 每个消费者读取分区中的日志是相互独立的
- 消费者消费完会让集群==记录下次==读取日志初始值的==offset==
- 每次读取的位置(新加入组的消费者)
auto.offset.reset = latest(最新的) / earliest(最早的) / none(未找到,抛出异常)
- 每次读取的位置(新加入组的消费者)
-
offset控制
- 默认会定期提交
- enable.auto.commit = true
- auto.commit.interval.ms = 5000
- 也可以自己控制,需要注意提交的offset要比本地消费的偏移量 ==+1==
- 默认会定期提交
-
Ack和Retry
- Ack
- 生产者发送完消息后,要求Broker在规定的时间Ack应答,如果没有会尝试n次重新发送
- 取值
1 : 只要写到leader就可以,但是如果失败,会导致所有丢失 0 :不等任何服务器确认,性能高 all/-1 : leader和flower(至少一个)确认
- Retry
- 规定时间没有应答
- 参数设置
requset.timeout.ms = 30000 默认 retries = 2147483647 默认
- 时序图
- 没有及时应答,retry多次消息
- 原因:ack应答设置为all,broker应答超时
- 解决:幂等性(从生产者角度,保证不丢失不重复)(版本1.1.0以上)
- 唯一标识
- 记录消息是否处理
enable.idempotence = true 必须开启 retries= true acks = all - 幂等性只能解决同一个分区的一条数据的不可重复
- 事务
- 解决多条记录的多分区的
- 分类
- 生产者事务Only
- 消费者&生产者事务
场景: topic1 --> 业务 --> topic2 若业务再给topic2发送消息时,失败了,要回滚从topic1提交的offset,保证还能继续从topic1读数据 - 参数设置
消费者设置事务隔离级别read_committed 生产者指定transactional.id
- Ack
-
数据同步机制
- 概念
- Topic被分为多个分区,分区按着Segments存储文件块(每个默认1G),有序的(根据offset能查到)
- leader负责读取,follower负责同步
- LEO(log end offset): 标识最后一条消息的下一个位置
- HW(high watermarker): 高水位线,所有HW之前的数据都是已经备份的,当所有结点都备份成功,leader会更新水位线
- ISR(in-sync-replicas,用于leader宕机后选出新的leader): leader会维护一份处于同步的副本集合,如果再规定的时间内(replica.lag.time.max.ms)没有发送fetch请求,或者发送了但是没有赶上限定时间,就会被leader从集合中剔除
- HW(0.11版本之前)问题
- 数据不一致或者丢失
- 问题的原因
- HW设计存在问题,在0.11+版本后引入Leader epoch概念(不在使用HW作为数据截断依据,但是没有废弃HW,而是只把HW作为同步的进度)
- 概念
-
价值点
- 高吞吐
- 日志存在磁盘中,但是读取快的原因是:
- 顺序写入
- 硬盘的每次写都会寻址(机械动作,耗时) -> 写入,顺序写能省去内存开销和IO寻址时间
- kafka数据不是实时写入到硬盘
- Memory Mapped Files(mmap),内存映射文件
- 分页存储(page cache),在磁盘中提前映射出一块要写入的地址,并把要写入的这块地址映射到操作系统的内核的内存中,程序只要把数据写到内核的空间中,就算写入成功,然后由OS自动刷新到磁盘
- 读取使用ZeroCopy技术
- 无需将数据拷贝到用户空间,而是将数据放到内核空间传递输出
- DMA计算(协处理器)
- 区分
- 顺序写入
-
kafka的监控
- kafkaEagle