Kafka
概述
kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能,持久化,多副本备份,横向扩展能力
相关概念
- Producer:消息的生产者,消息的入口
- kafka cluster: kafka集群
- Broker: kafka实例,每个服务器上有一个或多个kafka实例
- Topic:消息的主题,可以理解为消息的分类,kafka的数据保存在topic,每个broker上都可以创建多个topic
- Partion: Topic的分区,每个Topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量
- Replication:每一个分区都有多个副本,副本的作用是做备胎
- Message:每一条发送的消息主体
- Consumer:消费者
- Consumer Group:多个消费者组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量
工作流程
-
发送数据:Producer写入数据时永远找leader,不会将数据写入follower
消息在写入leader后,follower是主动的去leader进行同步的,producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的
为什么要分区呢?
-
方便扩展:因为一个topic可以有多个partition,所以我们可以通过扩展及其去应对日益增长的数据量
-
提高并发:以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率
kafka应该发送到哪个partition呢?
- 可以指定partition,则写入对应的partition
- 如果没有指定,但是设置了数据的key,则会根据key的值hash出一个partition
- 如果都没有,则会轮询出一个partition
那么怎么保证消息不丢失呢?
可以通过ACK应答机制
- 0:代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效率最高
- 1:代表producer往集群发送数据只要leader应答就会发送下一条
- all:代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条
-
-
保存数据:
Producer将数据写入kafka后,集群就需要对数据进行保存了。kafka将数据保存在磁盘,kafka初始会单独开辟一块 磁盘空间,顺序写入数据(效率比随机写入高)
-
Partition结构:
每个topic都可以分为一个或多个partition。Partition在服务器上的表现形式就是一个个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件,.log文件,.timeindex文件。log文件就实际是存储message的地方,而index何timeindex文件为索引文件,用于检索消息
-
Message结构:
消息主要包含消息体,消息大小,offset,压缩类型等等,主要的是以下三个:
- offset: offset是一个占8byte的有序id号,它可以唯一确定每条消息在partition内的位置
- 消息大小:消息大小占用4byte,用于描述消息的大小
- 消息体:消息体存放的是实际的消息数据(被压缩),占用的空间根据具体的消息而不一致
-
存储策略
无论消息是否被消费,kafka都会保存,那对于旧数据的删除策略是什么?
- 基于时间:默认7天
- 基于大小:默认1073741824(1G)
需要注意,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高性能
-
消费数据
消息存储在log文件后,消费者就可以进行消费了。kafka采用的是点对点模式,消费者主动的去kafka集群找leader拉取消息
多个消费者组成一个消费者组,每个消费者组都有一个组id,同一个消费者组的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区数据。所以实际应用中建议消费者和分区数量一致
查找数据是根据segment+offset+稀疏索引+二分查找+顺序查找来实现的
基本原理
分布式和分区
其实就是将一个topic划分为多个分区,每个分区对应一个文件,可以存储到不同的机器上,以实现分布式的集群存储。另外每个partition可以有一定的副本,可以备份到多台机器上,以提高可用性
副本
kafka还可以配置partitions需要的备份的个数(replicas),每个partition将会被备份到多台机器上,以提高可用性
好处
- 可靠性:kafka是分布式,分区,复制和容错的
- 可扩展性:kafka消息传递系统轻松缩放,无需停机
- 耐用性:kafka使用分布式提交日志,这意味着消息会尽可能快地保存在磁盘上,因此它是持久的
- 性能:kafka对于发布和订阅消息都具有高吞吐量。即使存储了许多TB的消息,也保持稳定的性能