Kafka
因为我遇到了Kafka,就记录Kafka的机制吧,先要了解一些概念:
1.producer & consumer
消息生产者与消费者
2.broker
kafka集群中包含的服务器,每个broker是一个节点,也可以看做是消费者系统中的一个kafka进程
3.topic & partition
topic相当于消息的key,属于消息的类别,一个topic包含一个或多个partition
4.replica
partition的副本
5.Zookeeper
管理producer,broker,consumer的动态加入与离开,要用kafka必须启用Zookeeper
Kafka的高可用性
Kafka 0.8 以后,提供了 HA 机制,就是 replica(复制品) 副本机制,每个partition不止直接给一个broker,而会生成自己的多个replica副本,所有的replica会选举出一个leader出来,所有的生产和消费与leader打交道,其余的replica就是follower。
写的时候,leader会负责把数据都同步到follower上,Kafka 会均匀地将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。
这么搞,就有所谓的高可用性了,因为如果某个 broker 宕机了,没事儿,那个 broker上面的 partition 在其他机器上都有副本的,如果这上面有某个 partition 的 leader,那么此时会从 follower 中重新选举一个新的 leader 出来,大家继续读写那个新的 leader 即可。这就有所谓的高可用性了。
写数据的时候,生产者就写 leader,然后 leader 将数据落地写本地磁盘,接着其他 follower 自己主动从 leader 来 pull 数据。一旦所有 follower 同步好数据了,就会发送 ack 给 leader,leader 收到所有 follower 的 ack 之后,就会返回写成功的消息给生产者。(当然,这只是其中一种模式,还可以适当调整这个行为)
消费的时候,只会从 leader 去读,但是只有当一个消息已经被所有 follower 都同步成功返回 ack 的时候,这个消息才会被消费者读到。
Kafka保证消息不被重复消费(保证消费的幂等性)
Kafka提供了两套consumer API,high-level API提供了更多的细节,offset能保证消息植被消费一次,每个消息被写的时候都有一个offset存在,代表消息的序号。当消费者消费了数据之后,每隔一段时间就会把自己消费过的消息的offset提交一下,若是要对系统做重启操作,就得冲上次消费到的offset来继续消费。
Kafka保证消息可靠性(消息不会丢失)
既然有了offset,也知道offset会自动的刷给kafka,告诉它你已经消费了这些消息,但有一种情况可能是消费者虽自动提交了offset,但其实你刚准备处理这个消息,你还没来得及处理,自己就挂了,但此时kafka已经认为你消费过了。
那么可以关闭自动提交offset,当你认为处理完消息后再手动提交,但的确可能你处理完还没提交offset自己又挂了那就只能靠自己来保证了
文章中提到起码要设置下面四个参数:
- 给 topic 设置
replication.factor
参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。 - 在 Kafka 服务端设置
min.insync.replicas
参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。 - 在 producer 端设置
acks=all
:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。 - 在 producer 端设置
retries=MAX
(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。