Kafka 概要设计
胡夕 - 《Kafka实战》笔记
kafka的设计从四方面进行了考量:
- 吞吐量/延时
高吞吐量
- 消息持久化
高可用
- 负载均衡和故障转移
高可用
- 伸缩性
高伸缩性
吞吐量和延时
写入消息
kafka写入磁盘的速度很快,得益于他对磁盘的使用方式不同。虽然Kafka会持久化所有数据到磁盘,但本质上每次写入操作系统的其实只是把数据写入到操作系统的页缓存
,然后由操作系统自行决定什么时候把页缓存数据写回磁盘。
这样设计的三个优势:
- 操作系统的页缓存是在内存中分配的,所以写入消息的速度很快。
- Kafka不必直接与底层的文件系统打交道,所有繁琐的IO操作都由操作系统来处理。
- Kafka的写入是追加Append的方式,避免了
磁盘的随机读写
实际上磁盘的顺序读写和内存的随机读写速度相差无几
消费消息
同样,消费消息前,Kafka在读消息时首先尝试从OS页缓存中读取。如果命中,则从页缓存中字节发送到网络的Socket中。这个过程是利用Linux的sendfile系统调用做到的,这就是零拷贝技术(Zero Copy)
总结
kafka依靠以下四点达到高吞吐量和低延迟的目的:
- 大量使用操作系统的页缓存,内存操作速度快且命中率高
- Kafka不直接参与物理IO操作
- 采用追加写入的方式,而不是随机读写
- 使用sendfile的零拷贝技术提高了网络数据的传输效率
消息持久化
消息持久化的好处:
- 解耦消息发送和消息消费
- 实现灵活的消息处理(重新消费)
负载均衡和故障转移
负载均衡
让系统的负载根据一定的规则均衡的分配到所有参与工作的服务器上,从而最大限度的提升系统的整体运行效率。Kafka默认提供了很智能的Leader选举算法
故障转移
当服务器意外中止时,整个集群可以快速的检测到该失败,并立即将该服务器上的应用或者服务自动转移到其他服务器上;故障转移通常通过心跳或者会话的机制来实现。即只要主服务器和备份服务器的心跳无法维持或者主服务器注册到服务中心的会话超时过期,那么就认为主服务器无法正常运行,集群会自动启动某个备份服务器来替代主服务器的工作。
Kafka服务器支持故障转移的方式是使用的会话机制。每台Kafka服务器启动后会以会话的形式把自己注册到zookeeper服务器上,一旦服务器运转出现问题,与zookeeper的会话连接便不能维持从而超时失效,从事Kafka 集群会选举另一台服务器来完全替代这台服务器继续提供服务。
伸缩性
伸缩性表示向分布式系统中增加额外的计算资源(比如CPU,内存,存储或宽带)时吞吐量的提升。
线性的伸缩性的扩展是很难达到的,因为分布式系统隐藏了很多单点瓶颈制约了这种线性扩容能力,阻碍线性扩容的以常见的因素是状态的保存
. Kafka只保存了很轻量级的内部状态,其他状态都交由Zookeeper保存。