Kafka--分区

分区(Partition)

传统的队列模型保存消息,并且保证它们的先后顺序不变。但是, 尽管服务器保证了消息的顺序,消息还是异步的发送给各个消费者,消费者收到消息的先后顺序不能保证了。这也意味着并行消费将不能保证消息的先后顺序。Kafka尽管没有完全解决这个问题,但是Kafka采用了一种分而治之的策略:分区。partition可以实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(跨多个partition间)的顺序。所以,如果你想要顺序的处理Topic的所有消息,只提供一个分区也是一种解决方法。

问题

1. 生产者将消息投递到哪个分区?

默认的分区策略是:

  • 如果在发消息的时候指定了分区,则消息投递到指定的分区
  • 如果没有指定分区,但是消息的key不为空,则基于key的哈希值来选择一个分区
  • 如果既没有指定分区,且消息的key也是空,则用轮询的方式选择一个分区

2. 分区与消费者组

消费者组订阅主题,意味着主题下的所有分区都会被组中的消费者消费到,如果按照从属关系来说的话就是,主题下的每个分区只从属于组中的一个消费者,不可能出现组中的两个消费者负责同一个分区。

2.1 分区数与消费者组实例数什么关系?

  • 如果分区数大于或者等于组中的消费者实例数:那自然没有什么问题,无非一个消费者会负责多个分区,当然,最理想的情况是二者数量相等,这样就相当于一个消费者负责一个分区。
  • 如果消费者实例的数量大于分区数:那么按照默认的策略,有一些消费者是多余的,一直接不到消息而处于空闲状态。

2.2 为什么一个分区只能被一个消费者组中一个实例消费?

Kafka它在设计的时候就是要保证分区下消息的顺序,也就是说消息在一个分区中的顺序是怎样的,那么消费者在消费的时候看到的就是什么样的顺序,那么要做到这一点就首先要保证消息是由消费者主动拉取的(pull),其次还要保证一个分区只能由一个消费者负责。倘若,两个消费者负责同一个分区,那么就意味着两个消费者同时读取分区的消息,由于消费者自己可以控制读取消息的offset,就有可能一个实例读到2,而另一个实例读到1,第一个实例还没处理完,第二个实例已经读到3了,则会造成很多浪费,因为这就相当于多线程读取同一个消息,会造成消息处理的重复,且不能保证消息的顺序,这就跟主动推送(push)无异。

另外消费者消费数据是需要自己提供offset的,多个实例消费同一分区,如果要实现一个分区读取数据不出现重复或保证顺序,就需要在多个实例之间维护一个公共的地方存放这个offset,这样既增加了设计难度,并且增加了通信开销。

3. 消费者组中的实例之间是怎么分配分区?

  • range分配策略(针对的是主题)
    首先,将分区按数字顺序排行序,消费者按消费者名称的字典序排好序。
    然后,用分区总数除以消费者总数。如果能够除尽,则平均分配;若除不尽,则位于排序前面的消费者将多负责一个分区。
  • 轮询分配策略(基于所有可用的消费者和所有可用的分区的)
    与range策略最大的不同就是它不再局限于某个主题。 如果所有的消费者实例的订阅都是相同的,那么这样最好了,可用统一分配,均衡分配。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值