Kafka 题

作者: 水木共美 | 来源:发表于2021-06-29 13:43 被阅读0次

1、kafka的设计

消息的生产者producer
消息的消费者consumer
kafka服务节点broker
kafka消息类型 topic
每个topic可以有多个分区 partition
每个topic的分区都有备份 replication
消费者组 consumer group
每个分区和其多个备份间 leader follower

2、ZooKeeper在Kafka中的作用

  • broker注册
    /brokers/ids/[0-N]
    临时节点 - 宕机自动删除

  • topic注册
    /borkers/topics/[topic_key]
    /brokers/topics/login_topic/3->2 标识id为3的broker为该topic总共提供了2个分区

  • 生产者负载均衡
    1、四层负载均衡
    根据生产者的ip和端口,为其确定唯一的一个broker连接
    好处:只用与一个broker建立tcp连接,减小开销
    坏处:如果生产者生产能力差异很大,会导致broker的负载差异很大,负载均衡效果减弱
    2、使用ZooKeeper负载均衡
    生产者通过ZooKeeper获取broker的列表,并监听节点变化。进行负载均衡

  • 分区与消费者的关系
    consumer group 会分配唯一id,topic下的某个分区只能分配给group_id下一个consumer。(所以group下consumer不要超过分区数,会出现有的consumer无法消费到消息)
    /consumers/[group_id]/owners/[topic]/[broker_id-partition_id]
    [broker_id-partition_id]就是一个消息分区的标识,该节点内容就是消费者的consumer_id

  • 记录消费进度offset
    /consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]
    节点内容记录的就是该分区的offset

  • 消费者注册
    /consumers/[group_id]/ids/[consumer_id] 消费者启动后注册consumer_id,节点内容是订阅的topics
    每个消费者都需要监听/consumers/[group_id]/ids节点的子节点变化,用来触发消费者的负载均衡

    image.png

3、Kafka消息如何保证消费的顺序性

  • topic下只创建一个分区,同一分区内的消费是有顺序性的
  • 生产者负载均衡的设计。比如如果使用对key的hash值进行负载均衡发送消息,那我们可以根据业务,需要保证顺序性的业务使用相同的key,如用户id 也可以代码指定需要发送的partition

4、如何保证消息的不丢失

生产者有个参数acks设置
0 标识只管发送,不用等待response,性能高,吞吐强
1 标识leader写入完成就返回,不需要等待ISR 吞吐量高 默认值
-1或者all 标识需要等待leader写入完成和ISR副本备份完成,才返回。 吞吐量低

消费者 设置是否自动提交
enable.auto.commit
consumer是批量拉取消息的,自动提交开启,会在拉取到消息后就立马提交offset,不管消息是否已经都消费了
关闭后,你可以在每次消费完当前消息就提交当前消息的offset,可以确保不丢失消费消息

5、Kafka如何加快消息消费速度

  • 增加consumer消费者个数,存在一个问题不能超过分区数
  • consumer内使用多线程消费,如拉取到一堆消息,将消息丢到线程池进行消费,消费完后提交offset。然后再拉取消息

6、Kafka如何加快生产

producer 需要设置批量发送,减少网络开销。
batch.size 消息达到多少时(字节数,不是条数),触发一次发送
linger.ms 缓存时间超过多少时,触发一次发送

如果消息设置了key,默认情况producer会根据key的hash值选取分区发送,而如果没有设置key,默认是轮训分区发送到每个分区
无key的情况下,很容易造成消息分散,batch发送无法达成。针对这个情况出现了粘性分区策略,也即某个短时间内的消息都发到一个分区上,过了这个时间段,然后换个分区。轮训的时间段版本

7、Kafka消费者语义at least once,如何处理重复消费问题

发送消息时,传入key作为唯一流水ID
消费消息时,判断是否已经已经消费过该ID消息
业务上做幂等

8、Kafka ISR机制

in sync replicate
这些机制都是针对acks=0或者1的情况

follower与leader不同步的原因:

  • 1.速度跟不上 leader写入速度过快,而follower因为网络IO等问题,拉取写入速度慢与leader速度
  • 2.进程卡主 follower一段时间内卡主未向leader拉取新消息FetchRequest,如太过频繁的GC等
  • 3.新增备份因子 factor扩大 刚启动的follower肯定慢与leader

replica.lag.max.messages 落后消息数大余这个值时,剔除出ISR列表,适合上诉场景的1
该参数已经被删除了,原因是这个值的设置需要根据具体业务数据量进行设置,而这个设置值是全局的,针对所有topic的。如果设置值过大,相当于无效设置,如果设置值过小,会导致不断触发剔除与加入,性能降低。
replica.lag.time.max.ms 超过这个时间没向leader请求数据FetchRequest,剔除出ISR列表。适合剔除上诉场景的2,3

9、Kafka文件存储机制 吞吐量为啥大

题外:

  • 磁盘随机读写慢 寻址耗时
  • linux pagecache 在内存上缓存了部分磁盘上的数据,免除用户访问每次都对磁盘进行直接操作
    预读
    回写
  • 普通IO
    读取网络数据写入磁盘过程 :
    DMA IO读取到内核socket缓冲区 -》 内核socket缓冲区读取到用户内存 -》用户内存写入内核磁盘缓冲区 -》 DMA内核缓冲区刷新存储到磁盘
    读取磁盘数据发送网络过程 :
    DMA磁盘读取到内核磁盘缓冲区 -》 内核磁盘缓冲区读取到用户内存 -》用户内存写入到内核socket缓冲区 -》DMA内核socket缓冲区写入到网络IO

Kafka文件存储
一个topic可以分多个partition存储到不同的broker,一个partition由多个segment组成,每个segment有.index和.log文件组成。segment的文件名由起始的offset定义,第一个segment文件从0开始。 .index 文件存储元数据,如(3,349)标识这个segment中的第3条消息在.log文件的物理偏移位置是349,


image.png

示例:查找offset为368776的消息
1、通过文件名列表排序后进行二分查找,定位到该消息在00000000000000368769.index|log这个segment中,
2、通过368769.index文件查找第7条元数据,定位到消息在.log中的偏移量,然后对368769.log文件进行顺序查找,找到该偏移量处的消息
.index这个文件 叫稀疏索引存储 降低索引文件存储空间占用

吞吐量高的原因:

  • 顺序读写 Kafka的message信息,是不断追加到本地磁盘末尾,而不是随机写入。对应到上面即为.log文件末尾写入,引起的问题是,不允许中间删除消息或修改消息。kafka提供了基于时间和空间的自动删除策略,删除是已segment为单位的整文件删除。
  • 使用PageCache 利用的是内核内存而不是jvm内存,避免了虚拟机内存开销及垃圾回收机制和构建Object的开销。服务重启PageCache也还在,缓存重建快速。
  • 零拷贝机制 系统的sendfile方法,可以直接将内核缓冲区数据PageCache 发送到 内核socket缓冲区,避免了向用户内存的2次拷贝。 mmap 直接操作内核缓冲区数据。
    java FileChannel 的支持
// 将当前 FileChannel 的字节传输到给定的可写 channel 中
public abstract long transferTo(long position, long count,  WritableByteChannel target) throws IOException;
// 将一个可读 channel 的字节传输到当前 FileChannel中
public abstract long transferFrom(ReadableByteChannel src, long position, long count) throws IOException;
// 对 Channel 做 mmap 映射
public abstract MappedByteBuffer map(MapMode mode, long position, long size) throws IOException;
  • 分partition分segment
  • 批量写和批量读

10、kafka消费分区策略

  • 默认 Range 每个topic都按其消费者数连续分配等量的分区数,多余的优先分配到前面的消费者
    如 T1 消息有7个分区T1-0,T1-1..T1-6,T2 消息有4个分区 有3个消费者C0,C1,C1
    则:
    C0 :T1-0,T1-1,T1-2,T2-0,T2-1
    C1: T1-3,T1-4,T2-2
    C2: T1-5,T1-6,T2-3
    缺陷:排号靠前的消费者,会分配到更多的分区,压力更大
  • RoundRobin
    1、如果组内消费者订阅的topic都相同,最终分配是均匀的
    如T0,T1都有3个分区,C0,C1都订阅了T0,T1
    则:
    C0:T0-0,T0-2,T1-1
    C1:T0-1,T1-0,T1-2
    2、组内消费者订阅topic不同时
    如T0,T1,T2都有3个分区, 消费者C0订阅的是主题T0,消费者C1订阅的是主题T0和T1,消费者C2订阅的是主题T0、T1和T2 会出现分配不均
    C0:T0-0
    C1:T1-0
    C2:T1-1,T2-0,T2-1,T2-3
  • StickyAssignor

11、消息队列

优点:解耦、异步、削峰
缺点:系统复杂性增加 (如一致性,重复消费,消息丢失等)、系统可用性降低

相关文章

  • Kafka 题

    1、kafka的设计 消息的生产者producer消息的消费者consumerkafka服务节点brokerkaf...

  • 2020-12-03

    操作系统计算机网络redis/kafka/brpc数据库/mysql算法刷题

  • Kafka详细的设计和生态系统

    Kafka详细的设计和生态系统 Kafka生态系统 - Kafka核心,Kafka流,Kafka连接,Kafka ...

  • kafka全面认知

    什么是Kafka[#---kafka] Kafka的应用场景[#kafka-----] Kafka的架构[#kaf...

  • Kafka & NSQ

    Kafka & NSQ Kafka kafka struct kafka & consumer group 2ka...

  • kafka学习系列

    Kafka学习总结(一)——Kafka简介 Kafka学习总结(二)——Kafka设计原理 Kafka学习总结(三...

  • Kafka Producer源码

    Kafka Producer Kafka Producer 是 kafka 提供的与 Kafka Broker 连...

  • Kafka 详解一 简介

    目录 Kafka 是什么 Kafka 核心组 Kafka 整体架构以及解析 Kafka数据处理步骤 Kafka名词...

  • kafka详解

    目录 Kafka 是什么 Kafka 核心组 Kafka 整体架构以及解析 Kafka数据处理步骤 Kafka名词...

  • kafka配置KAFKA_LISTENERS和KAFKA_ADV

    kafka配置KAFKA_LISTENERS和KAFKA_ADVERTISED_LISTENERS 介绍kafka...

网友评论

      本文标题:Kafka 题

      本文链接:https://www.haomeiwen.com/subject/ttbbyltx.html