一文吃透kafka
2024-08-01 21:02:03 0 举报
AI智能生成
kafka深度学习后总结整理,覆盖常见kafka面试题,包括应用场景,重要概念,架构设计,原理分析,高可用,常见面试题等部分,后续会不断调整优化
作者其他创作
大纲/内容
使用场景
消息传递
网站活动跟踪,把用户活动发布到数据管道中,可以用来做监控、实时处理、报表等
日志聚合
Metrics应用指标监控,可以用来记录运营数据
数据集成:把kafka数据导入Hadoop、HBase等离线数据仓库
流计算集成:非静态数据,没有边界的,源源不断产生的数据
集成canal实现数据同步(canal把自己伪装成slave,支持binlog增量订阅)
安装与命令
版本说明:kafka_2.12-2.60.tgz 前面是scala版本,后面是kafka版本
环境:JDK、ZK
利用ZK的有序节点、临时节点和监听机制帮kafka做了如下事情:
配置中心、负责均衡、命名服务、分布式通知、集群管理和选举、分布式锁
脚本介绍
架构分析
重要概念
Broker
Kafka集群包含一个或多个服务器,这种服务器被称为broker。broker端不维护数据的消费状态,提升
了性能。直接使用磁盘进行存储,线性读写,速度快:避免了数据在JVM内存和系统内存之间的复制,
减少耗性能的创建对象和垃圾回收
Producer
负责发布消息到Kafka broker
批量发送,batch.size:16384,等待时间到也会发
Consumer
消息消费者,向Kafka broker读取消息的客户端,consumer从broker拉取(pull)数据并进行处理
rabbitmq支持push和pull,kafka仅支持pull(考虑到生产速度远远大于消费速度)
max.poll.records,默认500
Topic
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
KV键值对,传输过程需要序列化
一个生产者可以发送多个Topic,一个Topic也可以有多个消费者
Partition
Parition是物理上的概念,每个Topic包含一个或多个Partition,对应物理一个目录,横向扩展,分片
replication-factor主题的副本数,必须在不同的broker,读写消息仅针对leader
segment
partition细分单位,提高检索数据效率,保存实际消息日志和索引(至少一个数据文件和2个索引文件,成套出现)
默认大小1G, log.segment.bytes
Consumer Offset:记录着下一条将要发送给consumer的消息的序号(偏移量)
Consumer Group
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group),同一组中的消费者不能消费相同的消息
Topic & Partition
Topic在逻辑上可以被认为是一个queue,每条消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件
Java API
Producer API
用于应用将数据发送至Kafka的topic
Consumer API
用于应用从Kafka的topic中读取数据流
Admin API
允许管理和检测Topic 、broker以及其他Kafka实例,与kafka自带的脚本命令类似
Streams API
用于从来源topic转化到目的topic转换数据流,作用跟Spark、Storm、Flink一样
Connect API
用于持续地从一些源系统输入数据到Kafka,或者从Kafka推送数据到一些系统,比如数据库或者Hadoop
进阶功能
幂等性
enable.idempotence:true,producer自动升级成幂等性
每个生产者一个唯一编号,每个消息一个序列号,同topic同分区有效,重启失效
事务消息
2PC,如果大家都可以提交则提交,否则回滚
步骤:
A:生产者通过initTransaction API向Coordinator注册事务ID
B:Coordinator 记录事务日志
C:生产者把消息写入目标分区
D:分区和Coordinator交互,当事务完成以后,消息的状态应该是已提交,这样消费者才可以消费到
与rabbit对比
产品侧重:kafka流式消息处理、消息引擎;RabbitMQ 消息代理
性能:kafka有更高的吞吐量,每秒几十万,延迟几ms,rabbit几万
方式:Rabbit push和pull,kafka只有pull
消息顺序:分区里的消息是有序的,同一个consumer group里面的消费者只能消费一个partition
消息的路由和分发:RabbitMq更加灵活
延迟消息,死信队列:RabbitMQ支持
消息的留存:kafka消费完后消息会留存,RabbitMQ消费完就会删除
消息复制和可用性:Kafka 允许配置多个消息副本,确保数据的冗余存储,提高可用性和容错性。RabbitMQ 也支持镜像队列以实现冗余,但是不如 Kafka 的多副本复制灵活。
社区和生态系统:Kafka 有一个更庞大的社区和丰富的生态系统
kafka原理
生产者原理
拦截器
实现消息的定制化,可以多个
序列化器
用指定工具对key和value进行序列化,可自定义
分区器
可指定patition或自定义分区器,仅有key时将keyhash值与topic的patition数据取余
消息累加器
选择了分区后并不是马上发送,会将消息放入ConcurrentMap,满了以后再发送
ACK应答3种机制,性能依次递减,数据健壮性依次递增
ISR:in-sync replica set 保持同步的副本集合
replica.lag.time.max.ms,默认值30s,超过此值未同步则将副本踢出ISR
0:不等待;
1:等待broker的ack ;默认
-1(all):leader和follower(ISR)全部落盘成功)
1:等待broker的ack ;默认
-1(all):leader和follower(ISR)全部落盘成功)
类比:MySQL的binlog主从复制-同步、半同步、异步
Broker存储原理
logs.dir:/tmp/kafka-logs
pation:横向扩展:一个topic分隔为多个partition,可以放在不同broker上,每个partion都有一个物理目录,topic名字后面的数字标识代表分区,v如 mytopic-1
replica
副本数量必须<=broker节点数;
为啥不读写分离:读写都在leader节点就不存在主从一致性问题,这个叫单调读一致性
副本在Broker的分布
第一个分区的第一个副本位置随机选;其他分区的第一个副本位置依次往后移,蛇形走位
提高容灾效果
一个分区的两个副本不能在一个broker上
segment
防止log文件过大,导致检索效率变低,一个patition被分成多个segment
组成
一个log文件(切分条件)
满足条件就新建log.segment.bytes(默认1G)
log.roll.hours=168(优先使用更加精细的时间单位如log.roll.ms)
索引文件达到一定大小,默认10m
偏移量索引文件:记录的是offset和消息物理地址(在log文件中的位置),稀疏索引,用消息的大小来控制,默认为4KB,
时间戳索引文件:记录的是时间戳和offset的关系;场景:可以基于时间切分日志或清理日志;默认是生产时间
基于索引如何快速检索
1.消息是带有分区信息的
2.segment命名为base offset,可用二分法快速确定
3.到对应索引文件中找到offset对应的position
4.到对应日志文件中找到消息
消息保留机制
删除策略(log.cleanup.policy:delete)默认
通过定时任务删除老数据
log.retention.check.interval.ms=300000(默认5分钟)
log.retention.hours:168(默认 1周)
对于生产消息速度不均匀时可以根据日志大小删除
压缩整理:把相同Key合并为最后一个value
高可用架构
Controller
选举:所有的Broker会尝试在zookeeper中创建临时节点/controller,只有一个能创建成功(先到先得)
zookeeper特点:1watch机制 2临时节点 3节点不允许重复写入
职责:
监听broker、topic、partition变化
获取和管理broker、topic、partion信息
管理partition主从信息,指挥副本leader选择工作
监听broker、topic、partition变化
获取和管理broker、topic、partion信息
管理partition主从信息,指挥副本leader选择工作
分区副本leader选举
AR(Assigned-Replicas)=ISR(In-Sync Replicas)+OSR(Out-Sync Replicas)
ZAB(ZK);缺点:节点不互通情况下出现多个leader脑裂
Raft(Redis Sentinel)
kafka:第一个副本变成leader-优先继承权
主从同步
LEO(Log End Offset):下一条等待写入的消息的offset
HW(Hign Watermark):ISR中最小的LEO,consumer只能消费hw之前的消息,要不消费组的offset容易偏大,leader挂时容易丢消息
1.follwer节点向Leader发送一个fetch请求,leader向follower发送数据后,即需要更新follower的LEO
2.follower接收到数据响应后,依次写入消息并且更新LEO
3.leader更新HW
replica故障处理
follower故障:首先被跳出ISR,恢复之后根据之前记录的HW,把高于HW的信息删除,然后向leader同步,重新加入ISR
leader故障,按优先继承选一个leader,为保证数据一致性,其他的follower需要把高于HW的消息截取掉
消费者原理
Offset的维护
offset存储:不会删除,追加,顺序写入
消费者组和partition偏移量关系
保存位置-特殊topic:_consumer_offsets
消费者的消费策略
消费者和分区关系
相等最好,一个消费者对应一个分区
分区多,一个消费者必须消费多个分区
范围
轮询
粘滞
分区少,有些消费者空闲
assign
指定分区消费
subscribe
自动分配消费者分区
rebalance(分区重分配)
消费者组的消费者发生变化
topic的分区数发生变更
为什么这么快
顺序I/O:读写的数据在磁盘上是集中的,不需要重复寻址过程 ,kafka的消息是不断追加到本地磁盘文件末尾的
一定条件下磁盘的顺序读写比内存随机读写要快
Memory Mapped Files
即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。所以 Kafka 的数据并不是实时的写入硬盘 ,它充分利用了现代操作系统分页存储来利用内存提高 I/O 效率
索引,偏移量索引和时间索引
批量读写和文件压缩
分区多partition
零拷贝
零拷贝并不是不需要拷贝,而是减少不必要的拷贝次数
传统IO
第一次:将磁盘文件,读取到操作系统内核缓冲区;
第二次:将内核缓冲区的数据,copy 到 application 应用程序的 buffer;
第三步:将 application 应用程序 buffer 中的数据,copy 到 socket 网络发送缓冲区(属于操作系统内核的缓冲区);
第四次:将 socket buffer 的数据,copy 到网卡,由网卡进行网络传输
第二次:将内核缓冲区的数据,copy 到 application 应用程序的 buffer;
第三步:将 application 应用程序 buffer 中的数据,copy 到 socket 网络发送缓冲区(属于操作系统内核的缓冲区);
第四次:将 socket buffer 的数据,copy 到网卡,由网卡进行网络传输
linux系统 sendfile()方法
sendfile主要依赖于 DMA 数据传输技术,采用一组单独的指令集来负责数据在内存不同区域之间的拷贝过程。这样就不再需要 CPU 来进行复制,从而减少 CPU 性能消耗,让 CPU 可以用于更重要的计算任务。sendfile通常适合于大文件的拷贝传输操作,Kafka 大量的运用 sendfile 机制,加速消息从 Partition 文件到网卡的传输过程。
Memory Mapped Files
mmap机制主要依赖于内存区域映射技术,可以减少一次 IO 操作中,内核态与用户态之间的数据传输,从而减少因为上下文切换而带来的 CPU 性能开销。mmap机制通常适合于对大量小文件的 IO 操作,Kafka 大量的运用 mmap 机制加速 Partition 日志文件的读写过程。
面试题
消息积压
消费能力弱
增加消费者数量:增加消费者实例来加快消息处理速度。
增加消费者的并行处理能力:提高单个消费者的处理能力,例如通过增加线程数或者使用更强的处理器。
调整消费者的消费速率:可以通过调整max.poll.records配置来控制每次poll调用返回的记录数量。
增加Kafka分区数:增加主题分区可以并行处理更多消息。
使用消息压缩:压缩发送到Kafka的消息可以减少带宽使用。
清理Kafka主题:定期清理不需要的消息来减少积压。
增加消费者的并行处理能力:提高单个消费者的处理能力,例如通过增加线程数或者使用更强的处理器。
调整消费者的消费速率:可以通过调整max.poll.records配置来控制每次poll调用返回的记录数量。
增加Kafka分区数:增加主题分区可以并行处理更多消息。
使用消息压缩:压缩发送到Kafka的消息可以减少带宽使用。
清理Kafka主题:定期清理不需要的消息来减少积压。
生产能力强
如何保障消息可靠
数据冗余:Kafka通过将消息副本(replica)的方式来实现数据冗余,每个topic都可以配置副本数量。在 Kafka 中,针对每个 Partition,会选举产生一个 Leader 节点,负责响应客户端的请求,并优先保存消息。而其他节点则作为 Follower 节点,负责备份 Master 节点上的消息。
消息发送确认机制:Kafka支持对生产者发送过来的数据进行校验,以检查数据的完整性。可以通过设置生产者端的参数(例如:acks)来配置校验方式。配置为 0,则不校验生产者发送的消息是否写入 Broker。配置为 1,则只要消息在 Leader 节点上写入成功后就向生产者返回确认信息。配置为-1 或 all,则会等所有 Broker 节点上写入完成后才向生产者返回确认信息。
ISR机制:针对每个 Partition,Kafka 会维护一个 ISR 列表,里面记录当前处于同步状态的所有Partition。并通过 ISR 机制确保消息不会Master 故障时丢失。
消息持久化:Kafka将消息写入到磁盘上,而不是仅在内存中缓存。这样可以保证即使在系统崩溃的情况下,消息也不会丢失。并且使用零拷贝技术提高消息持久化的性能。
消费者确认机制:Kafka消费者在处理完消息后会向Kafka broker发送确认消息,表示消息已经被成功处理。如果消费者未发送确认消息,则Kafka broker会保留消息并等待消费者再次拉取。这样可以保证消息被正确处理且不会重复消费。
0 条评论
下一页
为你推荐
查看更多