Kafka数据持久化、高效传输设计原理

一、kafka解决的业务痛点

解决大量数据的实时传输问题。例如:

  • 可能需要支持高吞吐量的实时日志聚合系统事件流
  • 可能需要支持大量后台日志处理中,离线系统周期加载数据
  • 低延时消息传输

这需要kafka系统支持分区,分布式,实时处理接收到的数据。此外,当数据被送到其他服务系统中时,kafka系统在机器出现问题是还必须有容错性保证。从某种程度上理解,kafka系统更像是一个日志数据库。

二、kafka持久化存储数据设计

kafka强依赖于文件系统操作系统页缓存,摈弃java堆缓存机制,同时将磁盘随机写修改为磁盘顺序写,并且加入了数据传送到socket的“Zero-Copy”技术。

2.1 磁盘和JVM存在的问题

(1)磁盘速度“慢”

磁盘慢的主要原因是,磁盘驱动的吞吐量和磁盘搜索方式强相关。例如在7200转磁盘上,其线性写性能是随机写性能的6000倍。磁盘线性读写大多情况是可预知的,能被OS优化通磁盘预读、后写技术(buffer)进行优化。

预读:从磁盘预读大块数据到buffer中。

后写:将数据放入buffer中,批次写入物理磁盘。

相关技术讨论看这里:

The Pathologies of Big Data - ACM Queue

磁盘随机读写为何慢?

机械硬盘采用传统的磁头探针结构,随机读写时需要频繁寻道,也就需要磁头和探针频繁的转动,而机械结构的磁头和探针的位置调整是十分费时,这严重影响到硬盘的寻址速度,进而影响到随机写入速度。

(2)JVM堆缓存

  • 对象中实际数据占比低
  • JVM堆内存垃圾回收频率高

2.2 kafka持久化数据存储设计

存储方式kafka将数据立即写入文件系统,刷入磁盘交给操作系统。

根据磁盘和JVM的性质,kafka使用文件系统和页缓存处理数据,而非在进程中对数据进行缓存。换句话说,kafka收到消息后立即被写入文件系统中,而后由OS内核管理的文件系统自动刷入到磁盘上。其中,数据写入文件系统这个操作意味着数据被转移到OS内核的分页缓存中。

使用页缓存:通过自动访问所有空闲的物理内存,至少使可用的页缓存增加了一倍。

存储字节数据:仅存储一系列紧凑的数据字节而不是单个java对象,可能又会使内存有效存储比例增加一倍。

上述kafka数据存储方式的优势

        在32GB的机器上的页缓存可能达到28-30GB而不会触发GC。即使服务(进程)被重新启动,内存中的页缓存(pagecache)也依旧存在(因为物理服务器未重启),而进程中的缓存则需要在内存中重新载入(对于10GB的缓存可能需要10分钟),否则就需要从文件中重新缓存(这可能意味着糟糕的初始性能)。

        这种存储方式简化了代码,因为所有维持页缓存和文件系统之间一致性的逻辑由操作系统完成,往往比在进程内维护更有效、更正确。

三、Kafka高效传输设计

  • 消息批量写入减少磁盘IO操作次数。
  • 统一消息格式减少消息转换时间。在producer、broker、consumer之间采用标准的二进制消息格式,这样消息块在三者之间就不需要额外修改。
  • 消息到socket之间通过sendfile方式(页缓存直接到socket)避免多次拷贝。
  • 提供端到端数据压缩以减少网络带宽占用。

3.1 批量消息写入

kafka消息发送(写入)并非单条发送,而是采用消息集合(批量)发送。同样,broker接收到消息集合,消费者消费消息集合。这种方式可减少broker中IO次数。

3.2 采用标准化二进制消息格式

kafka在生产者、broker和消费者之间通过标准二进制消息格式进行传输,数据块可以在他们之间不加修改即可传输。

3.3 消息文件传输到socket使用Zero-Copy优化

broker中的消息以文件方式存储在一起。Linux操作系统中,传统的文件发送到socket过程如下:

  • 操作系统在内核空间将磁盘数据读入页缓存
  • 应用程序从内核空间读取数据到用户空间buffer
  • 应用程序将数据写入到内核空间的socket buffer
  • 操作系统从socket buffer拷贝数据到NICbuffer,然后发送到网络

可以看出,传统方式发送文件到socket过程,对数据进行了四次拷贝两次系统调用,非常低效。

使用sendfile方式发送文件数据到socket,会避免上述方式中的重复拷贝。因为sendfile系统调用可以将页缓存中的数据直接传输到socket。优化后只需要最后一次将数据拷贝到网卡的缓冲区中。

这种结合页缓存和sendfile方式,意味着磁盘上没有任何读取操作,因为consumer直接从缓存中获取数据。更多sendfile技术请看这篇文章

3.4 压缩端到端传输的数据

批量消息压缩是为了降低因网络带宽导致跨网络数据传输效率低下。kafka支持的数据压缩格式有GZIP、Snappy、LZ4和ZStandard标准压缩协议

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值