Kafka 原理简介
Kafka 原理简介
Kafka 是一种高吞吐的分布式发布订阅的消息系统,可以处理消费者规模较大的网站流数据,具有高性能的,持久化,多副本,横向扩展能力。
- https://www.cnblogs.com/sujing/p/10960832.html
Kafka 的组成结构
Kafka 的基础架构图:
- Producer Producer 生产者,消息的生产者。
kafka cluster
- Broker : Broker 是 kafka 的实例,每个服务器有一个或者多个 Kafka实例。Kafka 集群内的 broker 有不重复的编号。
- Topic: 消息主题,可以理解为消息的分类,Kafka 的数据保存在 topic 中,有点类似队列,每个broker 可以创建多个 topic 。
- Partition: Topic 的分区,每个topic 可以有多个分区。分区的作用是负载,提高 kafka 的吞吐量。同一个 Topic 在不同分区上的的数据是不重复的,partion 的表现形式是一个个文件夹。
- Replication:每个分区有多个副本,当主分区(Leader)出现故障是,会选择一个副本(Follower)上位。成为新Leader 。Kafka 默认副本数为10 个,副本数量不能大于 Broker 的数量,follower 和leader 在不同机器。
- Message 消息主体
- Consumer 消息消费者
- Consumer Group ,可以将多个消费者组成一个消费者组,同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个 topic 的不同分区的数据。提高 Kafka 的吞吐量。
- zookeeper kafka 集群依赖 zookeeper 保存集群信息,保证系统的可用性。
工作流程
生产者发送数据
producer 是生产者,也是数据的入口,Producer 在写入数据时,写入leader , 不会将数据写入 follower。
producer 是采用 push 模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内数据是有序的。
- 一个topic可以有有多个partion ,可以提高系统的扩展性。
- 消费者以partion 读写单位,可以多个消费者同时消费数据,提高消息处理速率。
Partion 结构
Partion 文件夹下有很多组 segment 文件,每组 segement 文件包含 .index 、.log 文件、.timeindex 文件,这三个文件。
- log 文件是实际存储 message 的地方
- index 和 timeindex 文件为所有文件,用于检索消息。
每个partion 有多个 segement ,每个 segment 以 最小offset 来命名,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。
发送过程如何保证消息不丢失?
producer 向 kafka 发送消息时,要集群保证消息不丢失,其实是通过 ACK 机制, 当生产者写入数据,可以通过设置参数来确定 Kafka 是否接收到数据。
- 0 代表 producer 往集群发送数据,不需要等待集群返回,不确保消息发送成功。安全性低,效率高。
- 1 代表 producer 往集群发送数据,只需要leader 应答即可,只确保了leader 接收到了消息数据。
- all 代表 producer 往集群发送数据,需要所有的 follower 与leader 完成数据同步,生产者 producer 才会发送下一条消息。安全性最高,效率最低。
Message 结构
Message 是存储在log 里面的,Message 结构主要分成几个部分,消息体,消息大小,offset、压缩类型等。
- offset: offset 是一个有序 id ,可以为其确定每条消息在 partion 内的位置,占 8Byte
- 消息大小,描述消息的大小,占4byte
- 消息体,消息存放的实际消息数据
保留策略
Redis 有个缓存淘汰策略,Kafka 有个存储策略, 无论消息是否被消费,Kafka 都会保存所有的消息,这个和Rabbitmq不一样, kafka 是删除旧消息策略:
- 基于时间策略,默认配置 168小时(7天)
- 基于大小策略,当topic 所占日志大小大于一个阀值时,则可以开始删除最旧的消息了。
清理超过指定时间清理:
log.retention.hours=16
超过指定大小后,删除旧的消息:
log.retention.bytes=1073741824
消费者消费消息
消息存储在 Log 中,消费者可以进行消费了,消费者是从 Leader 中去拉取消息的。kafka 不决定何时,如何消费消息,而是通过 Consumer 决定何时,如何消费消息。
多个消费者可以组成一个消费组,每个消费组有一个组 id, 同一个消费组者的消费者可以消费同一个 topic 下不同分区的数据,但是不会组内多个消费者消费同一个分区的数据。一个分区只能被一个消费者消费。一个消费者可以消费多个分区。
怎么根据 segment + offset 查找到对应消息呢?
- 先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。
- 打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系,所以直接找相对offset为5的索引找不到,这里同样利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。
- 根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- GitHub-分支管理02-BUG与Feature分支
- GitHub-分支管理03-多人合作【重点】
- 宝塔面板phpMyAdmin未授权访问漏洞是个低级错误吗?
- GitHub-标签管理
- 经典写配置漏洞与几种变形
- GitLab安装及使用
- 持续集成-Jenkins安装部署
- 谈一谈Linux与suid提权
- PHP动态特性的捕捉与逃逸
- ES6 随性学习之 新增数据类型 Symbol
- 最简单入门深度学习
- 持续集成-Jenkins常用插件安装
- 小白学PyTorch | 15 TF2实现一个简单的服装分类任务
- 小白学PyTorch | 16 TF2读取图片的方法
- 小白学PyTorch | 17 TFrec文件的创建与读取