背景介绍
阿里云E-MapReduce公测以来,陆陆续续有一批用户开始在E-MapReduce上创建和使用集群。在和客户的交流和沟通过程中,我们发现这样一个现象:大部分用户更倾向于将数据存储在自建的集群HDFS中。这里面有几种考虑:
- 使用习惯:很多用户曾经线下或者线上运维过自己的集群,业务数据都是存放在集群的HDFS中。他们熟悉HDFS这一套,并且在使用HDFS上具有一定的经验。
- 性能考虑:将数据存在在HDFS中,可以在计算时充分利用数据本地性来提高计算性能。将数据存放在OSS上,计算时需要经过网络从远端拉取一次数据,存储时需要经过网络将数据上传上去,这部分开销将影响作业的整体性能。
- 不了解OSS:也有一部分用户对OSS不了解或者根本不知道。
对于数据应该存储在HDFS还是OSS的问题,我们说其实都是可以的。不管HDFS还是OSS,都是稳定可靠的数据存储系统。但是我们推荐用户将数据或者部分冷数据存储在OSS中,这是基于以下考虑:
- OSS的存储成本相较于ECS配属的云磁盘要更低。
- OSS存储的安全,高可靠和弹性扩展,可以让用户更专注与计算本身,不再分散精力到HDFS系统的运维上。
- 存储计算分离思想
计算存储分离
部署一个集群大体上可以分为两类:混合部署和分离部署。混合部署指的是计算和数据存储部署在一个集群中;分离部署指的是计算和数据存储分别部署在不同的集群中。下面两张图可以直观看出来:
早期将HDFS和Hadoop部署在一起时,可以利用数据本地化特性来提升作业性能。但目前看来,“数据本地化(data locality)”的概念已过时。在许多Hadoop场景中,即使计算和数据存储部署在一个集群,Hadoop作业也无法受益于数据本地化。然而将计算和存储分开可以简化操作,用户可以分别扩展和管理计算和存储系统。
- 对于计算和存储来说,所需要的机器类型也是不一样的。对于HDFS来说,你可能需要更大的磁盘空间;对于Hadoop/Spark来说你可能需要更多的CPU和更大的内存。针对HDFS和Hadoop/Spark选择合适的机型,可以让集群发挥更大的能力。
- 从集群扩展角度来说,随着业务的发展,集群的规模常常不能满足业务的需求。也许是数据规模超过了集群存储能力,也许是业务上对数据产出的周期提出新的要求导致计算能力跟不上。这就要求我们能随时应对集群存储空间不足或者计算能力不足的挑战。将计算和存储分离,可能更好地应对单方面的不足。如果将计算和存储混合部署,常常会因为为了扩存储而带来额外的计算扩容,这其实就是一种
浪费
;同理,只为了提升计算能力,也会带来一段时期的存储浪费。 - E-MapReduce的一个很大的特性是按需创建集群,也就是需要处理数据时才去创建集群,用完即可销毁。这种模式很适合那些只需要每天定时离线处理的场景,例如产出每天报表等等。但是,这种模式也带来一个要求,集群不能存放数据,否则集群释放后数据也就丢失。这就给那些希望用集群来存放数据的用户代码麻烦。计算和存储分离可以很好地解决这个问题,你只需要保证存储集群长期运行即可,计算集群可以随时使用随时创建,增加使用的灵活性。
这里只是简单说一下E-MapReduce上计算和存储分离带来的好处,关于存储计算分离部署的讨论还有很多,这里就不再赘述。
新的选择
上一节说到了计算存储分离的优势,如果你认可这一点,那么看完这一节你还会有更多收获。现在我们部署集群时,就有Hadoop和HDFS两个集群。使用开源软件时,我们一方面享受到技术贡献的便利,同时也不得不面对服务稳定性难以保证的问题。对于数据来说,服务的稳定性和安全性是高于一切的。所以,服务稳定性,数据安全性等等问题成为我们日常维护集群所不得不面对的问题。今天,在阿里云上,已经提供类似的产品来将你从这一切繁琐的问题中解脱出来,这就是OSS。OSS是阿里云提供的海量、安全和高可靠的云存储服务。存储容量和处理能力的弹性扩展使你专注于核心业务。有了OSS,我们可以这么玩集群部署:
有了OSS存储数据,我们接下来要面对的问题是如何在MR,Hive,Pig以及Spark作业中支持OSS数据源。虽然作业种类很多,但追根溯源,我们发现只要在Hadoop上实现对OSS的支持即可。Hive和Pig实际上就是分解成很多个MR作业来处理的,而Spark也是通过Hadoop接口来实现对HDFS类文件系统的支持。有了这个思路,我们就可以很方便地实现Hadoop上对OSS的支持了。
OSS通用支持2.0
我们已经将这一部分代码开源,有兴趣的可以看这里,也欢迎大家贡献代码(Bug fix或者New feature)。本节,我们不会去谈Hadoop中如何支持OSS数据源的实现细节,而是去谈谈实际线上用户使用Hadoop+OSS时碰到的性能问题:
数据读:一份相同大小的数据从OSS读过来的时间比直接从HDFS读的时间长。核心问题是网络带宽,包括集群机器的网络带宽以及OSS出数据的通道带宽。这个问题超出了E-MapReduce产品本身的范畴,需要协同OSS以及ECS来共同解决。但从实际效果看,这个读数据时间开销的差距是在可接受的范围之内,相对于作业的整体处理时间,这个读数据时间差别占了很小的部分,不会成为block作业生产的原因。当然如果OSS数据源性能真的成为瓶颈,那就得具体问题具体分析,不属于本篇文章范畴了。
- 结论:读数据时,确实存在一定的性能差距,差距不大。
数据写:一份相同大小的数据写OSS比写HDFS的时间长,当写大数据量时尤为明显,甚至达到几倍的时间。这个问题比较特殊,通过分析我们发现,整个写数据的过程可以细化为下面两个阶段:
- 从E-MapReduce集群端到OSS存储端的网络传输阶段。和读数据类似,这部分确实也存在这一定的性能差距,但差距不大,是在作业生产的可接受范围之内。
- 数据在OSS内部的拷贝阶段。由于Hadoop的底层实现机制,作业的输出数据首先会写到一个临时目录中,作业完成后结束前,将数据拷贝到最终目录,这一过程会多次发生。由于OSS的保护机制,数据在OSS内部的拷贝是有限制的,整体给与的带宽很小,这直接导致了数据输出过程会很“漫长”。
上面我们分析了将OSS作为数据源时存在的两类问题。其中一类问题集中在OSS端与E-MapReduce端的网络带宽问题,这个问题的影响实际上是有限的,也可以在今后不断提升基础设施来解决。另一类突出问题是Hadoop的执行机制和OSS的保护机制共同导致的,产生的影响也严重。第二个问题不解决,那么Hadoop+OSS只能是一个玩具,无法提供生产级别的作用。不过凡事也有特例,第二个问题对MR,Hive和Pig类型作业影响巨大,但对Spark作业的影响又小了很多。因为Spark执行过程中,数据都只会在E-MapReduce集群中转来转去,直到最终结果写OSS。而MR,Hive和Pig的执行过程中,中间结果会多次落回到OSS上,类比于HDFS,这样的影响就会多次放大! 今天,我们很高兴地告诉大家,通过对Hadoop底层代码的优化,我们已经较好地解决了因为数据拷贝问题导致的性能问题,最新的EMR_1.1.0
镜像将使用优化后的Hadoop版本。下面我们来简单跑几个作业来看看效果把。
性能测试
集群配置
机型:4核,8GB内存, 200GB高效云盘
规模:11台,1台Master节点,10台Slave节点
测试作业
作业:TextGenerator,随机生产一定量的文本数据。
类型:Spark
配置:--driver-memory 1G --executor-memory 4G --executor-cores 4 --num-executors 10
并发:1024个partition
结果对比
- 上图红线有个比较奇怪的变化,也就是200G数据写的耗时比10G数据要少。这是因为在底层实现上,当task的输出数据比较小时,采用直接上传的方式;当task的输出数据比较大时,采用direct multipart upload方式。在200GB数据时,产生了奇怪的耗时更少的现象。
- 数据量在200G时,性能提升了12倍;数据量在1T时,性能提升了10.6倍。
结语
我们可以看出,在EMR1.1.0版本集群中,Hadoop写OSS的性能得到了显著的提升。这个优化可以极大地提升在E-MapReduce上使用MR,Hive和Pig分析OSS数据的使用感受。当然,在Hadoop上支持OSS数据源的实现方式还有很多有待提升的地方,欢迎大家参与到E-MapReduce的开源项目中。