kafka消息持久化到本地磁盘,如何保证消息的读写速率和高吞吐量
kafka入门:一个开源的、轻量级、高吞吐、高可用的分布式消息系统,介绍了解到kafka根据消息类型(topic),将消息分段(分区)为1到多个分区,每个分区有多个副本,副本以log后缀的格式持久化到kafka集群节点服务器的本地磁盘,在Kafka服务器重启后可恢复使用。但是,消息持久化到本地磁盘的文件系统,大家普遍认为本地磁盘读写慢,它又是如何保证消息的读写速率和高吞吐量呢?
消息持久化的读写速率
说到本地磁盘的读写快慢,依赖于文件系统如何存储和缓存消息在性能上会大打折扣,其实文件系统存储速度快慢一定程度上也取决于我们对磁盘的用法。
据Kafka官方网站介绍:6块7200r/min SATA RAID-5阵列的磁盘线性写的速度为600 MB/s,而随机写的速度为100KB/s,线性写的速度约是随机写的6000多倍。由此看来磁盘的快慢取决于我们是如何去应用磁盘。
另外,现代的操作系统提供了预读(read-ahead)和延迟写(write-behind)技术,使得磁盘的写速度并不是大家想象的那么慢。
消息系统数据持久化一般采用为每个消费者队列提供一个B树或其他通用的随机访问数据结构来维护消息的元数据,B树操作的时间复杂度为O(log n),可以看成一个常量时间,但这并不适合磁盘操作。
目前的磁盘寻道时间一般在10ms以内,对一块磁盘来说,在同一时刻只能有一个磁头来读写磁盘,这样在并发IO能力上就有问题。同时,对树结构性能的观察结果表明:其性能会随着数据的增长而线性下降。
鉴于消息系统本身的作用考虑,数据的持久化队列可以建立在简单地对文件进行追加的实现方案上。因为顺序追加,所以Kafka在设计上是采用时间复杂度O(1)的磁盘结构,它提供了常量时间的性能,即使是存储海量的信息(TB级)也如此,性能和数据的大小关系也不大,同时Kafka将数据持久化到磁盘上,这样只要磁盘空间足够大数据就可以一直追加,而不会像一般的消息系统在消息被消费后就删除掉,Kafka提供了相关配置让用户自己决定消息要保存多久,这样为消费者提供了更灵活的处理方式,因此Kafka能够在没有性能损失的情况下提供一般消息系统不具备的特性。
消息的高吞吐量
Kafka在数据写入及数据同步采用了零拷贝(zero-copy)技术,采用sendFile()函数调用,sendFile()函数是在两个文件描述符之间直接传递数据,完全在内核中操作,从而避免了内核缓冲区与用户缓冲区之间数据的拷贝,操作效率极高。
Kafka还支持数据压缩及批量发送,同时Kafka将每个主题划分为多个分区,这一系列的优化及实现方法使得Kafka具有很高的吞吐量。
经大多数公司对Kafka应用的验证,Kafka支持每秒数百万级别的消息。