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

Facebook团队关于Hadoop/HBase在SSD上的实验和讨论(转)

硬件技术的发展给存储和数据库软件技术提供了新的机会。近年来SSD开始流行,那么SSD能否给Hadoop/HBase带来性能的提升呢?来自Facebook数据团队的工程师们做了相关的研究和实验工作。

本文是http://hadoopblog.blogspot.com/2012/05/hadoop-and-solid-state-drives.html (需自备梯子)的翻译并加上了一些自己的思考,版权归原博客作者所有。

先说下SSD吧,SSD没有传统机械硬盘的机械寻道时间而带来的延迟,所以IOPS性能可以达到100-200K(而15K的SAS一般在100左右),所以能提供相对于机械硬盘100+倍的的小文件读取性能,而且在连续读取方面也能带来3倍左右的性能提升。但是在写入性能方面,SSD由于擦除等因素的存在,导致写入性能提升并不是很大,而且顺序写性能明显由于随机写,所以实践中要尽量避免随机写SSD。SSD的读写性能差距较大,而机械硬盘读写性能差距不大。

Use case:

Hadoop在Facebook主要有两种使用场景:基于MapReduce的OLAP类分析型应用和简单的key-value存储。

前者的场景下 数据基本上是顺序读取的,不会所以用SSD可能获益不多。多数的MapReduce任务是CPU密集型的(decompression,deserialization等),瓶颈在于data shuffle过程中的map-output-fetch,加快从HDFS中读取文件的IO速度并不能显著提高MapReduce任务的执行速度。可以把Map任务的输出写到SSD上,这样能够加快data shuffle中map-output-fetch的速度 ,所以说这是一个优化思路。

对于后者的场景,SSD能够提升online-transaction-process-workload的速度是有理论依据的,所以说也是一个优化思路。

Background:

SSD的读写延迟和机械硬盘相比是有数量级的差距的,特别是在随机读写的时候。例如在随机读上,SSD的随机读取延迟大概是30 micro-seconds(微秒),而机械硬盘随机读取延迟大概在5-10 milli-secondes(毫秒)。SSD能支撑100k-200k的OPS,而机械硬盘仅能支撑200-300的OPS。这意味着随机读写在SSD上不是瓶颈。(这是Dhruba Borthakur的博客中的说法,但是我认为随机写在SSD上还是要尽量避免的。)另外一方面,现有的数据库架构都是基于机械硬盘设计的,没有考虑到SSD的IO代价模型。那么SSD能否给现有基于机械硬盘设计的数据库带来性能的提升呢?Facebook的数据团队做了实验。他们分别做了基于HDFS和HBase的随机读取实验,看到底SSD能够跑出什么样的性能。

HDFS random-read on cached data:

这个实验中,他们创建了一个两节点的集群,一个NameNode,一个DataNode。创建一个2G的HDFS文件,文件的block大小是256M,拷贝数是1,所以一共有8个block。DataNode配置了CPU超线程,同时本地文件系统用的是XFS存放block文件。Benchmark程序也在DataNode上跑,同时打开了hdfs-read-shortcircuit功能(https://issues.apache.org/jira/browse/HDFS-2246),这样DFSClient就会绕过与DataNode的网络通信而直接从本地磁盘文件系统读取数据。把这2G文件都放在操作系统的缓存中,所以整个测试过程没有磁盘IO。用这样的测试场景来模拟SSD的。然后分别用不同的client线程数测试,每个client线程从HDFS中读取16K的数据。由于一共就8个block,所以DFSclient缓存了所有的BlockLocations,所以这个过程没有与NameNode的通信。

在开始的几轮实验中,最大的随机读吞吐量大概在50K OPS,但是CPU还很空闲。他们发现在hdfs-read-shortcircuit过程中花费了非常可观的时间在DNS查询和metric-counters的更新上。在修改了这部分的代码之后,他们的最大随机读吞吐量已经达到了 92K OPS,同时CPU接近95%的利用率。下图是实验结果,从中可以看出基于HDFS的数据库并不能完全利用SSD提供的IOPS。

然后他们用profile的形式来跑HDFS的代码显示,DFSClient端的代码路径太长了,对缓存的数据随机读取产生了相当大的影响。使用机械硬盘的数据读取磁盘IO时间在毫秒的数量级,那么DFSClient读取流程的开销可能不是那么明显。但是当数据被存储在操作系统的cache或者在SSD中时,DFSClient的读取流程的开销就比较大了,这部分需要重新设计读取流程。另外一个思路是用C/C++实现一个read-only的client,避免现在基于Java实现的DFSClient的开销。

HBase random-get on cached data:

然后他们做了类似的实验在HBase上。创建了一个表,只有一个region,并且这个region所有的数据都是缓存在一台RegionServer操作系统的cache中。同样用这样的方法模拟SSD。用4个客户机做random-get操作。RegionServer配置最大2000个线程,HBase的table使用lzo压缩算法并开启delta-encoding-fast-diff功能。同样整个过程没有磁盘IO。HBase的吞吐量在35K OPS左右,并且同时CPU使用没有超过45%。在RegionServer上严重的锁竞争和上下文切换使得CPU的利用率比较低。实验结果如下图所示。

What dose this mean

两个实验表明,HDFS和HBase都不能完全利用SSD提供的高效IOPS。所以要想把HDFS/HBase用在SSD上跑出很好的性能,需要对代码进行重构,但是这需要花大量的时间。而且这个结论同样适用于其他数据库应用,因为现有数据库都是基于机械磁盘的IO代价模型设计的,不适用与SSD硬盘。能够完全利用SSD磁盘的数据库架构需要从头开始设计。

也有些人对这个实验提出了一些讨论和意见:

Q:35K OPS的HBase操作代表着多少次磁盘IO的OPS,一般情况下一次HBase操作并不是一次磁盘IO操作,也就是所谓的IO放大(IO amplification)。大多数数据库IO amplification大概是1:5到1:10,主要包括record相应的索引的查询和更新,transaction commit,index rebuild, multi-versioning checkpoints, archiving, WAN replication等。同时IO amplification也是负载相关的。

A:35K HBase OPS就代表着35K的磁盘IOPS,因为workload是纯随机读取,没有其他操作。

Q:可以考虑在HDFS中增加存储设备信息作为API开发给上层。例如对于HBase应用来说,把数据文件存放在机械硬盘上,把WAL和flush file等生命周期短、经常访问的数据存放在SSD上。有点类似于EMC他们经常说的分层存储的概念。

A:这种思路很好,可行性也很高。但是这样的话,瓶颈就会落到CPU核心数目越来越多,这些核心不能被高效利用。(http://pdos.csail.mit.edu/multicore/ 这个项目研究了操作系统和软件在多核处理器上的可扩展性问题)

Q:有人提出混合存储,可以把HDFS的block的第一个备份存在SSD上,另外两个备份存在机械硬盘上。甚至可以指定哪个表,哪个Region,哪个HFile block存放在SSD上。然后读取的时候首先尝试在SSD上的数据,这样就可以显著提升总的读取性能,而且不降低reliability。

A:混合存储的思路也很好,但是一个程序只能从HDFS DataNode上获得16K左右的随机读取OPS,并不能完全利用SSD提供的IOPS潜能。

Q:对于SSD来说,单一进程不能跑满SSD的IOPS,是否可以考虑多个进程实例来共享SSD所能提供的所有的200K+的IOPS呢?

A:是的,事实上在Facebook就是在每个SSD的机器上跑多个进程实例,为的就是提高IOPS的利用率。

总结与感想:SSD改变了传统的基于机械硬盘的IO代价模型,那么对于基于机械硬盘设计的数据库应用来说需要重构了。对于HDFS和HBase应用来说,需要优化的空间也很大,特别是LSM(http://www.springerlink.com/content/rfkpd5yej9v5chrp/?MUD=MP)模型的提出和使用,给HBase设计和优化提供了很大的空间。同时SSD带来了磁盘IOPS的数量级的提升,但是软件逻辑中锁操作使得CPU并不能跑满,所以就提出了单台server跑多个实例的概念,即多进程的概念。Redis也是单线程逻辑,单机多进程部署,从中可以看出软件特别是数据库软件开发的一种回归。多线程程序锁的争用导致CPU利用率低下,使得很多程序开始考虑单线程、多进程的概念,而且降低debug的成本,提高了鲁棒性。听说Amazon推出的DynamoDB也是基于SSD的,后面看看它是怎么用的。

 

转自 http://yanbohappy.sinaapp.com/?p=71

相关文章:

  • oracle db_link
  • Windows Phone 8 Wallet 手机钱包 / 电子钱包
  • jython - 安装
  • STOverlay
  • 学习地址
  • DR模式
  • oracle 不可见索引
  • 写Java程序的三十个基本规则
  • QXDM下查看CDMA短信信息
  • android手机信息表
  • 讯速开源分布式定向采集系统(ispider)
  • XmlReaderSettings类
  • Option parsing
  • 解决iframe显示高度自适应问题
  • (1)Android开发优化---------UI优化
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【前端学习】-粗谈选择器
  • android图片蒙层
  • Angular Elements 及其运作原理
  • ERLANG 网工修炼笔记 ---- UDP
  • HTML中设置input等文本框为不可操作
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • js学习笔记
  • MQ框架的比较
  • Python学习之路16-使用API
  • Vim 折腾记
  • XForms - 更强大的Form
  • 给初学者:JavaScript 中数组操作注意点
  • 关于Java中分层中遇到的一些问题
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 利用DataURL技术在网页上显示图片
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 探索 JS 中的模块化
  • 温故知新之javascript面向对象
  • 鱼骨图 - 如何绘制?
  • ​一些不规范的GTID使用场景
  • #Java第九次作业--输入输出流和文件操作
  • #Linux(make工具和makefile文件以及makefile语法)
  • $forceUpdate()函数
  • (12)Linux 常见的三种进程状态
  • (arch)linux 转换文件编码格式
  • (pytorch进阶之路)扩散概率模型
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (TOJ2804)Even? Odd?
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (一)基于IDEA的JAVA基础12
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转载)从 Java 代码到 Java 堆
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .net 中viewstate的原理和使用
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)