Kafka日志存储

摘要:
并不是每条消息都有自己的索引,kafka采用的是稀疏索引,说白了就是隔n条消息存一条索引数据。此例中我们假设跨度为2,实际kafka中跨度并不是固定条数,而是取决于消息累积字节数大小。

1.文件目录布局

Kafka消息以日志文件的形式存储,不同主题下不同分区的消息分开存储,同一个分区的不同副本分布在不同的broker上存储

逻辑上看来日志是以副本为单位的,每个副本对应一个log对象,实际在物理上,一个log划分为多个logSegment

创建一个topic为3个分区,会在log.dirs路径下创建三个文件夹,代表3个分区,命名规则为“topic名称-分区编号”

logSegment并不代表这个文件夹,logSegment代表逻辑上的一组文件,这组文件就是.log、.index、.timeindex这三个不同文件扩展名,但是同文件名的文件

  • .log存储消息
  • .index存储消息的索引
  • .timeIndex,时间索引文件,通过时间戳做索引

同一个logSegment的三个文件,文件名是一样的。命名规则为.log文件中第一条消息的前一条消息偏移量,也称为基础偏移量,左边补0,补齐20位。比如说第一个LogSegement的日志文件名为00000000000000000000.log,假如存储了200条消息后,达到了log.segment.bytes配置的阈值(默认1个G),那么将会创建新的logSegment,文件名为00000000000000000200.log。以此类推。另外即使没有达到log.segment.bytes的阈值,而是达到了log.roll.ms或者log.roll.hours设置的时间触发阈值,同样会触发产生新的logSegment。

2.日志定位

日志定位也就是消息定位,输入一个消息的offset,kafka如何定位到这条消息呢?

日志定位的过程如下:

1、根据offset定位logSegment。(kafka将基础偏移量也就是logsegment的名称作为key存在concurrentSkipListMap中)

2、根据logSegment的index文件查找到距离目标offset最近的被索引的offset的position x。

3、找到logSegment的.log文件中的x位置,向下逐条查找,找到目标offset的消息。
Kafka日志存储第1张

这里先说明一下.index文件的存储方式。.index文件中存储了消息的索引,存储内容是消息的offset及物理位置position。并不是每条消息都有自己的索引,kafka采用的是稀疏索引,说白了就是隔n条消息存一条索引数据。这样做比每一条消息都建索引,查找起来会慢,但是也极大的节省了存储空间。此例中我们假设跨度为2,实际kafka中跨度并不是固定条数,而是取决于消息累积字节数大小。

例子中consumer要消费offset=15的消息。我们假设目前可供消费的消息已经存储了三个logsegment,分别是00000000000000000,0000000000000000010,0000000000000000020。为了讲解方便,下面提到名称时,会把前面零去掉。

下面我们详细讲一下查找过程。

  • kafka收到查询offset=15的消息请求后,通过二分查找,从concurrentSkipListMap中找到对应的logsegment名称,也就是10。
  • 从10.index中找到offset小于等于15的最大值,offset=14,它对应的position=340
  • 从10.log文件中物理位置340,顺序往下扫描文件,找到offset=15的消息内容。

可以看到通过稀疏索引,kafka既加快了消息查找的速度,也顾及了存储的开销

3.日志清理

Kafka提供了两种日志清理的方式:

1.日志删除(Log Retention):直接删除

2.日志压缩(Log Compaction):对相同key的不同value值,只保留最后一个版本

通过log.cleanup.policy参数来设置清理策略,默认值为"delete",如果要设置为压缩,需要改为"compact",还可以同时支持两种策略

1.日志删除

1.基于时间

根据日志分段中最大的时间戳来查找过期的日志分段文件

2.基于日志大小

检查当前日志大小是否超过retentionSize,默认值为-1,表示无穷大,该值代表所有日志文件的总大小,不是单个日志分段的大小,单个日志分段大小默认为1GB

3.基于日志起始偏移量

判断某个日志分段的下一个日志分段的起始偏移量baseOffset是否小于等于logStartOffset

4.磁盘存储

1.页缓存

页缓存是操作系统实现的一种主要的磁盘缓存,用来减少对磁盘I/O的操作,将磁盘中的数据缓存到内存中,将对磁盘的访问转变为对内存的访问

当一个进程准备读取磁盘上的文件内容时,操作系统会首先查看待读取的数据所在的是否在页缓存中,如果在直接返回数据,如果没有,操作系统会向磁盘发起读取请求并将读取的数据页存入页缓存,再将数据返回,写入的时候也是类似

优点:对于进程而言,会在进程内部缓存数据,同时有可能这些数据缓存在操作系统的页缓存中,被缓存了两次,使用页缓存可以省去进程内部的缓存消耗,还可以通过结构紧凑的字节码替代使用对象的方式节省更多空间,假设服务重启页缓存还是保持有效

Kafka大量使用了页缓存,这是Kafka实现高吞吐的重要因素之一。在Kafka中提供了同步刷盘和间断性强制刷盘的功能,但不建议使用,因为会严重影响性能

Linux系统使用磁盘的一部分作为swap分区,把非活跃进程放入swap分区,对于Kafka而言,应该避免这种内存的交换,否则会影响性能,建议把vm.swappiness值设为1,保留了该机制又使得它对Kafka的影响最小

2.磁盘I/O流程

I/O调度策略:

1.NOOP

No Operation,I/O请求大致按照先来后到顺序进行操作,做了相邻I/O请求的合并

2.CFQ

Completely Fair Queuing(默认),按照I/O请求地址进行排序

3.DEADLINE

除了CFQ本身具有的I/O队列,还为读I/O和写I/O提供了FIFO队列

4.ANTICIPATORY

满足随机I/O和顺序I/O混合的场景

3.零拷贝

将数据直接从磁盘文件复制到网卡设备中,不需要经过应用程序,减少了内核和用户态之间的上下文切换,依赖sendFile()方法实现

通过DMA(Direct Memory Access)方式数据只需要复制2次,上下文切换也只需要两次,零拷贝是针对内核模式的

免责声明:文章转载自《Kafka日志存储》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WSGI详解Mac for MySQL 5.7 安装教程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# 委托实例(跨窗体操作控件)

今天研究了一下,在C#里面却是可以不用自定义消息这么复杂的方法来实现跨窗体调用控件,C#有更好的办法就是委托。 效果描述:有两个窗体,FORM1(一个名为“打开form2”的button控件)和FORM2(一个名为“改变form1颜色“的button控件)。启动时,FORM1中点击button控件“打开form2””使FORM2显示出来。点击FORM2中的...

# AMQP协议 0-9-1 简介

目录 AMQP是什么AMQP 0-9-1 模型简介 交换机和交换机类型 默认交换机 直连交换机 扇型交换机 主题交换机 头交换机 队列 队列名称 队列持久化 绑定 消费者 消息确认 拒绝消息 Negative Acknowledgements 预取消息 消息属性和有效载荷(消息主体) 消息确认 其他 AMQP 0-9-1 方法...

二进制日志备份与恢复,快照备份,复制

二进制日志备份与恢复 二进制日志非常关键,我们可以通过它来完成point-in-time的恢复工作。MySQL数据库的复制同样需要二进制日志。默认情况下并不启用二进制日志,要使用二进制日志,首先必须启用它,在配置文件中进行如下设置: [mysqld] log-bin 对于InnoDB存储引擎只是简单启用二进制日志是不够的,还需要启用一些其他参数来保证安全和...

消息机制、子窗口和父窗口的消息传递

1. 什么是窗口 MSDN: In a graphical Win32-based application, a window is a rectangular area of the screen where the application displays output and receives input from the user. Theref...

常见的MIME类型

作者:景安网络 MIME类型 MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。 常用Mime类型: 文件后缀 Mime类型 说明 .flv flv/flv-flash 在线播放 .html或.h...

Java消息系统简单设计与实现

前言:由于导师在我的毕设项目里加了消息系统(本来想水水就过的..),没办法...来稍微研究研究吧..简单简单... 需求分析 我的毕设是一个博客系统,类似于简书这样的,所以消息系统也类似,在用户的消息里包含了有:喜欢和赞、评论、关注、私信这样的一类东西,这样的一个系统应该包含以下的功能: 当用户评论/关注/点赞时能够通知到被评论/关注/点赞的用户,并...