一 .生产者生产数据
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).png2、消息传送以文件的形式
当消费者需要数据的时候Kafka直接把“文件”发送给消费者。
消费者选择消息的时候
Zero Copy对应的是sendfile这个函数(以Linux为例),这个函数接受
- out_fd作为输出(一般及时socket的句柄)
- in_fd作为输入文件句柄
- off_t表示in_fd的偏移(从哪里开始读取)
- size_t表示读取多少个
Kafka是用mmap作为文件读写方式的,它就是一个文件句柄,所以直接把它传给sendfile;偏移也好解决,用户会自己保持这个offset,每次请求都会发送这个offset。;数据量更容易解决了,如果消费者想要更快,就全部扔给消费者。如果这样做一般情况下消费者肯定直接就被压死了;所以Kafka提供了的两种方式——Push,我全部扔给你了,你死了不管我的事情;Pull,好吧你告诉我你需要多少个,我给你多少个。
网友评论