Kafka为什么那么快

Kafka那么快的原因:

  1. 使用partition并行处理
  2. 批处理、数据压缩
  3. 顺序写磁盘
  4. mmap内存映射
  5. 零拷贝

理解Topic和Partition,Partition的并行处理

在 Kafka 中,Topic 是一个存储消息的逻辑概念,可以认为是一个消息集合。
每个 Topic 可以划分多个分区partition(每个 Topic 至少有一个partition),同一 Topic 下的不同分区包含的消息是不同的。每个消息在被添加到分区时,都会被分配一个 offset,它是消息在此分区中的唯一编号,Kafka 通过 offset 保证消息在分区内的顺序,offset 的顺序不跨分区,即 Kafka 只保证在同一个分区内的消息是有序的。
不同Partition可以位于不同的机器,就算在同一个机器上也可以位于不同的磁盘。磁盘的io可比内存的io慢得多,不同的磁盘可以并行处理。

批处理、数据压缩

相比较于内存和磁盘,网络的io效率更低了。
kafka在一个批处理中积累多条读写记录,并通过压缩算法来优化。

顺序写磁盘

新的消息不断追加到 partition 的末尾,这个就是顺序写。
但是,kafka期待操作系统顺序写入磁盘,操作系统只能尽量顺序写(如果遇到磁盘坏道或者磁道被占用)。
机械盘顺序写比随机写性能高:磁头不需要反复寻址。
固态盘顺序写比随机写性能高:闪存不能直接覆盖,需要寻找新的空间来写数据并将原来的数据标记失效。当写命令找不到新空间时,需要的等一次垃圾回收。随机写会比顺序写造成更多的空间碎片,所以顺序写性能比随机写高!
kafka并不是实时写入磁盘,见mmap内存映射。

mmap内存映射

  1. 进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域
  2. 调用内核空间的系统调用函数mmap(不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系
  3. 进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝

用内存读写取代I/O读写,pdflush默认要30s才写入磁盘一次。
两空间的各自修改操作可以直接反映在映射的区域内。
通过各自对映射区域的改动,达到进程间通信和进程间共享的目的。
但凡是需要用磁盘空间代替内存的时候,mmap都可以发挥其功效。
kafka为了快,可以不设置同步flush。为了保证系统的一致性:按照指定的级别写入集群副本(内存中),只要集群有一个副本还活着,kafka就能恢复。

零拷贝

Java NIO中FileChannel.transferTo方法,将数据从FileChannel对象传送到可写的字节通道(如Socket Channel等)。在内部实现中,由native方法transferTo0()来实现,它依赖底层操作系统的支持。在UNIX和Linux系统中,调用这个方法将会引起sendfile()系统调用。
kafka的零拷贝采用了linux的sendFile方法,DMA引擎直接把数据从内核缓冲区传输到网卡设备,有2次copy操作。
Netty的零拷贝
疑问点:很多博客中都说java的nio中transfer方法不是真正意义上的零拷贝,有3次copy的行为但是也说是通过操作系统的sendfile方法实现的。linux在2.1版本引入了sendfile此时copy3次(通过socketBuffer中转),2.4版本增强了sendfile此时copy2次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值