kafak学习总结
高可用
多副本机制: 主副本和从副本,从副本只负责同步主副本数据,只有主副本进行读写。
高并发
网络结构设计
多路复用
多selector -> 多线程-> 多队列
高性能
写
- 把数据先写入os cache
- 然后顺序写入磁盘
读
- 根据稀疏索引快速定位到要消费消息
- 零拷贝机制,减少上下文切换和cpu拷贝
如何提高吞吐量
- 设置缓存区数据量
- 开启压缩
- 设置合适批大小batch.size, 太小网络请求频繁,太大导致发送消息慢
重试机制带来问题
- 消息会重复: 幂等支持
- 消息乱序:
max.in.flight.requests.per.connection
=1 producer 同一时间只能发送一条消息,默认重试间隔:retry.backoff.ms
=100
偏移量管理
每个consumer内存里数据结构保存对每个topic的每个分区的消费offset,定期会提交offset,老kafak写入zookeeper
(废弃)。
提交offset发送给kafka
内部topic:__consumer_offsets,提交过去的时候, key是group.id
+topic+分区号,value就是当前offset的值,每隔一段时间,kafka
内部会对这个topic进行compact(合并),也就是每个group.id
+topic+分区号就保留最新数据
消费异常感知
heartbeat.interval.ms:consumer
心跳时间间隔,必须得与coordinator保持心跳才能知道consumer是否故障了, 然后如果故障之后,就会通过心跳下发rebalance
的指令给其他的consumer通知他们进行rebalance
的操作session.timeout.ms
:kafka
多长时间感知不到一个consumer就认为他故障了,默认是10max.poll.interval.ms
:如果在两次poll操作之间,超过了这个时间,那么就会认为这个consume处理能力太弱了,会被踢出消费组,分区分配给别人去消费,一般来说结合业务处理的性能来设置就可以了。
消费者是如何实现rebalance的?
根据coordinator实现
- 什么是coordinator 每个consumer group都会选择一个broker作为自己的coordinator,他是负责监控这个消费组里的各个消费者的心跳,以及判断是否宕机,然后开启rebalance的
如何选择coordinator机器 首先对groupId进行hash(数字),接着对__consumer_offsets的分区数量取模,默认是50,_consumer_offsets的分区数可以通过offsets.topic.num.partitions来设置,找到分区以后,这个分区所在的broker机器就是coordinator机器。比如说:groupId,“myconsumer_group” -> hash值(数字)-> 对50取模 -> 8 __consumer_offsets 这个主题的8号分区在哪台broker上面,那一台就是coordinator 就知道这个consumer group下的所有的消费者提交offset的时候是往哪个分区去提交offset,
(1)每个consumer都发送
JoinGroup
请求到Coordinator,然后Coordinator从一个consumer group中选择一个consumer作为leader(第一个),Coordinator把consumer group情况发送给这个leader,leader定制消费方案,通过SyncGroup发给Coordinator,接着Coordinator就把消费方案下发给各个consumer,他们会从指定的分区的 leader broker开始进行socket连接以及消费消息。
谈谈Kafka客户端如何巧妙解决JVM GC问题?
1. Kafka 客户端缓冲机制
kafak Produer 流程
1)进行 Producer 初始化,加载配置参数,开启网络线程。
2)执行拦截器逻辑,预处理消息, 封装 Producer Record。
3)调用 Serializer.serialize() 方法进行消息的 key/value 序列化。
4)调用 partition() 选择合适的分区策略,给消息体 Producer Record 分配要发送的 Topic 分区号。
5)从 Kafka Broker 集群获取集群元数据 metadata。
6)将消息缓存到 RecordAccumulator 收集器中, 最后判断是否要发送。这个加入消息收集器,首先得从 Deque<RecordBatch> 里找到自己的目标分区,如果没有就新建一个 Batch 消息 Deque 加进入。
7)当达到发送阈值,唤醒 Sender 线程,实例化 NetWorkClient 将 batch record 转换成 request client 的发送消息体, 并将待发送的数据按 【Broker Id <=> List】的数据进行归类。
8)与服务端不同的 Broker 建立网络连接,将对应 Broker 待发送的消息 List 发送出去。
9)批次发送的条件为: 缓冲区数据大小达到 batch.size 或者 linger.ms 达到上限,哪个先达到就算哪个。
Kafka 实现的缓冲机制 ,减少垃圾回收,降低STW
在 Kafka 客户端内部,针对这个问题实现了一个非常优秀的机制,就是「缓冲池机制」。即每个 Batch 底层都对应一块内存空间,这个内存空间就是专门用来存放写进去的消息。 |
kafka
开启精确发送一次
通过引入「PID
及Sequence Number」支持幂等性,保证精确一次「exactly once」语义。
其中启用幂等传递的方法配置:enable.idempotence
= true。启用事务支持的方法配置:设置属性 transcational.id
= “指定值”。
谈谈你对Kafka控制器及选举机制是如何理解
所谓的控制器「Controller」就是通过 ZooKeeper 来管理和协调整个 Kafka 集群的组件。集群中任意一台 Broker 都可以充当控制器的角色,但是在正常运行过程中,只能有一个 Broker 成为控制器。
控制器的职责主要包括:
1)集群元信息管理及更新同步 (Topic路由信息等)。
2)主题管理(创建、删除、增加分区等)。
3)分区重新分配。
4)副本故障转移、 Leader 选举、ISR 变更。
5)集群成员管理(通过 watch 机制自动检测新增 Broker、Broker 主动关闭、Broker 宕机等)。
在2.x中 zookeeper作用: 帮助kafka选择controller ,通知controller节点关闭或者加入
Kafka 3.X 版本中,内部实现一个类似于 Raft 的共识算法来选举 Controller
HW 和LEO 理解
HW 作用:
1)用来标识分区下的哪些消息是可以被消费者消费的。
2)协助 Kafka 完成副本数据同步。
LEO 作用:
1)如果 Follower 和 Leader 的 LEO 数据同步了, 那么 HW 就可以更新了。
2)HW 之前的消息数据对消费者是可见的,属于 commited 状态, HW 之后的消息数据对消费者是不可见的。
谈谈 Kafka 消息分配策略都有哪些?
RangeAssignor 是 Kafka 默认的分区分配算法,它是按照 Topic 的维度进行分配的,首先对 每个Topic 的 Partition 按照分区ID进行排序,然后对订阅该 Topic 的 Consumer Group 的 Consumer 按名称字典进行排序,之后尽量均衡的按照范围区段将分区分配给 Consumer。此时也可能会造成先分配分区的 Consumer 任务过重(分区数无法被消费者数量整除)
RoundRobinAssignor:
该分区分配策略是将 Consumer Group 订阅的所有 Topic 的 Partition 及所有 Consumer 按照字典进行排序后尽量均衡的挨个进行分配。如果 Consumer Group 内,每个 Consumer 订阅都订阅了相同的Topic,那么分配结果是均衡的。如果订阅 Topic 是不同的,那么分配结果是不保证「 尽量均衡」的,因为某些 Consumer 可能不参与一些 Topic 的分配
StickyAssignor
该分区分配算法是最复杂的一种,可以通过 partition.assignment.strategy 参数去设置,从 0.11 版本开始引入,目的就是在执行新分配时,尽量在上一次分配结果上少做调整,其主要实现了以下2个目标:
1、Topic Partition 的分配要尽量均衡。
2、当 Rebalance 发生时,尽量与上一次分配结果保持一致。
Rebalance 触发后如何通知其他 Consumer 进程?
1 |
rebalance 的通知机制就是靠 Consumer 端的心跳线程,它会定期发送心跳请求到 Broker 端的 Coordinator 协调者组件,当协调者决定开启 Rebalance 后,它会将「REBALANCE_IN_PROGRESS」封装进心跳请求的响应中发送给 Consumer ,当 Consumer 发现心跳响应中包含了「REBALANCE_IN_PROGRESS」,就知道是 Rebalance 开始了。 |
谈谈Kafka线上大量消息积压你是如何处理的?
事前:
- 避免大消息发送
- 分区数和消费组数尽量相等
- 优化消费端逻辑,避免重平衡
kafak学习总结的更多相关文章
- kafak学习(一)
发布与订阅消息系统. 数据(消息)的发送者不会直接把消息发送给接受者,这是发布与订阅消息系统的一个特点.发布者以某种方式对消息进行分类,接受者订阅他们,以便接受特定类型的消息.发布与订阅系统一般会有一 ...
- 【Spark深入学习 -10】基于spark构建企业级流处理系统
----本节内容------- 1.流式处理系统背景 1.1 技术背景 1.2 Spark技术很火 2.流式处理技术介绍 2.1流式处理技术概念 2.2流式处理应用场景 2.3流式处理系统分类 3.流 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
随机推荐
- 前端 - JaveScrip
今日内容 JS简介 全程JaveScript但是与Jave没有关系 知识为了蹭Jave热度 它是一门前端工程师的编程语言 但是它本身有很多逻辑错误 IT行业鄙视链:前端.运维.测试.产品 前端想一统天 ...
- AI换脸实战教学(FaceSwap的使用)---------第二步Tools:处理输入数据集。
续上篇:https://www.cnblogs.com/techs-wenzhe/p/12936809.html 第一步中已经提取出了源视频的人脸照片以及对应人脸遮罩(landmark以及其他自选遮罩 ...
- Google Cloud Spanner 究竟是什么?
谷歌于2017年推出的Google Cloud Spanner,原是谷歌内部使用的一个数据服务,后来又成为了谷歌云平台上搭建的数据库服务. Google Cloud Spanner 是一种数据库,它结 ...
- 编程思想转换-Lambda表达式
编程思想转换 做什么,而不是怎么做 我们真的希望创建一个匿名内部类对象吗?不.我们只是为了做这件事情而不得不创建一个对象.我们真正希望做的事情是︰将run方法体内的代码传递给 Thread类知晓. 传 ...
- Spring中常见的注解
1.组件注解 @Controller @Service @Repository @Component ---标注一个类为Spring容器的Bean @Configration ---声明当前类为配置类 ...
- sqlserver数据库批量新增修改类
MSSql Server 数据库批量操作 需要引用的命名空间 using System; using System.Collections.Generic; using System.Data; us ...
- .net core 前端传递参数有值 后端接收到的数据却是null
1.问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2.解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比 ...
- 《爆肝整理》保姆级系列教程-玩转Charles抓包神器教程(7)-Charles苹果手机手机抓包知否知否?
1.简介 Charles和Fiddler一样不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求. Charles也能截获iOS设备发出的请求,比如 i ...
- Redis 源码解读之 Rehash 的调用时机
Redis 源码解读之 Rehash 的调用时机 背景和问题 本文想要解决的问题 什么时机触发 Rehash 操作? 什么时机实际执行 Rehash 函数? 结论 什么时机触发 Rehash 操作? ...
- 【KAWAKO】soundtoch-使用可执行文件对音频进行变调或变速
目录 下载 单次使用 使用python脚本批量处理 下载 从官网下载可执行文件. 单次使用 在终端中直接运行,会出现使用方法和可选参数. 变速就设置tempo,变调就设置pitch,都变就都设置.变速 ...