您的位置:首页 > 运维架构 > 网站架构

Kafka原理分析-持久化方案设计(Persistence)

2017-06-13 16:19 246 查看

Kafka持久化方案的设计

Kafka很大程度上依赖文件系统来存储和缓存消息。有一普遍的认识:磁盘很慢。这让人们怀疑使用磁盘作为持久化的性能。实际上,磁盘是快还是慢完全取决于我们是如何使用它。

就目前来说,一个 six 7200rpm SATA RAID-5磁盘线性(顺序)写入的性能能达到600MB/sec,而任意位置写(寻址再写)的性能只有100k/sec。这些线性读写是所有使用模式中最可预测的,并且由操作系统进行了大量优化。现在的操作系统提供了预读取和后写入的技术。实际上你会发现,顺序的磁盘读写比任意的内存读写更快。

基于jvm内存有以下缺点:

对象的内存开销非常高,通常会让存储数据的大小加倍(或更多)

随着堆内数据的增加,GC的速度越来越慢,而且可能导致错误

基于操作系统的文件系统来设计有以下好处:

可以通过os的pagecache来有效利用主内存空间,由于数据紧凑,可以cache大量数据,并且没有gc的压力

即使服务重启,缓存中的数据也是热的(不需要预热)。而基于进程的缓存,需要程序进行预热,而且会消耗很长的时间。(10G大概需要10分钟)

大大简化了代码。因为在缓存和文件系统之间保持一致性的所有逻辑都在OS中。以上建议和设计使得代码实现起来十分简单,不需要尽力想办法去维护内存中的数据,数据会立即写入磁盘。

这种以页面缓存(pagecache)为中心的设计风格在一篇关于Varnish设计的文章中有详细描述。

总的来说,Kafka不会保持尽可能多的内容在内存空间,而是尽可能把内容直接写入到磁盘。所有的数据都及时的以持久化日志的方式写入到文件系统,而不必要把内存中的内容刷新到磁盘中。

数据的zeroCopy

zeroCopy是指数据直接在kernel空间中进行读写,不通过进程空间。这样会减少进程Context的交换次数,大大提高数据读写的效率。有关zeroCopy的说明可以查看Linux的系统调用sendfile的实现,以及IBM的这篇论文。





以下两个图是说明zeroCopy和非zeroCopy两者在原理上的区别:





从上图可以看出,在通过网卡发送一个数据包时,zeroCopy会减少2次Context Switch。这会大大提升服务端的效率。如何编写zeroCopy的服务,见IBM的论文

Kafka读写的效率恒定

一般的消息系统的持久化数据结构,通常是每个消费者使用队列和BTree或一些通用的任意访问的数据结构来维护消息的元数据信息。但使用这些结构查询数据的效率一般最好情况下是O(logn),而随着数据量的增加,查询效率还会降低。

而对于Kafka来说,读写的效率都是恒定的,都是O(1),当然不同规格的磁盘读取和写入的效率不尽相同。对于Kafka来说,数据量的增长对读取和写入效率没有影响。

无需任何性能损失,就可以访问几乎无限的磁盘空间,这意味着Kafka可以提其他供消息传递系统没有的功能。例如,在Kafka中,消费者尽快消费消息,而我们可以保留消息相对较长的时间(例如一个星期)。这将为消费者带来很大的灵活性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息