Kafka高吞吐量的原因
Kafka每秒可以处理一百万条以上消息,吞吐量达到每秒百万级。那么Kafka为什么那么高的吞吐量呢?
简单来说有以下几点原因:
1)页缓存技术
Kafka是基于操作系统的页缓存来实现写入的
操作系统本身有一层缓存,叫做page cache,是在内存里的缓存,我们也可以称之为 os cache,意思就是操作系统自己管理的缓存
Kafka在写入磁盘文件的时候,可以直接写入到这个os cache里,也就是仅仅写入到内存中,接下来由操作系统自己决定什么时候把os cache里的数据真的刷入磁盘文件中。这样可以很大提升写性能
2)、磁盘顺序写
Kafka写数据的时候,Kafka的消息是不断追加到文件末尾的,而不是在文件的随机位置写入数据,这个特性使Kafka可以充分利用磁盘的顺序读写性能。顺序读写不需要磁盘磁头的寻道时间,避免了随机磁盘寻址的浪费,只需很少的扇区旋转时间,所以速度远快于随机读写。
Kafka中每个分区是一个有序的,不可变的消息序列,新的消息不断追加到Partition的末尾,在Kafka中Partition只是一个逻辑概念,Kafka将Partition划分为多个Segment,每个Segment对应一个物理文件,Kafka对segment文件追加写,这就是顺序读写。
2)、零拷贝
在消费数据的时候,实际上要从kafka的磁盘文件里读取某条数据然后发送给下游的消费者。
Kafka在读数据的时候为了避免多余的数据拷贝,使用了零拷贝技术。也就是说直接让os cache里的数据发送到网卡后然后传输给下游的消费者,跳过中间从os cache拷贝到kafka 进程缓存和再拷贝到socket缓存中的两次缓存,同时也减少了上下文切换。
在Linux Kernel2.2之后出现了一种叫做“零拷贝(zero-copy)”系统调用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户缓冲区”。
Kafka 使用到了 mmap+write(持久化数据) 和 sendfile(发送数据) 的方式来实现零拷贝。分别对应 Java 的 MappedByteBuffer 和 FileChannel.transferTo。
参考博客:什么是零拷贝
3)、分区并发
kafka中的topic中的内容可以分在多个分区(partition)存储,每个partition又分为多个段segment,所以每次操作都是针对一小部分做操作,很轻便,并且增加并行操作的能力
4)、批量发送
Kafka允许进行批量发送消息,Productor发送消息的时候,可以将消息缓存在本地,等到了固定条件发送到kafka,可减少IO延迟
(1):等消息条数到固定条数
(2):一段时间发送一次
5)、数据压缩
Kafka还支持对消息集合进行压缩,Producer可以通过GZIP或Snappy格式对消息集合进行压缩,压缩的好处就是减少传输的数据量,减轻对网络传输的压力。
批量发送和数据压缩一起使用,单条做数据压缩的话,效果不太明显。消息发送时默认不会压缩,可使用compression.type来指定压缩方式,可选的值为snappy、gzip和lz4
更多参考:https://mp.weixin.qq.com/s/iJJvgmwob9Ci6zqYGwpKtw
END.