kafka总结

特点

高性能、吞吐:顺序IO,topic-多partition,consumer group消费partition
可靠性:磁盘
高并发:支持数千client同时读写

高可用:topic-多partition
高扩展:支持热扩展

使用场景

消息系统,削峰填谷
日志收集,
异步处理,

流处理,比如spark streaming和storm
用户活动track,
运营指标,
事件源

概念

消息提供者:producer
服务节点:broker
集群:多个broker
消息消费者:consumer
消费组:consumer group,多个consumer组成
主题:topic
分区:partition,一个topic分为多个partition,每个partition有若干replica分布到不同broker保证容错性
分区副本:partition replica
分区leader:partition leader,producer发消息时是直接发给leader的,再由leader push给其它replica,消费也是只跟leader打交道
所有副本:AR,Assigned Repllicas,AR=ISR+OSR,正常情况下OSR应为空
ISR:In-Sync Replicas,同步副本(包括leader)
OSR:Out-Sync Relipcas,滞后副本

主(broker):kafka broker controller
从(broker):kafka broker follower

设计思想

broker选主

所有broker去zookeeper上注册临时节点,成功的成为controller,失败的都成为follower;

当controller宕机,其它节点重复上述操作;
当某个follower宕机,controller会进行以下处理并通知zk和其它follower;
– 去zk那读取宕机的follower的partition状态信息,为的是找出一个replica作为partition leader
– 优先读取ISR列表,选出leader;
– 如果ISR全挂,选出一个幸存的(非ISR)replica作为leader;
– 如果幸存的都没有,那只能等待恢复了,ISR或非ISR任意一个活过来就行,设置为leader
思想就是一台broker宕机了,它的partition不能没人管,去查查数据看谁还有相同数据的partition。partition必须有个老大(leader),优先ISR列表中的,因为数据全。

partition选主

大部分分布式都采用了投票的方法选主,但选出来的主可能不太理想,有可能少了部分数据,kafka没有采用这种办法,unclean.leader.election=true。

kafka在zk中动态维护了一个状态同步的副本集合,ISR(In sync replica),节点和leader保持高度同步。任何一条消息都必须在每个节点中读取并追加到日志文件中了,才会对外宣称消息已经提交了。

如果ISR中所有的副本全挂掉,有两种策略:
1. 等待任意一个恢复
1. 选择一个非ISR的节点(kafka做出的选择)
这是在可用性和可靠性之间作出的权衡,需要根据业务场景配置具体策略

消息的生产

kafka产生消息是push的形式,消费消息是pull的形式(所以有轮询开销,但可以控制速度)。

offset和生产没关系,它是消费端的消费状态。生产者只管发送大批量消息,消息经过负载均衡后会到某些partition上,意味着消费这些partition的消费线程又有活干了。

image-20211105102354425

producer 连接broker,broker访问zk更新更新offset,producer发送消息给broker。

消息生产的可靠性

ack机制
image-20211104230227877

消息存储可靠性

磁盘,顺序写,o(1)的时间复杂度,性能非常高,一般的机器,单机每秒100k条数据。

消息消费的可靠性

commit机制

消费组

多个consumer线程形成一个消费组,这个组会消费掉一个topic下所有partition的数据。
一条数据只会被一个消费组消费一次,若想消费两次,应该定义两个消费组消费这条消息。

关于消费组内线程会不会产生竞争问题,答案是不会
它的最佳实践是topic有几个partition,就开几个consumer thread去消费,互不干扰。如果数量匹配不上,那就可能消费速率过低,或者开了很多线程但不干活。
设定消费组时只要说明有几个consumer线程就行,会自动去rebalance决定怎么去消费partition。

当消息提供者流量增加时,很自然的扩展方式就是增加topic的partition,同时增加对应数量的consumer。

rebalance的条件
增删消费组
增删broker

消息的消费

一个消费线程读取partition的数据,时间复杂度是o(1)。它读的时候记录了一个offset,代表上次读到哪了。
这个数据在 high level api中是保存在zk里的,low level api 需要自己维护,所以一般都用high level的。

小知识:【在 Kafka 0.9 版本之前,Consumer 默认将 Offset 保存在 ZooKeeper 中,但是从 0.9 版本开始,Consumer 默认将 Offset 保存在 Kafka 一个内置的 Topic 中,该 Topic 为 __consumer_offsets, 以支持高并发的读写。】

读完了如果设置了autocomit = true,offset会加1,如果读取中断了业务没处理完这条消息就丢了,所以对可靠性要求高的应用应当设置为不自动提交,做好幂等性处理。

image-20211105102609102

consumer连接brokers,broker通过zk获取partition的信息,consumer读取broker上的数据。

部分转自:https://www.cnblogs.com/dreamroute/p/13092117.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注