欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Kafka是什么

程序员文章站 2022-07-13 17:03:18
...
Kafka 的核心功能是高性能的消息发送和高性能的消息消费.



在设计一个消息引擎系统的时候需要考虑两件事:
1.消息设计:消息必须是语义清晰的,且格式应当具备通用性.
2.传输协议设计:消息要能够在不同的系统间传输.
3.消息引擎范型:比如消息队列,发布/订阅.

消息队列模式:消息被一个生产者生产出来,放到消息队列中,消费者从指定位置消费消息,一旦消息消费完成,则从队列中移除该消息,所以,生产者和消费者是一一对应的.

发布/订阅模式:这种模式中有 topic 的概念(类似于盛装消息的容器),消费者订阅该主题,生产者生产消息,发送到主题上,然后所有订阅了该主题的消费者都能收到消息.

Kafka 在设计之初就是为了解决互联网公司超大量级数据的实时传输,所以其考虑了如下几个方面:
1.吞吐量/时延
2.消息持久化
3.负载均衡和故障转移
4.伸缩性

Kafka 是如何实现高吞吐量,低时延的了?
首先Kafka 的写入操作很快,因为每次写入操作都只是把数据写入到操作系统的缓存页中,然后由操作系统自行决定什么时候吧页缓存中的数据写会磁盘.
1.操作系统页缓存是在内存中分配的,所以消息写入的速度非常快.
2.Kafka不必直接与底层的文件系统打交道.所有繁琐的I/O都交由操作系统来处理.
3.Kafka写入操作采用追加写入的方式,避免了磁盘随机写操作.

首先 Kafka 尝试从 OS 的页缓存中读取,如果命中便把消息经页缓存直接发送到网络的 Socket(Zero Copy).

一般来说,数据从磁盘,然后通过网络发送出去需要拷贝 4 次.
1.通过 DMA,将数据从磁盘拷贝到内核缓冲区
2.通过 CPU,将数据从内核缓存区拷贝到用户缓冲区.
3.通过 CPU,将数据从用户缓冲区拷贝到 Socket 缓冲区.
4.通过 DMA,将数据从 Socket 缓冲区拷贝到网络.



2.mmap
让数据不需要拷贝到用户缓冲区.
1.通过 DMA,将数据从磁盘拷贝到内核缓冲区
2.操作系统将这段内核缓冲区和用户程序共享
3.通过 CPU,将数据从内核缓冲区拷贝到 Socket 缓冲区.
4.通过 DMA,将数据从 Socket 缓冲区拷贝到网络.

3.sendfile

目前为止,我们已经减少了数据拷贝的次数了,但是仍然存在一次拷贝,就是页缓存到socket缓存的拷贝。那么能不能把这个拷贝也省略呢?

借助于硬件上的帮助,我们是可以办到的。之前我们是把页缓存的数据拷贝到socket缓存中,实际上,我们仅仅需要把缓冲区描述符传到socket缓冲区,再把数据长度传过去,这样DMA控制器直接将页缓存中的数据打包发送到网络中就可以了。

总结一下,sendfile系统调用利用DMA引擎将文件内容拷贝到内核缓冲区去,然后将带有文件位置和长度信息的缓冲区描述符添加socket缓冲区去,这一步不会将内核中的数据拷贝到socket缓冲区中,DMA引擎会将内核缓冲区的数据拷贝到协议引擎中去,避免了最后一次拷贝。



参考:jianshu.com/p/fad3339e3448

总结一下:

1.大量使用操作系统页缓存,内存操作速度快且命中率高.
2.Kafka 不直接参与物理内存I/O操作,而是交给最擅长此事的操作系统来完成.
3.采用追加文件的方式,摒弃了缓慢的磁盘随机读/写操作.
4.使用以 sendfile 为代表的零拷贝技术加强网络间的数据传输效率.

Kafka 实现负载均衡是用过智能化的分区领导者选举来实现的.

Kafka 采用会话机制实现故障转移.每台Kafka 服务器启动后会以会话的形式把自己注册到 Zookeeper 服务器上,一旦该服务器出现问题,与 Zookeeper 的会话便不能维持从而超时失效,此时 Kafka 集群会选举出另一台服务器来完全代替这台服务器继续提供服务.

Kafka 基本概念

broker——Kafka服务器

Kafka 的消息设计:
消息头部(CRC、版本号、属性、时间戳、键长度、消息体长度)   key    value
key:消息键,对消息做 partition 时使用,即决定消息保存在某 topic 下的那个 partition.
value: 消息体,保存实际的消息数据.
Timestramp: 消息发送时间戳


topic-partition-message 三级结构,Kafka 的 partition 是不可修改的有序消息序列. 每个 partition 有自己的专属的 partition 号,通常是从 0 开始的. 用户对 partition 唯一能做的操作就是在消息序列的尾部追加消息.partition 上的每条消息都会被分配一个唯一的序列号(也就是偏移量 offset). 该位移值是从 0 开始递增的.

replica 副本,存在的意义就是防止数据丢失. 副本分为两类,领导者副本(leader)和追随者副本(follower). 追随者副本是不能提供服务给客户端的,它只被动的向领导者副本获取数据,而一旦领导者副本宕机,则会从剩余的副本中选举出新的 leader 继续提供服务.

Kafka 保证同一个 partition 的多个 replica 一定不会分配在同一台 broker 上.

ISR: in-sync replica,与领导者副本保持同步的 replica 集合.

Kafka 为 partition 动态维护一个 replica 集合. 该集合中的所有 replica 保存的消息日志都与 leader replica 保持同步状态. 只有这个集合中的 replica 才能被选举为 leader,也只有该集合中所有 replica 都接收到了同一条消息,Kafka 才会将消息设置为已提交状态,即认为该消息发送成功.

Kafka 对没有提交成功的消息不做任何交付保证,它只保证在 ISR 存活的情况下”已提交“的消息不会丢失.

正常情况下,partition 的所有 replica 都在 ISR 中,但是由于种种原因,有一部分 replica 落后于 leader replica 的进度,当滞后到一定程度的时候,Kafka 会将这些 replica 踢出 ISR,当这些 replica 重新追上 leader replica 的进度时,Kafka 会将它们重新加入到 ISR 中.