在这里插入图片描述Kafka 是一个可横向扩展,高可靠的实时消息中间件,常用于服务解耦、流量削峰。 好像是 LinkedIn 团队开发的,后面捐赠给apache基金会了。
Topic的分区
,每个 topic 可以有多个分区,分区的作用是做负载
,提高 kafka 的吞吐量。同一个 topic 在不同的分区的数据是不重复的,partition 的表现形式就是一个一个的文件夹。follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本。
raft
来保证系统的可用性。为什么同一个 partition 的数据只能被消费者组中的某一个消费者消费?
顺序性
将无法得到保证。当然由于各个分区的不同,我们顺序性还是不要靠kafka,在自己业务做判定。
负载均衡
,确保每个消费者都有机会消费消息,同时避免了重复消费
。每个消费者在消费时都会维护自己的 offset
**,如果多个消费者同时消费同一个分区,那么 offset 的管理将变得复杂,可能会导致重复消费或者消息丢失。kafka 会每次发送数据都是向 leader节点发送数据,并顺序写入到磁盘,然后 leader节点会将数据同步到各个从节点follower,即使主节点挂了,也不会影响服务的正常运行。
ack
后,发送ack给producer和生产者一样,消费者主动到kafka集群中拉取消息时,也是从leader节点去拉取数据
。
ack
,offset将会移动到下一位,待下次消费定位数据一共有四个原因
生产者发送数据到 kafka 集群中,最终会写入到磁盘中,会采用顺序写入的方式。消费者从 kafka 集群中获取数据时,也是采用顺序读的方式。无论是机械磁盘还是固态硬盘 SSD,顺序读写的速度都是远大于随机读写的。
磁头频繁寻址和旋转盘片
的开销制造更少的垃圾Block
,所以比随机写有更高的性能。PageCache
中,然后在顺序写入到磁盘中。PageCache
中查找,如果找不到,再去磁盘中读取。一般性能的瓶颈都是网络io、磁盘io。我们来看下从磁盘读取数据到网卡场景下,传统 IO 的整个过程:DMA方式,Direct Memory Access,也称为成组数据传送方式,有时也称为直接内存操作。DMA方式在数据传送过程中,没有保存现场、恢复现场之类的工作。
传统 IO 模型下,从磁盘读取数据,写到网卡设备中,经历了 4 次用户态和内核态之间的切换和数据的拷贝。红色箭头为数据拷贝
。 那能不能让拷贝次数发送的少一点呢?但是kafka 采用了 sendfile 的零拷贝技术
所谓的零拷贝技术不是指不发生拷贝,而是在用户态没有进行拷贝。
[1] https://strikefreedom.top/archives/why-kafka-is-so-fast [2] https://cloud.tencent.com/developer/article/2185290 [3] https://serverfault.com/questions/843628/why-do-sequential-writes-have-better-performance-than-random-writes-on-ssds [4] https://xie.infoq.cn/article/51b6764c48ff70988e124a868