Kafka高性能和高可用
Kafka 的高性能是如何保证的?¶
- 零拷贝。在 Linux 上 Kafka 使用了两种手段,mmap 和 sendfile,前者用于解决 Producer 写入数据,后者用于 Consumer 读取数据;
- 顺序写:Kafka 的数据,可以看做是 AOF (append only file),它只允许追加数据,而不允许修改已有的数据。(后面是亮点)该手段也在数据库如 MySQL,Redis 上很常见,这也是为什么我们一般说 Kafka 用机械硬盘就可以了。有人做过实验(的确有,你们可以找找,我已经找不到链接了),机械磁盘 Kafka 和 SSD Kafka 在性能上差距不大;
- Page Cache:Kafka 允许落盘的时候,是写到 Page Cache 的时候就返回,还是一定要刷新到磁盘(主要就是 mmap 之后要不要强制刷新磁盘),类似的机制在 MySQL, Redis 上也是常见,(简要评价一下两种方式的区别)如果写到 Page Cache 就返回,那么会存在数据丢失的可能。
- 批量操作:包括 Producer 批量发送,也包括 Broker 批量落盘。批量能够放大顺序写的优势,比如说 Producer 还没攒够一批数据发送就宕机,就会导致数据丢失;
- 数据压缩:Kafka 提供了数据压缩选项,采用数据压缩能减少数据传输量,提高效率;
- 日志分段存储:Kafka 将日志分成不同的段,只有最新的段可以写,别的段都只能读。同时为每一个段保存了偏移量索引文件和时间戳索引文件,采用二分法查找数据,效率极高。同时 Kafka 会确保索引文件能够全部装入内存,以避免读取索引引发磁盘 IO。(这里有一点很有意思,就是在 MySQL 上,我们也会尽量说把索引大小控制住,能够在内存装下,在讨论数据库磁盘 IO 的时候,我们很少会计算索引无法装入内存引发的磁盘 IO,而是只计算读取数据的磁盘 IO)
批量操作+压缩的亮点
- 批量发送和数据压缩,在处理大数据的中间件中比较常见。比如说分布式追踪系统 CAT 和 skywalking 都有类似的技术。代价就是存在数据丢失的风险;
- 数据压缩虽然能够减少数据传输,但是会消耗更过 CPU。不过在 IO 密集型的应用里面,这不会有什么问题;
Kafka 高可用¶
- 数据复制(Replication): Kafka 使用副本机制来实现数据的冗余存储和容错。每个分区都可以配置多个副本,其中一个作为领导者(Leader),其他副本作为追随者(Follower)。领导者负责处理所有的读写请求,而追随者则通过复制领导者的数据来提供冗余备份和故障恢复。当领导者发生故障时,追随者中的一个会被选举为新的领导者。
- ISR(In-Sync Replica)机制: 在 Kafka 中,追随者的副本需要与领导者保持同步才能提供可靠的数据复制。Kafka 使用 ISR 机制来确定一组处于同步状态的副本。只有属于 ISR 中的副本才能参与数据的复制和读取操作。如果某个副本无法及时复制领导者的数据或发生故障,它将从 ISR 中移除,直到与领导者保持同步为止。
- Controller 选举: Kafka 集群中有一个专门的节点称为 Controller,负责管理分区和副本的状态。当集群中的 Controller 发生故障时,会自动进行 Controller 的选举,确保集群能够继续正常运行。选举完成后,新选举出的 Controller 负责维护和管理分区和副本的状态。
- 故障恢复: 当领导者或副本发生故障时,Kafka 会自动进行故障恢复。追随者中的一个副本会被选举为新的领导者,并从 ISR 中添加新的副本,以确保数据的可靠性和高可用性。一旦故障副本恢复正常,它将再次加入 ISR,参与数据的复制和读取。
- 数据持久化: Kafka 使用磁盘作为主要的数据存储介质,消息和日志被持久化写入到磁盘中。这样即使发生节点故障,数据也不会丢失。Kafka 还支持数据的压缩和数据段的分割,以优化存储和提高读写性能。