漫游Kafka设计篇之数据持久化

  1. 云栖社区>
  2. 博客>
  3. 正文

漫游Kafka设计篇之数据持久化

技术mix呢 2017-11-09 21:02:00 浏览516
展开阅读全文

转载注明出处:http://blog.csdn.net/honglei915/article/details/37564595

不要畏惧文件系统!

Kafka大量依赖文件系统去存储和缓存消息。对于硬盘有个传统的观念是硬盘总是非常慢,这使非常多人怀疑基于文件系统的架构是否能提供优异的性能。实际上硬盘的快慢全然取决于使用它的方式。设计良好的硬盘架构能够和内存一样快。


在6块7200转的SATA RAID-5磁盘阵列的线性写速度差点儿相同是600MB/s,可是随即写的速度却是100k/s,差了差点儿相同6000倍。现代的操作系统都对次做了大量的优化,使用了 read-ahead 和 write-behind的技巧,读取的时候成块的预读取数据。写的时候将各种微小琐碎的逻辑写入组织合并成一次较大的物理写入。对此的深入讨论能够查看这里,它们发现线性的訪问磁盘,非常多时候比随机的内存訪问快得多。


为了提高性能。现代操作系统往往使用内存作为磁盘的缓存。现代操作系统乐于把全部空暇内存用作磁盘缓存。尽管这可能在缓存回收和又一次分配时牺牲一些性能。全部的磁盘读写操作都会经过这个缓存,这不太可能被绕开除非直接使用I/O。所以尽管每一个程序都在自己的线程里仅仅缓存了一份数据。但在操作系统的缓存里另一份。这等于存了两份数据。
另外再来讨论一下JVM,下面两个事实是众所周知的:

  • Java对象占用空间是很大的,差点儿相同是要存储的数据的两倍甚至更高。
  • 随着堆中数据量的添加,垃圾回收回变的越来越困难。

基于以上分析。假设把数据缓存在内存里,由于须要存储两份,不得不使用两倍的内存空间,Kafka基于JVM。又不得不将空间再次加倍,再加上要避免GC带来的性能影响,在一个32G内存的机器上,不得不使用到28-30G的内存空间。而且当系统重新启动的时候,又必须要将数据刷到内存中( 10GB 内存差点儿相同要用10分钟),就算使用冷刷新(不是一次性刷进内存。而是在使用数据的时候没有就刷到内存)也会导致最初的时候新能很慢。可是使用文件系统,即使系统重新启动了,也不须要刷新数据。使用文件系统也简化了维护数据一致性的逻辑。


所以与传统的将数据缓存在内存中然后刷到硬盘的设计不同。Kafka直接将数据写到了文件系统的日志中。

常量时间的操作效率

在大多数的消息系统中,数据持久化的机制往往是为每一个cosumer提供一个B树或者其它的随机读写的数据结构。B树当然是非常棒的,可是也带了一些代价:比方B树的复杂度是O(log N),O(log N)通常被觉得就是常量复杂度了。但对于硬盘操作来说并不是如此。磁盘进行一次搜索须要10ms,每一个硬盘在同一时间仅仅能进行一次搜索。这样并发处理就成了问题。尽管存储系统使用缓存进行了大量优化。可是对于树结构的性能的观察结果却表明,它的性能往往随着数据的增长而线性下降,数据增长一倍,速度就会减少一倍。


直观的讲,对于主要用于日志处理的消息系统。数据的持久化能够简单的通过将数据追加到文件里实现,读的时候从文件里读就好了。这样做的优点是读和写都是 O(1) 的,而且读操作不会堵塞写操作和其它操作。这样带来的性能优势是非常明显的。由于性能和数据的大小没有关系了。


既然能够使用差点儿没有容量限制(相对于内存来说)的硬盘空间建立消息系统,就能够在没有性能损失的情况下提供一些一般消息系统不具备的特性。比方。一般的消息系统都是在消息被消费后马上删除,Kafka却能够将消息保存一段时间(比方一星期),这给consumer提供了非常好的机动性和灵活性,这点在今后的文章中会有详述。




本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5180320.html,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术mix呢
+ 关注