kafka学习十-高效读写数据

1 顺序写磁盘

kafka的procedure生产数据,然后写入到log中,写的过程是直接追加到文件末端,顺序写。官方测试表明,同样的磁盘,顺序写能达到600M/s,随机写只能达到100K/s。
这与磁盘结构有关,顺序写之所以快,是因为减少了大量磁头寻址时间

2 零拷贝

传统模式下,从硬盘读取一个文件是这样的:
1)调用read函数,文件数据被copy到内核的缓冲区(read是系统调用,放到了DMA,所以用内核空间)。
2)read函数返回,文件数据从内核缓冲区copy到用户缓冲区。
3)write函数调用,将文件数据从用户缓冲区copy到内核与Socket相关的缓冲区。
4)数据从Socket缓冲区copy到相关协议引擎(网卡)。
以上细节是传统的read/write方式进行网络传输的方式,我们可以看到,在这个过程当中,文件数据实际上是经过了四次copy操作:硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎。
而sendfile系统调用则是提供了一种减少以上多次copy,提升文件传输性能的方法。Kafka在内核版本2.1中,引用了sendfile系统调用,以此简化网络上和两个本地文件之间的数据传输。sendfile的引入不仅减少了数据复制,还减少了上下文的切换:sendfile(socket, file, len)。
运行流程如下:
1)sendfile系统调用,文件数据被copy至内核缓冲区。
2)再从内核缓冲区copy至内核中socket相关的缓冲区。
3)最后再socket相关的缓冲区copy到协议引擎。

3 Memory Mapped Files

即便是顺序写入磁盘,磁盘的访问速度还是不可能追上内存的。所以Kafka的数据并不是实时的写入硬盘,它充分利用了现代操作系统的分页存储来利用内存,以此来提高I/O效率。Memory Mapped Files(后面简称MMAP)也被翻译成内存映射文件,在64位操作系统中一般可以表示20G的数据文件。它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后,你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。
通过MMAP,进程就可以像读写硬盘一样读写内存(当然是虚拟机内存),也不必关系内存的大小,因为有虚拟内存为我们兜底。使用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销(调用文件的read会有把数据先放到内核空间的内存中,然后再复制到用户空间的内存中)。但是这样也有一个很明显的缺陷:不可靠,因为写到MMAP中的数据并没有被真正地写入到硬盘中,操作系统会在程序主动调用flush命令的时候才会把数据真正地写入到硬盘中。Kafka提供了一个参数prducer.type来控制是不是主动flush,如果Kafka写入到MMAP之后就立即flush然后再返回Producer,就叫做同步(sync);如果Kafka写入到MMAP之后立即返回Producer不调用flush,就叫做异步(async)。
MMAP其实是Linux中的一个函数,就是用来实现内存映射的。Java的NIO提供了一个MappedByteBuffer类来实现内存映射

4 分区并发读写

kafka可以针对topic配置不同的分区,进行并发读写

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值