第 5 章 大规模数据流引擎(Large-Scale Dataflow Engines)
原文:Readings in Database Systems, Fifth Edition (2015),Chapter 5: Large-Scale Dataflow Engines,Introduced by Peter Bailis。原书文本采用 CC BY-NC-SA 4.0 许可;本译文按同一许可发布。
导读:Peter Bailis
选读论文
- Jeff Dean and Sanjay Ghemawat. “MapReduce: Simplified Data Processing on Large Clusters.” OSDI, 2004.
- Yuan Yu, Michael Isard, Dennis Fetterly, Mihai Budiu. “DryadLINQ: A System for General-Purpose Distributed Data-Parallel Computing Using a High-Level Language.” OSDI, 2008.
在过去十年数据管理的诸多发展中,MapReduce 以及后续的大规模数据处理系统,是最具颠覆性、也最有争议的一类。廉价的商品化存储和不断增长的数据规模,使许多互联网服务厂商抛弃传统数据库系统和数据仓库,转而构建定制的自研引擎。Google 关于其大规模系统的一系列论文,包括 Google File System [62]、MapReduce、Chubby [32] 和 BigTable [37],也许是市场中最著名、最有影响力的论文。几乎在所有情况下,这些新的自研系统只实现了传统数据库中一小部分功能,包括高级语言、查询优化器和高效执行策略。不过,这些系统以及随之而来的开源 Hadoop 生态,在许多开发者中极受欢迎。这带来了大量投资、营销、研究兴趣,以及围绕这些平台的开发。今天,这些平台仍处在变化中,但作为生态系统,它们已经开始类似传统数据仓库,同时又带有一些重要修改。我们在这里反思这些趋势。
历史与后继者
我们的第一篇阅读材料是 2004 年 Google 最初的 MapReduce 论文。MapReduce 是一个库,旨在简化在 Google 规模下对分布式数据进行并行、分布式计算,尤其是从爬取页面批量重建 Web 搜索索引。当时,传统数据仓库不太可能处理这种工作负载。不过,与传统数据仓库相比,MapReduce 提供的是一个非常低层的接口,即两阶段数据流,并且紧密绑定到一种容错执行策略,即在两阶段数据流之间进行中间结果物化。同样重要的是,MapReduce 被设计为一个并行编程库,而不是端到端数据仓库解决方案;例如,MapReduce 把存储委托给 Google File System。当时,数据库社区成员谴责这种架构过于简单、效率低下且用途有限 [53]。
虽然最初的 MapReduce 论文发布于 2003 年,但直到 2006 年 Yahoo! 开源 Hadoop MapReduce 实现之前,Google 外部的相关活动相对较少。随后,兴趣爆炸式增长:一年之内,包括 Dryad(Microsoft)[89]、Hive(Facebook)[156]、Pig(Yahoo)[123] 在内的一系列项目都在开发中。我们将这些系统称为后 MapReduce 系统。它们在开发者中获得了相当大的牵引力,这些开发者很大程度上集中在硅谷,同时也获得了严肃的风险投资。横跨系统、数据库和网络社区的大量研究,考察了调度、拖尾任务缓解、容错、UDF 查询优化,以及替代编程模型等问题 [16]。
几乎立刻,后 MapReduce 系统就扩展了自己的接口和功能,加入更复杂的声明式接口、查询优化策略和高效运行时。今天的后 MapReduce 系统已经开始实现传统 RDBMS 功能集里越来越大的比例。最新一代数据处理引擎,例如 Spark [163]、F1 [143]、Impala [98]、Tez [1]、Naiad [119]、Flink/Stratosphere [9]、AsterixDB [10] 和 Drill [82],经常做到:第一,暴露 SQL 等更高层查询语言;第二,提供更高级的执行策略,包括处理一般算子图的能力;第三,在可能时使用结构化输入数据源的索引和其他功能。在 Hadoop 生态中,数据流引擎已经成为一套更高层功能和声明式接口的基底,包括 SQL [15, 156]、图处理 [64, 110] 和机器学习 [63, 146]。
人们也越来越关注流处理功能,重新审视数据库社区在 21 世纪头十年开创的许多概念。不断增长的商业和开源生态,已经开发出通向各种结构化和半结构化数据源的“连接器”、目录功能,例如 HCatalog,以及数据服务和有限事务能力,例如 HBase。这些功能中的许多,例如这些框架中的典型查询优化器,与许多成熟商业数据库相比仍然比较初级,但正在快速演化。
本节第二篇选读论文 DryadLINQ,也许最有趣的是它的接口:一组用于数据处理的嵌入式语言绑定,能够与 Microsoft 的 .NET LINQ 无缝集成,提供一个并行化集合库。DryadLINQ 通过更早的 Dryad 系统 [89] 执行查询,Dryad 实现了一个针对任意数据流图的运行时,并采用基于重放的容错。虽然 DryadLINQ 仍然把程序员限制在一组无副作用的数据集转换中,包括“类 SQL”操作,但它呈现了一个比 MapReduce 高得多的接口。DryadLINQ 的语言集成、轻量容错和基本查询优化技术,对后来的数据流系统产生了影响,包括 Apache Spark [163] 和 Microsoft 的 Naiad [119]。
影响与遗产
MapReduce 现象至少有三项持久影响,如果没有它们,这些影响可能不会发生。这些思想,就像分布式数据流本身一样,并不一定新颖,但后 MapReduce 的数据流和存储系统生态,广泛扩大了它们的影响:
-
模式灵活性。也许最重要的是,传统数据仓库系统是围墙花园:被摄取的数据是干净、经过整理且有结构的。相比之下,MapReduce 系统可以处理任意结构的数据,无论干净还是脏乱,是否经过整理都可以。没有加载步骤。这意味着用户可以先存储数据,之后再考虑如何处理它。再加上存储,例如 Hadoop File System 中的存储,比传统数据仓库便宜得多,用户有能力把数据保留得越来越久。这是相对于传统数据仓库的重大变化,也是“大数据”兴起和聚集背后的关键因素。越来越多的存储格式,例如 Avro、Parquet、RCFile,把半结构化数据和列式布局等存储进展结合起来。与 XML 相比,这一波最新的半结构化数据甚至更加灵活。因此,extract-transform-load(ETL)任务成为后 MapReduce 引擎的重要工作负载。很难夸大模式灵活性对现代数据管理实践各层面的影响,从分析师到程序员再到分析厂商都是如此;我们相信它未来会变得更加重要。不过,这种异构性并不是免费的:整理这种“数据湖”非常昂贵,远比存储更贵,而这是我们在第 12 章深入讨论的主题。
-
接口灵活性。今天,几乎所有用户都通过类 SQL 语言与大数据引擎交互。不过,这些引擎也允许用户结合多种范式来编程。例如,一个组织可能在同一个框架内使用命令式代码执行文件解析,使用 SQL 投影某一列,并使用机器学习子例程对结果进行聚类。像 DryadLINQ 那样紧密、惯用的语言集成已经很常见,进一步改善了可编程性。虽然传统数据库引擎历史上支持用户定义函数,但这些新引擎的接口使用户定义计算更容易表达,也更容易把用户定义计算的结果与使用 SQL 等传统关系构造表达的查询结果集成起来。接口灵活性和集成是数据分析产品的强卖点;在单个系统中结合 ETL、分析和后处理,对程序员来说非常方便,但对使用传统 JDBC 接口的传统 BI 工具用户来说,不一定如此。
-
架构灵活性。对 RDBMS 的一个常见批评是,其架构耦合太紧:存储、查询处理、内存管理、事务处理等在实践中紧密交织,彼此之间缺少清晰接口。相比之下,由于自底向上的发展,Hadoop 生态实际上把数据仓库构建成了一系列模块。今天,组织可以针对原始文件系统,例如 HDFS,编写和运行程序;可以使用任意数量的数据流引擎,例如 Spark;可以使用高级分析包,例如 GraphLab [105]、Parameter Server [101];也可以通过 SQL,例如 Impala [98]。这种灵活性增加了性能开销,但在这个规模上混合搭配组件和分析包的能力是前所未有的。这种架构灵活性也许对系统构建者和厂商最有趣,因为他们在设计基础设施产品时拥有了额外自由度。
总结来说,今天分布式数据管理基础设施中的一个主导主题,是灵活性和异构性:存储格式的异构性、计算范式的异构性,以及系统实现的异构性。其中,存储格式异构性可能拥有高出一个数量级甚至更多的影响力,因为它同时影响新手、专家和架构师。相比之下,计算范式异构性主要影响专家和架构师,而系统实现异构性主要影响架构师。这三者都是数据库研究中相关且令人兴奋的发展,但它们的市场影响和持久性仍然存在悬而未决的问题。
展望
在某种意义上,MapReduce 是一种短命的、极端的架构,它打开了一个设计空间。这个架构简单且高度可扩展,它在开源领域的成功让许多人意识到,市场需要替代解决方案,也需要它所体现的灵活性原则,更不用说基于开源的更便宜数据仓库解决方案所代表的市场机会。随之而来的兴趣至今仍让许多人惊讶,它来自许多因素,包括社区时代精神、聪明的营销、经济因素和技术转变。一个有趣的问题是,这些新系统与 RDBMS 之间的哪些差异是根本性的,哪些只是工程改进导致的。
今天,人们仍在争论大规模数据处理的合适架构。例如,Rasmussen 等人有力地论证了为什么中间结果容错只有在非常大的集群,即 100 个以上节点时才有必要 [132]。另一个例子是,McSherry 等人生动地说明了许多工作负载可以用单台服务器,甚至单个线程高效处理,从而完全消除对分布式的需要 [113]。最近,GraphLab 项目 [105] 等系统暗示,为了性能必须使用领域专用系统;后续工作,包括 Grail [58] 和 GraphX [64],则认为情况未必如此。最近还有一波提案,为流处理、图处理、异步编程和通用机器学习提出了新接口和系统。这些专用系统真的必需吗?还是一个分析引擎可以统治一切?时间会给出答案,但我感觉有一股走向整合的推动力。
最后,如果不提 Spark,我们就有失周全。Spark 只有六年历史,但在开发者中越来越受欢迎,并且得到了风险投资支持的初创公司,例如 Databricks,以及 Cloudera、IBM 等成熟公司的有力支持。我们之所以收录 DryadLINQ 作为后 MapReduce 系统的例子,是因为它具有历史意义和技术深度;不过,项目早期写成的 Spark 论文 [163],以及包括 SparkSQL [15] 在内的近期扩展,也值得进一步阅读。和 Hadoop 一样,Spark 在相对早期的成熟阶段就聚集了主要兴趣。今天,Spark 的功能集要与传统数据仓库竞争仍有一段路要走。不过,它的功能集正在快速增长,人们对 Spark 作为 Hadoop 生态中 MapReduce 继任者的期望很高;例如,Cloudera 正在努力用 Spark 替换 Hadoop 生态中的 MapReduce [81]。这些期望是否准确,时间会证明;与此同时,传统数据仓库与后 MapReduce 系统之间的差距正在迅速缩小,最终形成的系统不仅和传统系统一样擅长数据仓库,而且还能做更多事情。
评论:Michael Stonebraker,2015 年 10 月 26 日
最近,作为“大数据”这个营销标签的一部分,人们对数据分析产生了相当大的兴趣。从历史上看,这意味着商业智能(BI)分析,由 BI 应用,例如 Cognos、Business Objects 等,与关系数据仓库,例如 Teradata、Vertica、Redshift、Greenplum 等通信来提供服务。更近一些,它开始与“数据科学”联系在一起。在这个语境下,让我们从十年前的 MapReduce 说起。MapReduce 是 Google 专门为支持其 Web 爬取数据库而构建的。随后,市场人员接管了叙事,其基本论点是:“Google 很聪明;MapReduce 是 Google 的下一件大事,所以它一定很好。” Cloudera、Hortonworks 和 Facebook 站在炒作 MapReduce 及其开源相似物 Hadoop 的前列。几年前,市场一片喧嚣,大家都在喝 MapReduce 的 Kool-Aid。大约同一时期,Google 停止在 MapReduce 原本专门为之构建的应用中使用它,转而迁移到 Bigtable。大约延迟了 5 年之后,世界其他人正在看到 Google 更早就弄明白的事情:MapReduce 并不是一种具有广泛规模适用性的架构。
实际上,MapReduce 遭遇了以下两个问题:
- 它不适合作为构建数据仓库产品的平台。任何商业数据仓库产品内部都没有看起来像 MapReduce 的接口,而且这是有充分理由的。因此,DBMS 并不想要这种平台。
- 它不适合作为构建分布式应用的平台。MapReduce 接口不仅对分布式应用来说不够灵活,而且使用文件系统的消息传递系统实在太慢,不值得关注。
当然,这并没有阻止 MapReduce 厂商。他们只是把自己的平台重新包装成 HDFS,也就是一个文件系统,并基于 HDFS 构建了不包含 MapReduce 的产品。例如,Cloudera 最近推出了 Impala,这是一个 SQL 引擎,并不是构建在 MapReduce 之上。事实上,Impala 其实也不真正使用 HDFS,而是选择钻过这一层,直接读写底层本地 Linux 文件。Hortonworks 和 Facebook 也有类似项目在进行。因此,MapReduce 群体已经变成 SQL 群体,而 MapReduce 作为接口已经成为历史。当然,当 SQL 引擎使用 HDFS 时,HDFS 存在严重问题,所以尚不清楚它是否会有生命力,这还有待观察。无论如何,MapReduce-HDFS 市场将与 SQL 数据仓库市场合并;愿最好的系统胜出。总结来说,MapReduce 作为分布式系统平台已经失败,厂商正在把 HDFS 作为数据仓库产品下方的文件系统使用。
这把我们带到 Spark。支持 Spark 的原始论点是,它是更快版本的 MapReduce。它是一个主内存平台,并带有快速消息传递接口。因此,当用于分布式应用时,它不应遭遇 MapReduce 的性能问题。不过,根据 Spark 主要作者 Matei Zaharia 的说法,超过 70% 的 Spark 访问是通过 SparkSQL 完成的。实际上,Spark 被用作 SQL 引擎,而不是分布式应用平台!在这个语境下,Spark 有身份问题。如果它是 SQL 平台,那么为了在 SQL/数据仓库领域具有竞争力,它需要某种持久化机制、索引、用户之间共享主内存的机制、元数据目录等等。Spark 似乎很可能会沿着 Hadoop 的同一条路径,变成数据仓库平台。
另一方面,Spark 访问中有 30% 不是访问 SparkSQL,并且主要来自 Scala。可以推测,这是分布式计算负载。在这个语境下,Spark 是一个合理的分布式计算平台。不过,有几个问题值得考虑。第一,普通数据科学家会混合进行数据管理和分析。更高性能来自二者的紧密耦合。在 Spark 中并没有这种耦合,因为 Spark 在这两个任务上的数据格式并不一定通用。第二,Spark 是纯主内存的,至少目前如此。可扩展性需求大概会随时间修复这一点。因此,观察 Spark 未来如何演化会很有趣。
总结来说,我想提出以下几点启示:
- 仅仅因为 Google 认为某件事是好主意,并不意味着你应该采用它。
- 不要相信所有营销话术,要弄清楚任何给定产品实际具有什么收益。尤其应该把这一点应用到性能声明上。
- 程序员社区迷恋“下一个闪亮物”。这很可能在你的组织中制造“扰动”,因为闪亮物的“半衰期”可能相当短。