为什么 Kafka 那么快

一 .生产者生产数据

1、顺序写入

2、Memory Mapped Files(Kafka的数据并不是实时的写入硬盘,它充分利用了现代操作系统分页存储来利用内存提高I/O效率)

它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。写到mmap中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正的写到硬盘。Kafka提供了一个参数——producer.type来控制是不是主动flush,如果Kafka写入到mmap之后就立即flush然后再返回Producer叫同步(sync);写入mmap之后立即返回Producer不调用flush叫异步(async)。

消费者消费数据

“一个用硬盘的比用内存的快”,这绝对违反常识;如果这种事情发生说明——它作弊了。

1、zero copy

先复制到内核空间(read是系统调用,放到了DMA,所以用内核空间),然后复制到用户空间(1,2);从用户空间重新复制到内核空间(你用的socket是系统调用,所以它也有自己的内核空间),最后发送给网卡(3、4)。

clipboard.png

Zero Copy中直接从内核空间(DMA的)到内核空间(Socket的),然后发送网卡。

clipboard (1).png

2、消息传送以文件的形式

当消费者需要数据的时候Kafka直接把“文件”发送给消费者。

消费者选择消息的时候

Zero Copy对应的是sendfile这个函数(以Linux为例),这个函数接受

  • out_fd作为输出(一般及时socket的句柄)
  • in_fd作为输入文件句柄
  • off_t表示in_fd的偏移(从哪里开始读取)
  • size_t表示读取多少个

Kafka是用mmap作为文件读写方式的,它就是一个文件句柄,所以直接把它传给sendfile;偏移也好解决,用户会自己保持这个offset,每次请求都会发送这个offset。;数据量更容易解决了,如果消费者想要更快,就全部扔给消费者。如果这样做一般情况下消费者肯定直接就被压死了;所以Kafka提供了的两种方式——Push,我全部扔给你了,你死了不管我的事情;Pull,好吧你告诉我你需要多少个,我给你多少个

猜你喜欢

转载自blog.csdn.net/cclucc/article/details/82805498