(2)为什么Kafka速度那么快

消息保存或缓存磁盘上,一般认为磁盘读写数据是会降低性能,因为寻址会消耗时间,实际Kafka特性之一是高吞吐率

Kafka轻松支持普通服务器每秒百万级写入请求,超过了大部分的消息中间件,在日志处理海量数据场景广泛应用。

基准测试参考:Apache Kafka基准测试:每秒写入2百万(在三台廉价机器上)

一、写入数据

优化写入速度用两个技术:顺序写入 和 MMFile 。

1.1 顺序写入

Linux对磁盘读写优化:read-ahead和write-behind,磁盘缓存等。内存做这些操作,JAVA对象内存开销大,堆内存数据增多,GC时间长,磁盘好处:

(1)顺序读写速度超过内存随机读写:每次读写都寻址(“机械动作”最耗时)

(2)JVMGC效率低内存占用大磁盘可避免

(3)系统冷启动后,磁盘缓存依然可用

写入数据

每个Partition都是一个文件收到消息后Kafka会把数据插入到文件末尾(虚框部分)。

缺陷:不能删除数据 ,每个消费者(Consumer)对每个Topic都有一个offset表示 读到第几条数据

Consumer1有两个offset分别对应Partition0、Partition1(假设每一个Topic一个Partition);Consumer2有一个offset对应Partition2offset是由客户端SDK负责保存,Kafka的Broker完全无视这个东西的存在;一般情况下SDK会把它保存到zookeeper里面。(所以需要给Consumer提供zookeeper的地址)。

解决:Kakfa删除数据策略:(1)基于时间,(2)基于partition文件大小(配置文档看具体配置)。

1.2 Memory Mapped Files(mmap内存映射文件)

出现原因:顺序写入硬盘,硬盘访问速度还是不可能追上内存。Kafka不是实时写入硬盘 ,利用了操作系统 分页存储(用内存提高I/O效率)

工作原理:操作系统Page实现文件物理内存直接映射。对物理内存的操作会同步到硬盘(操作系统适当时)。64位操作系统中可表示20G数据文件

用途:进程读写硬盘一样读写内存(当然是虚拟机内存),不必关心内存大小,虚拟内存兜底。

好处:I/O提升, 省去用户空间内核空间 复制开销(调用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中。)

缺点:不可靠, 写到mmap中的数据,没被真正写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正写到硬盘

Kafka提供了参数producer.type控制是不是主动flush,如果Kafka写入到mmap之后就立即flush然后再返回Producer叫 同步 (sync);写入mmap之后立即返回Producer不调用flush异步 (async)。

二、读取数据

基于sendfile实现Zero Copy,sendfile系统调用减少多次copy,提升文件传输性能

2.1 传统模式文件传输流程(read/write方式):

1.文件数据被copy到内核缓冲区(调read函数),2.然后到用户缓冲区(read函数返回),3.再到内核与socket相关缓冲区(write函数调用)

4.相关协议引擎

四次copy操作:硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎

2.2 简化网络上和两个本地文件之间的数据传输

引入sendfile系统调用,减少数据复制、上下文切换。

(1)sendfile(socket, file, len)运行流程:    减少到user缓冲区

1.文件数据被copy至内核缓冲区(sendfile系统调用),2.至内核中socket相关缓冲区,3.协议引擎     

(2)优点:1)2.1linux内核引进sendfile:减少内核缓冲区到user缓冲区,再到socket相关缓冲区文件copy  2)2.4后,文件描述符结果被改变:仅将记录数据位置长度数据存 socket缓存。实际数据由DMA模块直接发送到协议引擎,减少一次copy。(4次,变2次,变1次)

(3)在apache,nginx,lighttpd等web服务器当中,都有一项sendfile相关的配置,提升文件传输性能。

Kafka把所有的消息都存放在一个个文件中,当消费者需要数据的时候Kafka直接把文件发送给消费者,配合mmap作为文件读写方式,直接把它传给sendfile。

三、批量压缩

系统瓶颈是网络IO不是CPU或磁盘,数据压缩消耗CPU资源少,

批量压缩,多个消息一起压,如每个消息都压缩,压缩率低,

Kafka用递归消息集合,传输并保持压缩格式(在日志中),直到被消费者解压缩

Kafka支持多种压缩协议(Gzip和Snappy压缩协议)

总结

Kafka速度秘诀:

(1)读取数据时配合sendfile直接暴力输出

(2)写入数据:顺序写入,单个Partion是末尾添加所以速度最优。

(3)批量压缩把所有消息变成一个批量文件,合理减少网络IO损耗,通过mmap提高I/O速度

https://www.cnblogs.com/binyue/p/10308754.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容