kafka
2021-01-31 14:34:31 2 举报
AI智能生成
登录查看完整内容
kafka
作者其他创作
大纲/内容
kafka
基础
分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统)
主要设计目标
以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能
高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输
支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输
Kafka保证一个Partition内的消息的有序性
同时支持离线数据处理和实时数据处理。
支持在线水平扩展
架构图
组件
Broker
每台机器定义为一个Broker
Topic
无论何种类型的消息统一定义为Topic类,topic即消息的容器
消息的逻辑分区
Partition
存放消息的容器
消息的物理分区
分区有leader和follwer节点,follower节点为数据备份,通过zk维护可用性
Producer
消息的生产者
生产者发布消息时根据消息是否有键,采用不同的分区策略
消息没有键时,通过轮询方式进行客户端负载均衡
消息有键时,根据分区语义(例如hash)确保相同键的消息总是发送到同一分区
Consumer
消息消费者
offset由Consumer控制
Kafka broker是无状态的,它不需要标记哪些消息被哪些消费过,也不需要通过broker去保证同一个Consumer Group只有一个Consumer能消费某一条消息,因此也就不需要锁机制,这也为Kafka的高吞吐率提供了有力保障
Consumer Group
消费者组,实现单播和广播
实现广播,只要每个consumer有一个独立的Consumer Group就可以了
实现单播只要所有的consumer在同一个Consumer Group
延时时间轮的应用
双向环形链表,插入和删除的时间复杂度O(1)
JDK的Timer和DelayQueue插入和删除操作的平均时间复杂度为O(nlog(n))
延迟生产、延迟拉取以及延迟删除
性能高的原因
磁盘顺序写
磁盘写慢的原因是因为随机写需要寻址,寻址速度很慢
文件末尾按照顺序的方式来写数据的话,那么这种磁盘顺序写的性能基本上可以跟写内存的性能本身也是差不多的不允许修改
持久化消息落盘
优点
解耦消息生产者和消费者,中转存消息
灵活的消息处理,可以对已经处理过的消息重放
所有数据写的时候会立即写入文件系统的持久化日志才返回成功。减少对内存的消耗,将内存留给页缓存,提高整体体验
页缓存
操作系统本身的缓存page cache
Page Cache把磁盘中的数据缓存到内存,把对磁盘的访问改为对内存的访问
kafka对页缓存写操作,然后系统定时会将页缓存刷盘
可以配置每次写页缓存,flush刷盘,保证数据不丢失
# 当达到下面的消息数量时,会将数据flush到日志文件中。默认10000#log.flush.interval.messages=10000# 当达到下面的时间(ms)时,执行一次强制的flush操作。interval.ms和interval.messages无论哪个达到,都会flush。默认3000ms#log.flush.interval.ms=1000# 检查是否需要将日志flush的时间间隔log.flush.scheduler.interval.ms = 3000
繁琐的io操作交给系统处理
零拷贝方式
传统方式
从磁盘读出数据->内核空间->用户空间,然后用户空间再写数据->内核空间的socket缓冲区->网卡设备协议引擎
4次数据拷贝
零拷贝
从磁盘读出数据->内核空间->socket缓冲区
本质
将两个文件描述符关联
in_fd必须是一个支持类似mmap函数的文件描述符,即它必须指向真实的文件,不能是socket和管道,而out_fd必须是一socket
1、系统调用 sendfile() 通过 DMA (直接存储器访问)把硬盘数据拷贝到 kernel buffer,然后数据被 kernel 直接拷贝到另外一个与 socket 相关的 kernel buffer。这里没有 用户态和核心态 之间的切换,在内核中直接完成了从一个 buffer 到另一个 buffer 的拷贝。
2、DMA 把数据从 kernel buffer 直接拷贝给协议栈,没有切换,也不需要数据从用户态和核心态,因为数据就在 kernel 里
读取数据,如果页缓存有直接发送到网络的socket
批量处理
客户端buffer批量发送
broker批量写
消息不丢失
生产者丢失消息
生产者网络抖动,发送消息超出大小限制等原因发送失败
producer.send(Object msg) ; 异步发送消息,发送而不管结果如何
font color=\"#c41230\
网络抖动: 重发
发送消息超出大小:调整消息大小进行发送
消费者丢失消息
先更新位移,再消费消息,如果消费程序出现故障,没消费完毕,则丢失了消息
先消费消息,再更新位移;这种可能带来消息重复消费的问题,但是不会出现消息丢失问题;需要做幂等处理
多线程消费丢失消息,开启了自动位移提交,线程处理失败但是更新了位移
关闭自动提交位移,消费者端配置参数:enable.auto.commit=false
调优broker参数防止消息丢失
消费者端
生产者端
acks=all即配置所有的partition副本都收到消息了才返回提交成功
retries=N即出现问题比如网络抖动的重试次数
broker端
replication.factor>=3消息分区的副本数多少个
min.insync.replicas>1消息写入多少个副本才算已提交
broker
日志文件
日志以分区为单位,每个分区都有自己的日志文件,分区日志
.log
真是的kafka消息记录
使用该文件的第一条记录的offset来命令该文件
文件大小默认最大1G
.index
位移索引文件
索引文件默认最大10M
.timeindex
时间戳索引文件
索引文件有序,可以根据索引文件二分查找
默认会清除7天前的日志文件
0 条评论
回复 删除
下一页