谷歌MapReduce比Spark强在哪里?

发布于 2021-05-13 21:38 ,所属分类:数据库和大数据技术学习资料

10几年前,大家聊大数据总是聊这样的一个故事。谷歌的三驾马车开启了大数据的新时代。然后Hadoop则带来了开源的生态。当然,和谷歌同一个时代的还有Michael Stonebraker说的MapReduce-a major step backward。


之后就是和Hadoop生态圈若即若离的Spark,一开始通过猥琐发育,和Hadoop打成一片,后来自己开始做Spark Summit,干翻了整个Hadoop,成为了现在大数据领域当之无愧的标准。


这么多年过去了,谷歌的MapReduce也发展出了Flume,在内部使用。当然同一个团队还做了Millwheel的流引擎。但是有一个问题可能一直都没被人讨论过:谷歌的MapReduce到底比Spark强在哪里?


这个问题可以换个说法,谷歌的MapReduce和Hadoop的MapReduce有什么不一样吗?


其实问题都是等价的。我们先看看Spark吧。Spark从诞生到今天,有一个问题一直都在困扰着Spark,这个问题就是shuffle。


Spark做shuffle的办法是(我简化一下),每个Mapper把自己的shuffle 文件写到本地盘,然后,后面的executor就可以来读这些文件了。


这个做法有一个要求,这个写了本地文件的executor必须活着,不然的话这些本地文件也跟着丢了。丢了只能从上一步开始重新执行。所以一旦因为什么原因导致这个executor被砍,就会付出巨大代价。


解决问题的办法,好像是Spark 1.2就开始有了,可以引入一个external shuffle service。让这个long running process来接管这些文件的控制。这个做法不是没有副作用,这很容易就导致本地盘被写满。


由于这个写本地盘读本地盘的问题,Uber,LinkedIn等公司又开始引入自己的external shuffle service。而Spark3开始引入的dynamic allocation又导致了一些其他问题,这使得Spark开始记录哪些本地shuffle文件被哪些executor给使用了,以及为了防止一个executor跑太久,还增加了最久多久要timeout的选项等等。这个问题还导致了K8S做autoscaling的时候scale down总出问题。


听起来这是个很复杂的问题,需要各种各样的调参。


谷歌的MapReduce怎么解决这个问题的呢?Mapper直接写进Google File System。Reducer直接读Google File System。这些shuffle文件是不是存在是由GFS来管的。


Hadoop也是这样做的,但是效果非常的惨烈。因为HDFS作为一个文件系统性能太差了。而GFS不一样,性能好,尤其是二代GFS,完全可以当做一个巨大容量的本地盘用。


所以,只要有一个性能很好的分布式文件系统,shuffle就不是一个天大的问题。Spark的shuffle搞的如此复杂,问题频出,各种补救,到底是Spark自己的问题还是Spark缺了一个高性能的分布式文件系统来存shuffle的文件呢?


谷歌的MapReduce很强,其实就强在了谷歌的GFS牛逼。到今天看,shuffle文件写本地盘,然后硬撑着不死掉让其他人来读的设计,实在不知道说什么了。但是Spark根本就没有一个高性能的分布式文件系统啊,只能一边哭,一边写本地盘了。


微软搞Cosmos的时候,也是用了自己的分布式文件系统来解决这个问题的。但是微软取巧的办法是数据只写一份,进本地盘,元数据则直接进元数据服务了。这样就算executor死了,文件大概率并不会丢,只不过只有一份而非三份冗余。


当然,谷歌文件系统牛逼,不能改变MapReduce这个东西本身是屎的本质。Spark的shuffle一直都在苦苦挣扎,也不能改变Spark本身计算模型更牛逼的事实。只不过,屎也可以建立在牢固的地基上,牛逼的东西也可以建立在屎堆里。

相关资源