Hadoop大数据相关我的收藏

为什么Kafka速度那么快

2019-06-22  本文已影响9人  hedgehog1112

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

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

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

一、写入数据

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

1.1 顺序写入

磁盘读写的快慢取决于你怎么使用它,也就是顺序读写或者随机读写。在顺序读写的情况下,某些优化场景磁盘的读写速度可以和内存持平(注:此处有疑问, 不推敲细节,参考 http://searene.me/2017/07/09/Why-is-Kafka-so-fast/)。

硬盘是机械结构,每次读写都会寻址(“机械动作”最耗时)->写入,硬盘最讨厌随机I/O,喜欢顺序I/O。为提高读写硬盘速度,Kafka用顺序I/O。

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

    顺序读写速度超过内存随机读写

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

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

上图展示Kafka如何写入数据, 每个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

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

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

4.相关协议引擎

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

而sendfile系统调用则提供了一种减少以上多次copy,提升文件传输性能的方法。

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

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

sendfile(socket, file, len)运行流程:

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

减少到user缓冲区

在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速度

上一篇下一篇

猜你喜欢

热点阅读