outline
- kafka是什么
- 基本概念和整体架构
- producer端
- 消息的存储机制
- consumer端
- Kafka高吞吐率的保证
kafka是什么
- 分布式的消息系统
- Scala编写
- 可水平扩展
- 高吞吐率
消息投递的三种语义
语义投递类型 | 含义 |
---|---|
At most once | 最多一次,消息可能会丢失,但不会重复 |
At least once | 最少一次,消息不会丢失,可能会重复 |
Exactly once | 只且一次,消息不丢失不重复,只且消费一次。 |
基本概念和整体架构
基本概念
概念名称 | 作用 |
---|---|
broker | 一个kafka实例 |
topic | 相当于数据库中的表 |
partition | |
segment | 段文件,最小的数据存储单位 |
Replica | partition的副本 |
Offset | 消息在分区中的偏移量,用来在分区中唯一地标识这个信息。 |
producer | 生产者,写入消息 |
consumer | 消费者 |
ConsumerGroup | 每个Consumer属于一个特定的Consumer Group,一条消息可以发送到多个不同的Consumer Group,但是一个Consumer Group中只能有一个Consumer能够消费该消息 |
AR(Assigned Replica) | 所有副本 |
ISR(In-Sync Replicas) | 同步副本列表 |
OSR(Outof-Sync Replicas) | 非同步副本列表 |
LEO(LogEndOffset) | 表示每个partition的log最后一条Message的位置 |
HW(HighWatermark,高水位) | 取一个partition对应的ISR中最小的LEO作为HW,避免数据不一致 |
zookeeper | 存储集群的 meta 信息 |
AR=ISR+OSR
整体架构
leader/follower是对于partition来说的
producer和consumer只跟leader交互
消息的存储机制
topic
topic是一个逻辑概念
每个partition在存储层面是append log文件。任何发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型数字,它是唯一标记一条消息。它唯一的标记一条消息。kafka并没有提供其他额外的索引机制来存储offset,因为在kafka中几乎不允许对消息进行“随机读写”。
partition
物理概念,物理结构上是一个文件夹,partition的名称规则为:topic名称+有序序号
每个partition都由一些列有序的、不可变的消息组成
Kafka在Zookeeper中为每一个partition动态的维护了一个ISR,这个ISR里的所有replica都跟上了leader,只有ISR里的成员才能有被选为leader的可能(unclean.leader.election.enable=false)。在这种模式下,对于f+1个副本,一个Kafka topic能在保证不丢失已经commit消息的前提下容忍f个副本的失败
在ISR中至少有一个follower时,Kafka可以确保已经commit的数据不丢失
segment
存储策略
基于时间:log.retention.hours=168
基于大小:log.retention.bytes=1073741824
producer端
写入和复制过程
producer 采用 push 模式将消息发布到 broker,每条消息都被 append 到 patition 中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障 kafka 吞吐率)。
1.根据key进行hash,选择partition--消息路由
2.producer将消息给该partition的leader,leader写日志
3.followers从leader pull消息(复制),写入本地log后 leader发送ACK
4.leader 收到所有ISR(in-sync replicas)中的replica的ACK后,增加HW(high watermark,最后commit offset)并向producer发送ACK
对于leader新写入的消息,consumer不能立刻消费,leader会等待该消息被所有ISR中的replicas同步后更新HW,此时消息才能被consumer消费。
Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。
同步复制要求所有能工作的follower都复制完,这条消息才会被commit,这种复制方式极大的影响了吞吐率。
异步复制方式下,follower异步的从leader复制数据,数据只要被leader写入log就被认为已经commit,这种情况下如果follower都还没有复制完,落后于leader时,突然leader宕机,则会丢失数据。
Kafka的这种使用ISR的方式则很好的均衡了确保数据不丢失以及吞吐率。
消息的语义投递
目前默认情况下一条消息从 producer 到 broker 是确保了最多一次,可通过设置 producer 异步发送实现最少一次。
参数 | 含义 | 默认值 | 设定值 |
---|---|---|---|
request.required.acks | 数据可靠性的级别 | 1(仅leader拿到数据) | -1 |
min.insync.replicas | ISR中的最小副本数 | 1 | > 1 |
要保证数据写入到Kafka是安全的,高可靠的,需要如下的配置:
- topic的配置:replication.factor>=3,即副本数至少是3个;2<=min.insync.replicas<=replication.factor
- broker的配置:leader的选举条件unclean.leader.election.enable=false
- producer的配置:request.required.acks=-1(all),producer.type=sync
发送模式
Kafka的发送模式由producer端的配置参数producer.type来设置
- 同步的方式,即producer.type=sync
- 异步的模式,即producer.type=async,可以是producer以batch的形式push数据,这样会极大的提高broker的性能,但是这样会增加丢失数据的风险。如果需要确保消息的可靠性,必须要将producer.type设置为sync。
consumer端
partition和consumer的个数关系
- kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息.
-
Kafka只能保证一个分区内消息的有序性,在不同分区之间无法保证
消息的语义投递
- 读完消息之后先commit再处理消息 --> 最多一次
- 读完消息先处理再commit --> 最少一次
consumer从broker中读取消息后,可以选择commit,该操作会在Zookeeper中存下该consumer在该partition下读取的消息的offset。
该consumer下一次再读该partition时会从下一条开始读取。如未commit,下一次读取的开始位置会跟上一次commit之后的开始位置相同。
- autocommit,即consumer一旦读取到数据立即自动commit。
消息去重
只且一次就需要引入消息去重机制
GUID(Globally Unique Identifier)
consumer API
- The high-level Consumer API
high-level consumer API 提供了 consumer group 的语义,一个消息只能被 group 内的一个 consumer 所消费,且 consumer 消费消息时不关注 offset,最后一个 offset 由 zookeeper 保存。 - The SimpleConsumer API
- 多次读取一个消息
- 只消费一个 patition 中的部分消息
- 使用事务来保证一个消息仅被消费一次
Kafka高吞吐率的保证
- Sequence I/O
- sendfile技术---“零拷贝”
- pagecache
磁盘I/O的性能
引用一组Kafka官方给出的测试数据(Raid-5,7200rpm0):
Sequence I/O: 600MB/s
Random I/O: 100KB/s
sendfile
上图整个过程共经历两次Context Switch,四次System Call。
pagecache
Kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。
实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。
使用PageCache功能同时可以避免在JVM内部缓存数据
避免GC
参考资料
kafka数据可靠性深度解读
kafka学习笔记:知识点整理
kafka高性能解密 pagecache sendfile
kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)