消费者分组
- 一个分组中的多个消费者作为一个整体需要能够读到它关心的话题的所有数据记录
- 同一个分组中的多个消费者的处理负载可以很容易的被Kafka自身做负载均衡
- 对于多个不同的消费者分组而言,同一个分区对每一个分组都有一个唯一的消费者和其关联
- 这种潜在的关联映射决定了任何一个消费者分组中消费者实例的数量不能超过话题本身所对应的分区的数目,否则分区到消费者实例的关联关系则无法分配
注意默认情况下,Kafka分配数据的方式是轮询式的,并尽量将连续的数据流分配到不同的服务器上
数据记录的顺序性:Kafka仅仅保证同一个分区的数据一定会按照顺序被某个消费者处理,多个分组之间的顺序是不被Kafka自身所保证的。
性能和可靠性考虑
数据复制
以分区为基本单位提供数据复制,即同一个分区有多分不同的拷贝;所有的数据读写都发生在Leader上面,而数据会同时复制给所有的Follower上。
数据写入保证
Kafka对任何一个主题,还支持一个最小必须同步的复制实例个数的设置以提高灵活性;显然这个配置应该小于该主题的副本个数。
当生产者要求获取消息写入确认的时候,Kafka会检查是否超过给定设置的Follower实例已经得到了该消息,如果没有,则写入操作会被阻塞直到满足要求的副本复制完毕
leader失效下的选举算法
最常用的算法是一种基于投票的方法,一般地Follower的个数必须是奇数以便于进行基于多数的投票和选举:即如果有 2N+1 个副本,那么必须有 N+1 个节点确认收到数据后,Leader节点才能确认数据写入成功。
大数据场景下,我们需要更多的节点和存储空间,譬如为处理单一节点的可能失效,我们需要3份数据拷贝,这在实际情况在往往是不过的;而对于有大量数据的系统中,增加系统的存储空间到5倍乃至更多倍以上则资源浪费也是相当惊人的。实际的场景中,这一策略仅仅适宜于维护轻量级的数据(如系统配置信息)而不是应用的实际数据。
kafka的处理思路:
它内部动态维护了一个保持同步的副本集合,该集合中的副本虚保证其处理速度和Leader是匹配的。只有该集合中的副本才会参与Leader的选举。所谓的动态,以为这这个副本集会在运行期中被修改刷新并保存于ZooKeepr中去;并且其数量小于实际的节点数量。写入某个分区数据的操作仅仅在这个集合中的所有节点都消费了该数据的时候才会被认为是写入提交完毕的。基于该算法,同步副本集中的任何一个副本都可以在出错的情况下被选举为新的Leader
均匀分布leader
Kafka提供的一个有意思的机制是尽可能得均衡Leader角色的分区,使得集群中的每一个机器上的Leader角色的分区数量大致相同,从而最大程度地提高整个系统的可用性
Kafka内部会将其中的一个节点设置为controller角色,这样可以处理Kafka节点层面的失效,当controller节点检测到其他的机器节点失效时,Kafka可以尽量主动切换这些设置故障节点为Leader角色的所有分区,避免被动的Leader选举算法影响整体可用性,可谓是一种主动优化措施