当前位置: 首页 > news >正文

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

转载注明出处: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,如需转载请自行联系原作者

相关文章:

  • LVS+Keepalived实现高可用集群
  • 互联网领袖高峰对话实录:马云李彦宏等激烈碰撞
  • 从91移动应用发展趋势报告看国内应用现状
  • 用户和组管理权限及文件访问控制
  • Android模拟器启动选项 (转发)
  • 解决 window server2008 r2 没有注册Ofiice组件的方法
  • 20171110_allow_read_only_corruption参数
  • 手机震动效果--ios
  • AD DS最佳实践分析程序(BPA)应用实例---扫描并归档结果
  • httpd.conf文件详解(转)
  • java环境JDK安装及配置
  • WCF 入门
  • 学会提问 (豆瓣)
  • 路由协议OSPF
  • Linux服务器装机安全快速进阶指南
  • Apache Spark Streaming 使用实例
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • C++类中的特殊成员函数
  • If…else
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • java2019面试题北京
  • JavaScript类型识别
  • JS题目及答案整理
  • Mithril.js 入门介绍
  • MySQL用户中的%到底包不包括localhost?
  • Mysql优化
  • Spring框架之我见(三)——IOC、AOP
  • Vue2.x学习三:事件处理生命周期钩子
  • 仿天猫超市收藏抛物线动画工具库
  • 猴子数据域名防封接口降低小说被封的风险
  • 微信小程序开发问题汇总
  • 微信小程序实战练习(仿五洲到家微信版)
  • 我感觉这是史上最牛的防sql注入方法类
  • 一道闭包题引发的思考
  • 译有关态射的一切
  • 原生js练习题---第五课
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • # 透过事物看本质的能力怎么培养?
  • (1)(1.13) SiK无线电高级配置(六)
  • (4)(4.6) Triducer
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (第一天)包装对象、作用域、创建对象
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (算法)前K大的和
  • (转)Windows2003安全设置/维护
  • (转)创业家杂志:UCWEB天使第一步
  • **PHP二维数组遍历时同时赋值
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .Net 8.0 新的变化
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET 跨平台图形库 SkiaSharp 基础应用