Kafka教程(三):原理及存储
一、思维导图
1、实时更新连接
https://www.mubucm.com/doc/1GRE2U7qYuj
2、思维导图图片
二、具体内容
- 8.系统架构
- 架构推导
- 拓扑结构
- 多对多
- leader读写,follower同步
- 结构组成
- 分类topic存储数据
- 提高吞吐量,进行分区
- 多副本数据一致性通过leader统领
- 动态选举保证分区可用性
- 通过zk获取集群内的元信息和状态信息
- 通过偏移量获取消息读取位置
- broker
- 一个kafka集群包括多个broker
- 一个server代表一个broker
- 生产者和消费者
- 向broker发消息的客户端叫生产者
- 消费者
- 从broker读消息的客户端叫消费者
- 消费者组
- 单个或多个消费者组成消费者组
- 是实现消息广播(发多个消费者)和单播的手段
- 广播:每个消费者都有独立的cg
- 单播:一个cg包含多个消费者
- 消费到的偏移量之前记录在zookeeper中,现在记录在内置topic中(__consumer_offset)
- 主题和分区
- topic
- 存储数据的逻辑分类(数据库中的表)
- partition
- topic数据的具体管理单元(HBASE中表的region)
- 通过key的哈希桶或轮询方式将消息发送到特定分区
- 好处:数据负载均衡、提高读写并发度和吞吐量
- 分区副本replica
- leader
- 生产者与消费者只能跟leader交互(读写数据)
- 是分区副本replica的角色
- follower
- 又名observer观察者
- 通过心跳信息从leader拉取、复制数据
- leader宕机,则从follower中选举出leader
- 消息偏移量offset
- 是一个自增id,用于定位消息的存储位置
- 只保证一个partition中消息的顺序
- 不保证topic的整体顺序(即多个partition间)
- ISR副本同步列表
- In-Sync Replica
- 每个分区的leader维护一个ISR列表
- 存放跟得上leader的follower副本
- 是否跟得上通过:replica.lag.time.max.ms=10000配置
- leader的同步时间-每个follower的最后一次同步时间
- AR=ISR+OSR
- 条件
- 踢出ISR:参数
- 重新加入:OSR副本的LEO(log end offset)追上leader的LEO
- 数据存储架构
- 整体存储结构
- topic(逻辑)
- partition(物理)
- replica副本
- log日志
- logsegment日志分段
- .log日志文件
- .index偏移量索引文件
- .timeindex时间戳索引文件
- 物理存储目录
- 目录规范
- topic名-分区号
- 如:topic1-0
- 文件规范
- 消息会追加到log末尾,为了避免数据定位效率低下
- 对log文件采取分片+索引机制
- 具体方案
- 每个partition分为多个segment存储
- 每个segment对应.log和.index两个文件
- 以当前segment第一条消息的offset命名
- 索引寻找消息
- 文件名(offset)+偏移量(每个文件从0开始)-》index的索引
- 根据索引确定log中的位置(对应位置上)
- 索引项的密度由log.index.interval.bytes决定
- 常通过二分法定位偏移量的位置
- 消息message存储结构
- API编程中有两个封装类
- ProducerRecord
- ConsumerRecord
- MessageSet下包含多个Message、offset及对应的size
- 校验crc/magic版本/key和value的长度、K和value
- attributes存储压缩编码、时间戳类型
- 9.关键原理加强
- 日志分段切分条件
- 分段文件大小大于1G(log.segment.bytes)
- 文件中消息的最小时间戳与当前时间差值大于log.roll.xxx
- ms(优先级高)
- hours(默认,7天)
- 偏移量或时间戳索引文件大于设定大小
- log.index.size.max.bytes
- 追加消息的偏移量与日志起始偏移量差值大于Integer最大值
- controller控制器
- 概述
- 含义
- kafka集群的状态管理者,是集群中的某个broker
- 维护集群所有分区和副本的状态,以及分区leader的选举
- 负责内容
- 分区leader选举
- ISR变化时,通知broker更新元数据信息
- 增加分区时,负责分区的重新分配
- 位置
- 成功竞选控制器的节点会在zookeeper中创建/controller临时节点
- 节点内容包括:version-1,brokerid,timestamp
- 竞选过程:读取brokerid的值
- 不为-1
- 放弃竞选
- 内存保存当前控制器的brokerid,并标识为activeControllerId
- 为-1
- 多个broker均尝试创建
- 先到先得
- 职责
- 监听partition的变化
- /admin/reassign_partition节点注册监听器,处理topic增减
- isr_change_notification节点注册监听器,处理ISR集合变更
- /admin/prefered-replica-election节点注册监听器,处理优先副本选举
- 监听topic增减变化
- /brokers/topics节点注册监听器,处理topic增减
- /admin/delete_topics注册监听器,处理topic删除
- 监听broker相关变化
- /brokers/ids节点注册监听器,处理broker增减
- 更新集群的元数据信息
- 从zk获取与topic、partition、broker有关信息并进行管理
- 从/brokers/topics/topic节点注册监听器,监听分区分配变化
- 同步最新信息给其他所有broker
- 启动并管理分区状态和副本状态
- 开启定时任务维护分区leader副本的均衡
- 分区的负载分布
- controller负责分区副本在broker上的分配
- 副本因子小于节点数
- 第一个分区leader随机选,其他分区leader依次后移
- 剩余副本相对前一个副本便宜随机数
- 分区leader的选举
- 时机
- 创建分区
- leader下线
- 策略
- AR顺序查找第一个存活的副本,且该副本在ISR集合中
- 生产者原理解析
- 工作流程
- 主线程-消息累加器RecordAccumulator-Sender线程
- 各模块职责
- 主线程由kafkaProducer创建消息,通过拦截器、序列化器、分区器后缓存到消息累加器
- Sender线程从消息累加器中获取消息并发送到kafka
- 消息累加器用来缓存消息,以便Sender可以批量发送,减少传输的资源消耗
- 参数设置
- 缓存大小:buffer.memory,默认32M
- 生产者发送速度大于发送到服务器速度
- 要么被阻塞,要么抛异常
- 通过max.block.ms设置,默认60000
- 结构
- RecordAccumulator
- 每个分区维护一个Deque双端队列
- 写入时,追加到尾部
- 读取时,从头部读取
- 一个消息批次称为一个ProducerBatch,可以凑多为一,通过batch.size决定
- 需要向很多分区发消息,建议调大buffer.memory
- Sender
- 缓存消息结构转换,将分区转换为Node
- 消息还会保存到InFlightRequest,保存发出未响应的请求
- 通过参数设置缓存未响应请求的个数:max.in.flight.request,默认为5
- 消息的应答(确认)机制
- 即:配置消息发送到分区的几个副本才算发送成功
- 通过acks参数决定
- 0
- 通过网络发出去则成功
- 速度快,可能发生错误,大概率丢消息
- 1
- leader收到消息并写入分区数据文件返回确认或错误响应
- 会丢消息:follower同步消息前leader崩溃
- -1/all
- 所有同步副本都收到消息
- 与min.insync.replica结合决定至少多少副本收到消息
- 生产者等待所有副本收到,速度慢
- 只有最小同步副本数大于2,才不会丢数据,负责只有一个leader
- 重要的生产者参数
- max.request.size
- 生产者发送消息最大值,默认1M
- 与其他参数联动(如broker的message.max.bytes)
- retries和retry.backoff.ms
- 配置生产者的重试次数,默认为0
- 存在异常:网络抖动、leader选举
- 后者为重试时间间隔,避免无效的频繁重试
- 保证顺序还需设置in.flight
- compression.type
- 默认不压缩,压缩即空间换时间
- 包含类型:gzip/snappy/lz4
- batch.size
- 凑够批次大小,才会发送消息
- 和吞吐量成正比,和延迟成反比
- linger.ms
- 生产者发送batch前等待更多消息加入的时间
- 在batc填满或时间超过时发送
- 增加延迟,提高吞吐量
- enable.idempotence
- 是否开启幂等性
- 幂等性
- 语句重复做,不影响最终结果
- 如:int i=1/i++,满足&不满足
- 在kafka即,消息发多次只存一次
- partitioner.class
- 指定分区器,默认分区器根据有无key、value进行哈希或轮询
- 自定义分区器需要实现Partitioner接口
- 消费者组再均衡分区分配策略
- 意义:提高数据处理并行度
- 触发
- 新消费者加入cg
- 消费者真/假下线
- 主动退出消费者组,如unsubscribe
- 消费者组节点变更
- 订阅的主题或分区发生变化
- 含义:分区的消费权转移给另一个消费者
- 策略(消费者参数partition.assignment.strategy)
- range(默认)
- partition数/消费者数
- 按区间分配,多出来的给前两个,一开始就多分配
- round robin:TopicPartition按哈希码排序,轮询方式分配
- 新:Sticky Strategy
- 最大化均衡,尽可能保留原有分区
- 先取消自身分区再重新分区
- 新:Cooperative Sticky Strategy
- 最大化均衡,尽可能保留原有分区
- 不会取消所有分区
- 消费者组再均衡流程
- 组内事务协调角色
- 组协调器:Group Coordinator(服务端的某个broker)
- 组长:Group Leader(消费者组中的某个消费者)
- Group Coordinator
- 每个消费者组对应一个Group Coordinator进行管理
- 是kafka服务端用于管理消费者组的组件
- 与消费者客户端的ConsumerCoordinator交互
- 二者的实则是负责执行消费者的Rebalance操作
- 再均衡流程
- eager协议:再均衡发生时,停止所有消费者的工作,取消所有分区
- cooperative协议:把eager的一次全局再均衡,转换成负责分区的小均衡
- eager协议再均衡步骤
- 定位group coordinator组协调器
- 位置:__consumer_offset分区的leader所在broker上
- 先定位其分区号(groupid的哈希码对分区总数50取余)
- 确定分区中leader的broker节点
- 加入组Join The Group
- 消费者组leader选举(随机)
- 选择分区随机策略
- 各消费者支持的分配策略第一个投票,计算选票数作为消费责组策略
- 分区分配策略由Group Coordinator执行
- 组信息同步SYNC Group
- 消费者组leader将分配方案,通过Group Coordinator转发给组内消费者
- 心跳联系Heart Beat
- 消费者正常工作后向协调器Coordinator发送心跳
- 参数
- 心跳间隔时间:heartbeat.interval.ms
- session.timeout.ms
- 再均衡监听器
- 功能:控制消费者发生再均衡时执行特定操作
- 再均衡时,处理消费位移
- 避免再均衡时,重复消费
- 调用subscribe重载方法,内部包含两个方法,分别进行实现
- kafka系统的CAP保证
- 分布式系统的CAP理论
- 内容:三个特性最多满足两个
- 三个特性
- C(consistency):一致性
- 读写一致
- A(availability):可用性
- P(Partition tolerance)分区容错性
- 对kafka来讲,可靠性(分区容错性)和可用性优先考虑,兼顾一致性
- 分区副本机制
- 从0.8.0开始引入分区副本,带来数据冗余
- CAP理论解释:通过副本及动态选举提高了其分区容错性和可用性,但增加了一致性的困难
- 分区副本的数据一致性困难
- 基本手段:follower定期向leader请求数据同步
- 带来数据不一致的场景
- 分区副本读到的offset进度不一致(动态过程中)
- followers副本选举为leader后消费者所见的不一致
- 分区间副本最终数据不一致(选举后写入其他数据,原来leader变为follower)
- 一致性问题解决方案(HW)
- 核心思想
- 维护步进式的临时一致线(High Watermark)
- 高水位线HW=ISR副本中的最小LEO
- offset<HW,是各副本间一致且安全的(所有副本已备份好的数据)
- 问题解决
- 消费者所见不一致:只允许看到HW以下的message
- 分区副本数据最终不一致:根据新leader的HW对数据阶段,保证与新leader的数据一致
- HW方案的天生缺陷
- leader和follower进行RPC通信更新LEO和HW时,需要额外一轮请求才能完成更新
- 在leader切换过程中,存在丢数和不一致的问题
- Leader-Epoch-checkpoint机制引入
- 格式:epoch,offset,epoch为leader的版本,递增
- 副本成为leader,更新epoch和LEO;成为follower请求最新epoch,一致则取leader的LEO
- 可以解决HW的数据丢失、数据最终不一致问题
- LEO/HW/LSO术语
- LEO-最大偏移量,LSO-最后一个稳定的偏移量
- HW-各副本LEO最小值,LW-副本中最小偏移量
- 不清洁选举
- 非ISR副本可以选举为leader,由unclean.leader.election.enable控制
- 会产生数据丢失及不一致问题
Kafka教程(三):原理及存储的更多相关文章
- kafka 教程(四)-原理进阶
kafka 最初由 Linkedin 公司开发,是一个 分布式.支持分区.多副本的,基于 zookeeper 协调的分布式发布订阅消息系统,该公司在 2010 年将 kafka 贡献给 apache ...
- kafka 教程(三)-远程访问
远程连接 kafka 配置 默认的 kafka 配置是无法远程访问的,解决该问题有几个方案. 方案1 advertised.listeners=PLAINTEXT://IP:9092 注意必须是 ip ...
- Kafka数据安全性、运行原理、存储
直接贴面试题: 怎么保证数据 kafka 里的数据安全? 答: 生产者数据的不丢失kafka 的 ack 机制: 在 kafka 发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够 ...
- 深入剖析kafka架构内部原理
1 概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Cl ...
- kafka集群原理介绍
目录 kafka集群原理介绍 (一)基础理论 二.配置文件 三.错误处理 kafka集群原理介绍 @(博客文章)[kafka|大数据] 本系统文章共三篇,分别为 1.kafka集群原理介绍了以下几个方 ...
- 《转载》仅需3分钟,你就能明白Kafka的工作原理
仅需3分钟,你就能明白Kafka的工作原理 周末无聊刷着手机,某宝网 App 突然蹦出来一条消息“为了回馈老客户,女朋友买一送一,活动仅限今天!”. 买一送一还有这种好事,那我可不能错过!忍不住立马点 ...
- kafka如何实现高并发存储-如何找到一条需要消费的数据(阿里)
阿里太注重原理了:阿里问kafka如何实现高并发存储-如何找到一条需要消费的数据,kafka用了稀疏索引的方式,使用了二分查找法,其实很多索引都是二分查找法 二分查找法的时间复杂度:O(logn) ...
- Windows OS上安装运行Apache Kafka教程
Windows OS上安装运行Apache Kafka教程 下面是分步指南,教你如何在Windows OS上安装运行Apache Zookeeper和Apache Kafka. 简介 本文讲述了如何在 ...
- Kafka 设计与原理详解
一.Kafka简介 本文综合了我之前写的kafka相关文章,可作为一个全面了解学习kafka的培训学习资料. 转载请注明出处 : 本文链接 1.1 背景历史 当今社会各种应用系统诸如商业.社交.搜索. ...
- Fastify 系列教程三 (验证、序列化和生命周期)
Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) Fastify 系列教程三 (验证.序列化和生命周期) 验证 Fast ...
随机推荐
- (一)JPA的快速入门
JPA简介 JPA是什么 JPA 是Java Persistence API的缩写,是一套由Java官方制定的ORM标准.当制定这套标准以后,市场上就出现很多JPA框架.如:OpenJPA(apach ...
- Django 使用cmd 创建工程
一.Django 安装 1 通过pip安装 Django 如果你是通过升级的方式安装Django,那么你需要先卸载旧的版本. Django 提供3种发行版本,推荐使用官方的稳定版本: 你的操作系统提供 ...
- 1.通俗易懂理解Kubernetes核心组件及原理
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483736&idx=1&sn=0cbc3d6a ...
- 2. Fluentd事件的生命周期
事件(Event)是Fluentd内部处理流程使用的数据结构,日志记录一旦进入Fluentd便被封装成一个event.Event由三部分组成:tag.time.record. tag: 标识事件的来源 ...
- 1_Maven
一. 引言 1.1 项目管理问题 项目中jar包资源越来越多, jar包的管理越来越沉重 1.1.1 繁琐 要为每个项目手动导入所需的jar, 需要搜集全部的jar 1.1.2 复杂 项目中的jar如 ...
- 手把手教你使用LabVIEW OpenCV dnn实现图像分类(含源码)
@ 目录 前言 一.什么是图像分类? 1.图像分类的概念 2.MobileNet简介 二.使用python实现图像分类(py_to_py_ssd_mobilenet.py) 1.获取预训练模型 2.使 ...
- Nginx代理和动静分离
Nginx代理 微服务项目可能需要 Nginx来实现反向代理,用户请求 Nginx,随后 Nginx将请求转发至 Gateway网关,再由网关转至具体的微服务 一.动态代理 1.1 网关配置 针对使用 ...
- Go_Goroutine详解
Goroutine详解 goroutine的概念类似于线程,但 goroutine是由Go的运行时(runtime)调度和管理的.Go程序会智能地将 goroutine 中的任务合理地分配给每个CPU ...
- map集合类型/实体类类型的参数
map集合类型的参数 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合, 将这些数据放在map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要 ...
- UDP协议的网络编程
public class UDPTest { //发送端@Testpublic void sender() throws IOException { DatagramSocket socket = n ...