如何设计像 Kafka 这样的分布式日志系统的存储方案?

查看原文

日志是一种线性序的,只增加数据的数据结构,通常来说内容就是时间戳和内容数据,被添加到文件的末尾。虽然说起来这么简单,但要做到满足企业海量的日志数据的生成,就得引入像 Kafka 这样的系统。企业需求:高性能,高可用,可扩展,为了满足这些,我们也就要去实现领导选举,数据 replication,日志持久化,消息队列等等。

跟消息队列不同的是,消息只会被添加不会被删除,另外有基于某些规则的保留 (retention)能力。我们还有一些需求是定点重放,从某个日志记录开始读取数据,这意味着我们要做二分查找。

理论上来说,日志是无限增长的,单纯的文件不足以应对无限的数据。为了解决数据存储, Kafka 引入了 Chunk,不直接存储数据进文件,而是存进一个个小区块里,再把区块的索引登记到 index file 里。

为了性能考虑,我们尽可能要用到操作系统的页缓存,避免磁盘读操作。为此我们数据存储的时候可以直接将数据格式设定存储网络序,这样从内存页中可以直接转到 socket buffer 上(zero copy), 否则就需要从内存页中转到用户空间的程序再转到 socket buffer 上。这样的设计节省了 CPU 和内存带宽。

此外,我们在存储的时候还得考虑批量存储和数据压缩。简单来说,分布式日志系统一点页不简单。