速度特性
通常认为磁盘操作较慢,而 kafka 的吞吐量非常惊人,可以轻松达到 QPS 百万,广泛应用于海量数据场景。
Apache Kafka 基准测试:每秒写入 2 百万(在三台廉价机器上)
下面从数据写入和读取两方面分析,为什么为什么 Kafka 速度这么快。
写入
磁盘顺序写入
机械硬盘的寻址是最耗时的,而顺序写入可以达到最高效率,极端场景下甚至和内存操作达到同一数量级。
kafka 直接在文件末尾写入,所有消息都是顺序关系,通过 Consumer 的 offset 确认读取位置。
- 为了避免磁盘写满,kafka 有数据淘汰机制,可以基于过期时间或 partition 容量淘汰数据。
mmap(Memory Mapped Files)
磁盘写入时,如果以 16KB(页) 为单位,效率最高,所以 kafka 利用 mmap 技术,将要写入的磁盘映射到内存空间, 然后批量写入内存。
不过这样做也可能造成数据没有及时写入磁盘丢失的情况,可以通过配置项来决定真正写盘的频率,按消息条数/间隔时间。
读取
Zero-Copy 零拷贝读取
利用sendfile
减少用户态、内核态的切换,同时减少内存消耗、提高速度。
如果是未写入磁盘的数据,可以直接利用 mmap+sendfile 的方式,从内核空间拷贝到网络协议引擎。
批量压缩
有些情况下,系统的瓶颈不是 CPU 或磁盘,而是网络带宽,对于广域网上运行的数据中心之间发送消息的数据尤其如此。 进行数据压缩会消耗少量的 CPU 资源,不过对于 kafka 而言,网络带宽更需要考虑。
- 如果每个消息都压缩,压缩率会相对较低,所以 kafka 采用批量压缩的方式,将多个消息一起压缩
- kafka 允许使用递归的消息集合,批量的消息可以以压缩的形式传输和保存,直到被消费者解压缩
- kafka 支持多种压缩协议,如 Gzip 和 Snappy