1 kafka架构
1.1 概念和基本架构
kafka介绍
有两种主要的消息传递模式:
- 点对点传递
- 发布-订阅模式
kafka就是一种发布订阅模式
对于消息中间件,消息分推拉两种模式。kafka只有消息的拉取,没有推送,可以通过轮询实现消息的推送。
1.1.1 kafka的优势
1.1.2 kafka应用场景
日志收集:一个公司可以用kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种Consumer;
消息系统:解耦生产者和消费者、缓存消息等;
用户活动跟踪:kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后消费者通过订阅这些topic来做实时的监控分析,也可保存到数据库。
运营指标:Kafka也经常⽤来记录运营监控数据。包括收集各种分布式应⽤的数据,⽣产各种操作的集中反馈,⽐如报警和报告;
流式处理:⽐如Spark Streaming和Storm
1.1.3 基本架构
消息和批次
kafka的数据单元称为消息,可以把消息看成是数据库的一个“数据行”。
消息有键,消息由字节数组组成
当消息以一种可控的方式写入不同的分区时,会用到键。
为了提高效率,消息被分批写入kafka。批次就是一组消息,这些消息属于同一个主题和分区。
把消息分成批次可以减少⽹络开销。批次越⼤,单位时间内处理的消息就越多,单个消息的传输时间就越⻓。批次数据会被压缩,这样可以提升数据的传输和存储能⼒,但是需要更多的计算处理。
模式
消息模式(schema)有许多可⽤的选项,以便于理解。如JSON和XML,但是它们缺乏强类型处理能⼒。Kafka的 许多开发者喜欢使⽤Apache Avro。Avro提供了⼀种紧凑的序列化格式,模式和消息体分开。当模式发⽣变化时,不 需要重新⽣成代码,它还⽀持强类型和模式进化,其版本既向前兼容,也向后兼容。
主题和分区
生产者和消费者
broker和集群
⼀个独⽴的Kafka服务器称为broker。broker接收来⾃⽣产者的消息,为消息设置偏移量,并提交消息到磁盘保 存。broker为消费者提供服务,对读取分区的请求做出响应,返回已经提交到磁盘上的消息。单个broker可以轻松处 理数千个分区以及每秒百万级的消息量。
每个集群都有⼀个broker是集群控制器(⾃动从集群的活跃成员中选举出来)。 控制器负责管理⼯作:
1.将分区分配给broker
2.监控broker
集群中⼀个分区属于⼀个broker,该broker称为分区⾸领。
⼀个分区可以分配给多个broker,此时会发⽣分区复制。
分区的复制提供了消息冗余,⾼可⽤。副本分区不负责处理消息的读写。
2 kafka高级特性解析
2.1 主题
2.1.1 管理
创建主题
kafka-topics.sh --zookeeper localhost:2181/myKafka --create --topic topic_x -- partitions 1 --replication-factor 1
kafka-topics.sh --zookeeper localhost:2181/myKafka --create --topic topic_test_02 -- partitions 3 --replication-factor 1 --config max.message.bytes=1048576 --config segment.bytes=10485760
查看主题
kafka-topics.sh --zookeeper localhost:2181/myKafka --list
kafka-topics.sh --zookeeper localhost:2181/myKafka --describe --topic topic_x
kafka-topics.sh --zookeeper localhost:2181/myKafka --topics-with-overrides --describe
修改主题
kafka-topics.sh --zookeeper localhost:2181/myKafka --create --topic topic_test_01 -- partitions 2 --replication-factor 1
kafka-topics.sh --zookeeper localhost:2181/myKafka --alter --topic topic_test_01 -- config max.message.bytes=1048576
kafka-topics.sh --zookeeper localhost:2181/myKafka --describe --topic topic_test_01 kafka-topics.sh --zookeeper localhost:2181/myKafka --alter --topic topic_test_01 -- config segment.bytes=10485760
kafka-topics.sh --zookeeper localhost:2181/myKafka --alter --delete-config max.message.bytes --topic topic_test_01
删除主题
kafka-topics.sh --zookeeper localhost:2181/myKafka --delete --topic topic_x
2.1.2 增加分区
kafka-topics.sh --zookeeper localhost/myKafka --alter --topic myTop1 --partitions 2
2.1.3 分区副本的分配
2.2 分区
2.2.1 副本机制
2.2.2 Leader选举
2.3 稳定性
2.3.1 事务
1、事务使⽤场景
在⼀个原⼦操作中,根据包含的操作类型,可以分为三种情况,前两种情况是事务引⼊的场景,最后⼀种没⽤。
- 只有Producer⽣产消息;
- 消费消息和⽣产消息并存,这个是事务场景中最常⽤的情况,就是我们常说的
模式 - 只有consumer消费消息,这种操作其实没有什么意义,跟使⽤⼿动提交效果⼀样,⽽且也不是事务属性引 ⼊的⽬的,所以⼀般不会使⽤这种情况
2、事务配置
1、创建消费者代码,需要:
将配置中的⾃动提交属性(auto.commit)进⾏关闭
⽽且在代码⾥⾯也不能使⽤⼿动提交commitSync( )或者commitAsync( ) 设置isolation.level
2、创建⽣成者,代码如下,需要: 配置transactional.id属性
配置enable.idempotence属性
2.3.2 控制器
Kafka集群包含若⼲个broker,broker.id指定broker的编号,编号不要重复。
Kafka集群上创建的主题,包含若⼲个分区。
每个分区包含若⼲个副本,副本因⼦包括了Follower副本和Leader副本。
副本⼜分为ISR(同步副本分区)和OSR(⾮同步副本分区)。
控制器就是⼀个broker。
控制器除了⼀般broker的功能,还负责Leader分区的选举。
2.3.2.1 broker选举
集群⾥第⼀个启动的broker在Zookeeper中创建临时节点 /controller。
其他broker在该控制器节点创建Zookeeper watch对象,使⽤Zookeeper的监听机制接收该节点的变更。
即:Kafka通过Zookeeper的分布式锁特性选举集群控制器。
每个新选出的控制器通过 Zookeeper 的条件递增操作获得⼀个全新的、数值更⼤的 controller epoch。其他 broker 在知道当前 controller epoch 后,如果收到由控制器发出的包含较旧epoch 的消息,就会忽略它们,以防⽌ “脑裂”。
结论:
- Kafka 使⽤ Zookeeper 的分布式锁选举控制器,并在节点加⼊集群或退出集群时通知控制器。
- 控制器负责在节点加⼊或离开集群时进⾏分区Leader选举。
- 控制器使⽤epoch 来避免“脑裂”。“脑裂”是指两个节点同时认为⾃⼰是当前的控制器。
2.3.3 可靠性保证
2.3.3.1 失效副本
Kafka中,⼀个主题可以有多个分区,增强主题的可扩展性,为了保证靠可⽤,可以为每个分区设置副本数。 只有Leader副本可以对外提供读写服务,Follower副本只负责poll Leader副本的数据,与Leader副本保持数据的
同步。
系统维护⼀个ISR副本集合,即所有与Leader副本保持同步的副本列表。 当Leader宕机找不到的时候,就从ISR列表中挑选⼀个分区做Leader。
如果ISR列表中的副本都找不到了,就剩下OSR的副本了。
此时,有两个选择:要么选择OSR的副本做Leader,优点是可以⽴即恢复该分区的服务。 缺点是可能会丢失数据。
要么选择等待,等待ISR列表中的分区副本可⽤,就选择该可⽤ISR分区副本做Leader。优点是不会丢失数据 缺点是会影响当前分区的可⽤性。
2.3.4 ⼀致性保证
2.3.4 消息重复
消息重复主要发⽣在以下三个阶段:
- ⽣产者阶段
- broke阶段
- 消费者阶段
⽣产发送的消息没有收到正确的broke响应,导致producer重试。
producer发出⼀条消息,broke落盘以后因为⽹络等种种原因发送端得到⼀个发送失败的响应或者⽹络中断,然 后producer收到⼀个可恢复的Exception重试消息导致消息重复。