kafka核心原理

分片与副本机制

  • 分片
    分片是一种逻辑概念,将topic比作一个大容器,一个topic可以拆分为多个小容器,多个小容器可以构建为一个topic
  • 分片的目的
    • 提高读写效率:分片可以分布在不同节点上,在进行读写的时候,可以让多个节点一起负责
    • 分布式存储:解决单节点存储容量优先的问题
  • 副本
    副本是一种物理的概念,针对每个分片的数据,可以将其进行备份
    • 副本的目的:提高数据可靠性,防止数据丢失
    • 副本的数量:最多与节点数保持一致

kafka保证数据不丢失

1、生产者端保证数据不丢失

在生产者端,数据生产发送到Broker后,Broker提供一个确认响应ack,ack返回的值有01-1|ALL,分别代表的含义是

  • ack=0: 生产者只发送数据,不关心Broker的响应
  • ack=1:生产者发送数据到Broker端,等待Broker端中topic对应分片上的主副本接收到消息后,才认定为发送成功
  • ack=-1|ALL:生产者发送数据到Broker端,等待Broker端中topic对应分片上所有副本都接收到消息后,才认定为发送成功

从效率来说:0 > 1> -1
从安全角度来说:-1 > 1 > 0

在实际使用中,三种方案都有可能,在数据非常重要的情况下,选择-1,如果关心效率问题,不在意丢失的情况,选择0,如果允许数据有一定丢失的情况,可以选择1。

思考点:

  • 如果Broker迟迟未给ACK响应该如何解决?

可以设置超时时间,如果超时进行重试,多次重试无法解决,程序会出现报错的情况

  • 每次发送数据,Broker就要给予一次ACK响应,对网络带宽会造成影响,如何处理?

对于经常使用的数据,引入缓存池,池中的数据到一定条件后,通过异步的方式发送到Broker端,Broker则需要针对这批数据给予一次响应

  • 通过按批次异步发送数据,如果Broker端对这批数据没有给予响应,此时缓存池中数据已经满了,如何解决?

如果数据是可重复读的情况下,可以选择清空缓存池,让程序报错,通知处理,处理后,重新读取发送;如果数据是不可重复读的,此时需要对数据进行一个备份,当数据生产成功时,删除其备份,如果生产失败,可以在对应的位置上重新拉取处理(补推)。不清空缓存池的情况下,可以让程序阻塞写入,一直等待。

相关配置:

# 缓存池的大小  默认值32M
buffer.memory :33554432
# 重试次数, 最终重试不完全取决于此参数     
retries :2147483647
# 一次发送数据总的超时时间  默认值为 120000(120s)  
delivery.timeout.ms :120000
# 一次请求的超时时间 默认值为30000(30s)     
request.timeout.ms :30000
# 最终重试次数:  (delivery.timeout.ms / request.timeout.ms) -1
# 一批数据的大小 默认值 16384(16kb)   
batch.size: 16384
# 每一批次的间隔时间 默认值 0
linger.ms :0

2、broker端保证数据不丢失

broker端保证数据不丢失的方案:磁盘存储 + 多副本 + ack为-1

3、消费端保证数据不丢失

  • consumer启动后,连接到kafka,根据group.id搜索kakfa上次消费的位置
  • 如果找到上次消费的位置,就接着从这个位置开始消费数据,如果没找到,则是第一次到来,消费的位置从当前消息的偏移量位置开始
  • 消费者每次消费完数据,都要向kafka进行汇报,汇报当前消费到哪个偏移量信息

通过这种方式,可以保证消费端数据不丢失,但是会存在数据重复消费的问题。

在0.8.x版本之前,消息的偏移量记录在zookeeper上
在0.8.x版本后,消息的偏移量记录在kafka集群上,通过一个topic进行记录:__consumer_offsets,该topic共有50个分片,每个分片下有一个副本

kafka消息存储和查询机制

  • segment
    • 由两个文件组成:index文件和log文件,log文件存储消息数据,index文件存储log文件位置(索引)
    • 默认情况下,log文件最大为1GB,当到达1GB后,会滚动形成新的log文件,同时index文件也会滚动形成新的文件
    • 文件名表示当前消息的起始偏移量
    • 在默认情况下,kafka会自动删除超过7天的数据

相关配置:

# server.properties
log.retention.hours=168
log.segment.bytes=1073741824
  • 数据查询机制

查询数据的步骤分为3步:

  1. 确定数据存储在哪个segment
  2. 找到对应segment的index文件,根据index找到log位置
  3. 返回log文件的位置信息,基于磁盘顺序查询找到log文件,读取log文件中的数据。

kafka消费者负载均衡机制

对于kafka消费者负载均衡:

  • 在同个消费者组内,消费者数量最多和所监听的topic分片数量是相等的,如果有大于分片数量的消费者,则会存在消费者处于闲置的状态
  • 在同个消费者组内,topic的一个分片数据只能被一个消费者接收,不允许出现一个分片被多个消费者接收,而一个消费者可以接收多个分片数据

模拟场景:
现在有一个topic(3个分片),1个副本,有一个consumer,每分钟可以消费40条消息

1、生产者每分钟生产40条消息到topic,此时消费者每分钟可以消费40条数据,两者到达均衡,此时是一个理想化的状态。
2、生产者生产的数据量变为120条,消费者消费能力不变,此时会发生数据积压,此时我们可以通过增加消费者来解决这个问题,前提是新增的消费者在同一个消费者组内;也可以通过提高消费者消费速度来解决。
3、解决以上问题后,生产者消费者的能力持平,又达到理想化状态,随着时间推移,生产者生产速度又快了,到达160,此时假设我们再增加消费者,还是会出现数据积压问题,此时我们可以尝试增加topic的分片数量,同时提升消费者的消费速度。

  • 对于点对点消费模式:所有监听这个topic的消费者都在同一个消费者组内
  • 对于发布订阅模式:所有监听这个topic的消费者在不同消费者组内

查看数据积压命令:

kafka-consumer-groups.sh --bootstrap-server zk1:9092,zk2:9092,zk3:9092 --group yourgroupname --describe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值