首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kafka的存储及刷盘原理

首先我们先来了解一下kafka日志的结构:每个topic的partition对应一个broker上一个目录,目录中的文件以日志的大小(log.segment.bytes)和时间(log.roll.hours)来roll。我们看到的kafka v0.10.2的日志文件包括三个部分,分别是xxxxxxxxxxxxxxxxxxxx.index、xxxxxxxxxxxxxxxxxxxx.log和xxxxxxxxxxxxxxxxxxxx.timeindex,其中xxxxxxxxxxxxxxxxxxxx代表的是offset,20位,从0开始。Kafka没有采用uuid的形式,为每个message分配一个message.id,而是通过offset来标记message,offset并不是消息在文件中的物理编号,而是一个逻辑编号,通过追加方式,每次加1。那通过offset如何查找消息的呢?

通过offset查找文件位置,分为3步:

1)对xxxxxxxxxxxxxxxxxxxx.log进行排序,通过二分查找,得到所在的xxxxxxxxxxxxxxxxxxxx.log文件;

2) 对应的xxxxxxxxxxxxxxxxxxxx.index文件,通过二分查找,找到对应的条目,也就是offset到position的映射;

3)拿到这个position,就可直接定位xxxxxxxxxxxxxxxxxxxx.log的位置。然后从这个位置顺序扫描,得到实际的消息。

这里index文件的目的,就是为了加快查找速度。如果没有index文件,通过扫描log文件,从头扫描,也可以找到位置。

一条消息在磁盘的存储格式如下:

offset : 8 bytes

message length: 4 bytes (value: 4 + 1 + 1 + 8(if magic value > 0) + 4 + K + 4 + V)

crc : 4 bytes

magicvalue : 1 byte

attributes : 1 byte

timestamp : 8 bytes (Only exists when magic valueis greater than zero)

key length : 4 bytes

key : K bytes

valuelength : 4 bytes

value : V bytes

在Linux系统中,当我们把数据写入文件系统之后,其实数据在操作系统的pagecache里面,并没有刷到磁盘上。如果操作系统挂了,数据就丢失了。一方面,应用程序可以调用fsync这个系统调用来强制刷盘,另一方面,操作系统有后台线程,定时刷盘。频繁调用fsync会影响性能,需要在性能和可靠性之间进行权衡。实际上,官方不建议通过上述的三个参数来强制写盘,认为数据的可靠性通过replica来保证,而强制flush数据到磁盘会对整体性能产生影响。

Kafka的持久性并非要求同步数据到磁盘,因为问题节点都是从副本中恢复数据。这样刷盘依赖操作系统及Kafka的后台刷盘机制。这样的好处是:无需调优、高吞吐量、低延时和可全量恢复。

【关注】

如果觉得文章对你有用,请关注本微信公众号 - 全栈生涯

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190122G1A8JL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券