Kafka的特性
- 能够保证消息的可靠性投递:
- 持久化:producer生产的消息会在broker中进行持久化到硬盘的操作,consumer从broker中拉取消息
- 多副本+容灾:producer生产的消息发送到leader broker之后,会有follower进行复制操作;当leader发生故障时可以进行故障转移,保证消息的正常消费
- 高并发:
- 可以同时支持多个consumer并行消费
- 将topic进行分区,在每个consumerGroup中的consumer可以消费1个或者多个分区,consumer之间是并行操作的
- 高吞吐量:
- 消息批量操作:将多条消息整合为一个消息集进行写入,可以节省IO
- 消息压缩:可以通过配置compression.tye设置消息的压缩类型,比如gzip —— producer在生产消息时会进行压缩后再写入broker中,并且在消息中附带压缩方式;consumer在消费消息时根据对应的压缩方式进行解压后处理;
- 顺序写盘:kafka写入文件的方式为append-only,即只顺序地在文件后追加内容。这样的好处是不需要进行磁盘寻道和磁臂旋转,可以直接进行数据写入;顺序写入的执行效率可以达到400M/s,而随机写入在几兆的级别。
- 采用零拷贝减少了内核空间与用户空间之间的数据拷贝操作。
零拷贝
为什么需要拷贝
因为是业务代码将read文件的数据和write网卡的数据关联起来,数据需要放到用户空间来,所以需要从内核态-用户态-内核态的拷贝
Kafka消费消息
优化思路
不需要将数据拷贝到用户空间中来,直接在内核空间中完成数据转发
producer发送消息
- broker通过MMAP系统调用将消息写入文件;
- MMAP映射的空间对于内核空间和用户空间都可见所以不用拷贝;
3.写入后等待操作系统异步地将内存中的脏页回写到磁盘上 ( 可以通过配置producer.type=sync,即每次写入内存都执行msync系统调用,将MMAP的数据刷盘)
consumer拉取消息
- broker从文件中读取并且通过网络发送——sendfile系统调用
- broker从文件中读取的buffer数据,直接作为参数给到socket.send (file.read())函数,直接从内核空间完成数据从文件到socket buffer的转发