【kafka】partition分区策略

方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个 topic 又可以有多个 Partition 组成,因此整个集群就可以适应任意大小的数据了;

可以提高并发,因为可以以 Partition 为单位读写了。

我们需要将 producer 发送的数据封装成一个 ProducerRecord 对象。

ProducerRecord(String topic, Integer partition, K key, V value)

ProducerRecord(String topic, Integer partition, Long timestamp, K key, V value)

ProducerRecord(String topic, K key, V value)

ProducerRecord(String topic, V value)

分区策略:

  • (1)指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
  • (2)没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值;
  • (3)既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后 面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法。

 ACK机制(保证生产者数据不丢失)

生产者将消息发送到broker,broker需要告诉生产者,你这个消息是否发送成功。如果未成功,生产者还可以采取重发的机制。

因为消息是发送到Partition,而Partition同时有多个副本。副本是需要实时同步消息的。

borker判断消息是否成功,是消息可靠落盘。

  • 半数副本以上消息完成同步,就发送ack。延迟低,但选举新的 leader 时,容忍 n 台 节点的故障,需要 2n+1 个副本

  • 全部副本完成消息同步,才发送ack。虽然延迟高,但 选举新的 leader 时,容忍 n 台节点的故障,需要 n+1个副本

Kafka 选择的第二种方案,虽然延迟高,但网络延迟对 Kafka 的影响较小,且为Kafka 的每个分区都有大量的数据,第一种方案会造成大量数据的冗余。

优化方案:ISR

leader 收到数据,所有 follower 都开始同步数据, 但有一个 follower,因为某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去, 直到它完成同步,才能发送 ack。这个问题怎么解决呢?

Leader 维护了一个动态集合in-sync replica set(和 leader 保持同步的 follower 集合)。通过参数replica.lag.time.max.ms设置时间阈值,当follower在规定时间未完成同步,则将该follower剔出这个集合。

当某些消息数据,不需要可靠。即生成者不需要ack机制时,对于不需要数据的可靠性时,kafka就没必要等 ISR 中的 follower 全部接收成功,才返回ack.所以 Kafka 为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,

acks 参数配置:

0:(只管发) producer 不等待 broker 的数据落盘就直接返回 ack,当broker故障时有可能丢失数据

1:(只保证broker数据落盘)producer 等待 broker 的 ack,partition的leader落盘成功后就不等follower同步便直接返回 ack

如果在 follower同步成功之前leader故障,那么将会丢失数据;

-1(all):(保证broker和所有follower数据落盘)producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盘成功后才 返回 ack。

但是如果在 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会 造成数据重复。

消息幂等性

kafka0.11版本之前解决消息幂等性,需要在每个消费端手动进行去消息判重(可以使用redis,或者mysql主键特性,将消费后的消息进行存储)这也是RocketMQ的消息幂等性的解决方案

kafka0.11版本后,borker支持了幂等性。将原来消费端手动需要做的去重放在了数据borker原生支持中。

要启用幂等性,只需要将 Producer 的参数中 enable.idompotence 设置为 true 即可。

原理: 开启幂等性的 Producer 在初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而Broker 端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker 只会持久化一条。但是 PID 重启就会变化,同时不同的 Partition 也具有不同主键,所以broker解决消息的幂等性无法保证跨分区跨会话的 Exactly Once。也就是说不能重启生产者。否则还是会产生重复消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值