Kafka之基础笔记

1. kafka offset 存储

1.1 去zookeeper依赖

比较广为人知的Kafka offset存储方式为zookeeper,在0.8版本时,默认依然是zk,但是此时其实已经出现另外一种offset存储方式了,Kafka以“consumer group + topic + partition”为组合key,记录一份消费信息,存储在默认的”__consumer_offset”的Topic中。
在0.9版本中,已经默认采用第二种方式存储offset了,这么做的原因,主要是zk性能成为kafka性能的瓶颈。
1. 消费者频繁去和zk进行交互,利用ZKClient频繁写入zk,本身就是一种低效的行为。
2. 如果zk出现问题,kafka将受到影响
3. 因为zk存在羊群效应(herd)和脑裂(split brain),导致一个group里面,不同consumer拥有了同一个partition,从而引发消息的错乱

第三个原因,导致了Kafka 0.9版本中 coordinator的诞生,Kafka集群本身进行consumer之间的同步。

所以,为了提高性能,减少对Zk的依赖,offset存储在kafka topic中,因为这部分信息十分重要,所以消息的acking级别是-1,生产者等到所有ISR(In-Sync Replicas的缩写,表示副本同步队列)都受到消息后才会ack,数据安全性极好,但是性能会受到影响,所以,Kafka又在内存中维护了一个关于Group,Topic和Partition的三元组,来存储最新的offset信息,消费者获取最新offset的时候,直接从内存中获取。

1.2 zookeeper集群的脑裂

zookeeper是一个分布式应用程序的协调服务。它是一个为分布式应用提供一致性服务的软件,提供的性能包括:配置维护、名字服务、分布式同步、组服务等。
zookeeper是以Fast Paxos算法为基础,paxos算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成功,而Fase Paxos作了一些优化,通过选举产生一个leader,只有leader才能提交proposer,具体的可以看一下Fast Paxos算法。
大的集群中一般使用HA,一个Master多个slave,当Master宕机时,从slave中选出一个作为新的Master。选举leader的方案一般有两种:
1. 节点名称唯一性:多个客户端创建一个节点,只有成功创建节点的客户端才能获得锁
2. 临时顺序节点:所有客户端在某个目录下创建自己的临时顺序节点,只有序号最小的才获得锁

通常使用第一种方式,创建的节点为临时节点,存在一个Master节点平时对外服务,同时至少一个slave监控maste,在该节点上注册watcher监听器,监控的同时以某种方式进行数据同步,保持相同的状态。假如master死掉了,临时节点被删除,slave能够很快得知,并且多个slave同时向zookeeper注册该节点,成功注册的作为Master,其他slave继续重新监听。
但是可能会出现假死脑裂
1. 什么是假死
一般使用心跳检测机制确定节点是否死亡,一旦心跳检测确定master状态出现意外,则迅速通知其他slave,完成一个切换。但是心跳检测,有可能是master挂了,也有可能是超时,或者master和zk之间出现网络原因,其实master并未真的死掉。
2. 脑裂
此时,新的master和老的master将会共存。 zookeeper将会通知zk client连接到新的master,但是这个过程需要时间,有可能一部分通知到了,一部分还没有通知到,如果这时刚好有数据各自向新老master写,将会出现数据混乱。
出现脑裂的概率很 小,但是后果很严重。一般避免的方式,是检测到老master异常后,不用立刻切换,等待一段足够的时间,确保老的master已经获知变更并且做了相关的shutdown清理工作了然后再注册成为master就能避免这类问题了,这个休眠时间一般定义为与Zookeeper定义的超时时间就够了,但是这段时间内系统不可用了。
3. kafka consumer的脑裂
我们知道,kafka consumer同一个group中的消费者不能同时消费一个partition。在0.9版本之前,使用zk协调consumer之间的消费,可能会出现某一个consumer假死,其正在消费的分区被rebalance到其他消费者,出现一个分区被多个消费者消费的情况,造成数据混乱。也因此,kafka 0.9出现了coordinator

2. kafka的Replication机制

2.1 副本数据同步

在0.8版本之前,kafka是没有提供Partition的Replication机制的,一旦Broker宕机,其上所有的Partition就都无法提供服务了,而Partition又没有备份数据,数据的可用性就无法保证,所以0.8提供了Replication机制保证Broker的failover,由于Partition有多个副本,为了保证副本之间的通信,有多种方案:
1. 所有副本之间是无中心结构的,可同时读写数据,需要保证多个副本之间数据的同步
2. 在所有副本中选择一个Leader,生产者和消费者只和Leader副本交互,其他follower副本从Leader同步数据
3. 因为

第一种方式,同时写多个Replication的时候,同步很复杂,需要两两副本之间都建立连接,也就是每一个副本都需要和其他所有副本建立连接,确保和其他所有副本的数据都是同步的,效率低下。
所以,Kafka选择的是第二种方案,假设有一个5个副本的Partition,将选举一个副本作为leader,其他四个作为follower,而4个follower只需要和leader各自建立一条链路通信。此时,副本的功能变成在leader发生故障时,follower副本能够代替副本继续工作(从follower中选出一个新的leader)。

2.2 同步策略

follower必须和Leader保持完全的同步,才能在Leader故障时,代替leader。两种同步策略:
1. primary-backup replication 主备模式
2. quorum-based replication 也叫作Majority Vote,少数服从多数

首先说说第二种,leader需要等待副本集合中大多数的写操作完成(大多数的概念是指一半以上)。如果一些副本当掉了,副本组的大小也不会发生变化,这就会导致写操作无法写到失败的副本上,就无法满足半数以上的限制条件。这种模式下,假设有2N+1个副本,在提交之前要确保有N+1个副本复制完消息,为了保证正确选出新的Leader,失败的副本数不能超过N个。因为在剩下的任意N+1个Replica里,至少有一个Replica包含有最新的所有消息。这种策略的缺点是:为了保证Leader选举的正常进行,它所能容忍的失败的follower个数比较少,如果要容忍N个follower挂掉,必须要有2N+1个以上的副本。
使用主备模式复制,leader会等待组(所有的副本组成的集合)中所有副本写成功后才返回应答给客户端。如果其中一个副本当掉了,leader会将它从组中删除掉,并继续向剩余的副本写数据。一个失败的副本在恢复之后如果能赶上Leader,leader就会允许它重新加入组中。kafka中这个组的概念就是Leader副本的ISR集合。这个ISR里的所有副本都跟上了Leader,只有ISR里的成员才有被选为Leader的可能。这种模式下对于N+1个副本,一个Partition能在保证不丢失已经提交的消息的前提下容忍N个副本的失败(只要有一个副本没有失败,其他失败了都没有关系)。
比较Majority Vote和ISR,为了容忍N个副本的失败,两者在提交前需要等待的副本数量是一样的(ISR中有N+1个副本才可以容忍N个副本失败,而Majority Vote副本总数=2N+1,N+1个副本成功,才能容忍N个副本失败,所以需要等待的副本都是N+1个。这里的等待一般是将请求发送到N+1个副本后,要等待这些副本应答后才表示成功提交),但是ISR需要的总的副本数几乎是Majority Vote的一半(假设ISR中所有副本都能跟上Leader,则一共也之后N+1个副本,而Majority Vote则需要2N+1个副本)。

参考:

  1. http://zqhxuyuan.github.io/2016/02/23/2016-02-23-Kafka-Controller/
  2. https://blog.csdn.net/u010185262/article/details/49910301
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值