Ch12-Kafka 为什么这么快
May 11, 2019
Apache Kafka 以牺牲延迟和抖动为代价优化了吞吐量,但并没有牺牲,比如持久性、严格的记录有序性和至少一次的分发语义。当有人说“Kafka 速度很快”,并假设他们至少有一定的能力时,你可以认为他们指的是 Kafka 在短时间内分发大量记录的能力。
1. Broker 优化 #
1.1 顺序写磁盘 #
Kafka 利用分段、追加日志的方式,在很大程度上将读写限制为顺序 I/O(sequential I/O)。 在一块普通的 7200 RPM SATA 硬盘上,随机 I/O(random I/O)与顺序I/O相比,随机I/O的性能要比顺序I/O慢3到4个数量级。
1.2 充分利用 Page Cache #
Broker 收到数据后,写磁盘时只是将数据写入 Page Cache,并不保证数据一定完全写入磁盘。如果数据消费速度与生产速度相当,甚至不需要通过物理磁盘交换数据,而是直接通过 Page Cache 交换数据。同时,Follower 从 Leader Fetch 数据时,也可通过 Page Cache 完成。 I/O Scheduler 会将连续的小块写组装成大块的物理写从而提高性能,还会将一些写操作重新按顺序排好,从而减少磁盘头的移动时间。
1.3 支持多 Disk Drive #
Broker 的 log.dirs 配置项,允许配置多个文件夹。如果机器上有多个 Disk Drive,可将不同的 Disk 挂载到不同的目录,然后将这些目录都配置到 log.dirs 里。Kafka 会尽可能将不同的 Partition 分配到不同的目录,也即不同的 Disk 上,从而充分利用了多 Disk 的优势。
1.4 零拷贝 #
Kafka 使用了 Zero Copy 技术提升了消费的效率。前面所说的 Kafka 将消息先写入页缓存,如果消费者在读取消息的时候如果在页缓存中可以命中,那么可以直接从页缓存中读取,这样又节省了一次从磁盘到页缓存的 copy 开销。文件大小从几 MB 到 1GB 的范围内,传统拷贝和零拷贝相比,结果显示零拷贝的性能提高了两到三倍。
2. Producer 优化 #
2.1 批量发送 #
Producer 支持一次性发送多条消息。由于每次网络传输,除了传输消息本身以外,还要传输非常多的网络协议本身的一些内容(称为 Overhead),所以将多条消息合并到一起传输,可有效减少网络传输的 Overhead,进而提高了传输效率。
2.2 高效的序列化方式 #
Kafka 消息的 Key 和 Payload(或者说 Value)的类型可自定义,只需同时提供相应的序列化器和反序列化器即可。因此用户可以通过使用快速且紧凑的序列化 - 反序列化方式(如 Avro,Protocal Buffer)来减少实际网络传输和磁盘存储的数据规模,从而提高吞吐率。
3. Consumer 优化 #
3.1 数据压缩 #
Broker 接收消息后,并不直接解压缩,而是直接将消息以压缩后的形式持久化到磁盘。Consumer Fetch 到数据后再解压缩。因此 Kafka 的压缩不仅减少了 Producer 到 Broker 的网络传输负载,同时也降低了 Broker 磁盘操作的负载,也降低了 Consumer 与 Broker 间的网络传输量,从而极大得提高了传输效率,提高了吞吐量。