【译论】现在还有人使用 MapReduce 吗?为什么?
除 Hadoop 生态系统外,我还在其他数据库和分析工具(如 MatLab)中看到一些对 MapReduce 的引用。在我的印象中,Spark 完全取代了 MapReduce。是否只是 MapReduce 的实现方式不同,而 Hadoop 实现的 MapReduce 被 Spark 取代了?
本文文字及图片出自 Ask HN: Does (or why does) anyone use MapReduce anymore?
你也许感兴趣的:
- 为什么Google用Apache Beam彻底替换掉MapReduce
- 如何简单解释 MapReduce 算法
- 【外评】电脑从哪里获取时间?
- 【外评】为什么 Stack Overflow 正在消失?
- Android 全力押注 Rust,Linux 却在原地踏步?谷歌:用 Rust 重写固件太简单了!
- 【外评】哪些开源项目被广泛使用,但仅由少数人维护?
- 【外评】好的重构与不好的重构
- C 语言老将从中作梗,Rust for Linux 项目内讧升级!核心维护者愤然离职:不受尊重、热情被消耗光
- 【外评】代码审查反模式
- 我受够了维护 AI 生成的代码
(这里是Spark的第二位用户和开发者)。这取决于您的要求。MapReduce 框架是谷歌专有的,有些管道仍在谷歌内部运行。MapReduce 作为一个概念,目前仍在广泛使用。Hadoop 受到 MapReduce 的启发。Spark 最初是围绕 MapReduce 的基元构建的,这一点在其操作(交换、收集)的描述中仍能看到。然而,Spark 和所有其他现代框架都意识到了这一点:- 用户并不关心映射和还原,他们需要更高级别的基元(过滤、连接……)。- mapreduce 非常适合一次性批量处理数据,但却难以适应其他非常常见的大规模用例(低延迟、图处理、流式处理、分布式机器学习……)。你可以在 mapreduce 的基础上实现这些功能,但如果你真的开始针对具体情况进行调整,你最终会得到截然不同的结果。例如,kafka(可扩展流引擎)的灵感来源于 MR 的一般原理,但现在的用例和 API 已大不相同。
另请参见 https://news.ycombinator.com/item?id=37313576
其实一直都只有 Map 和 Shuffle(Reduce 就是 Shuffle+Map;Shuffle 的另一个名字是 GroupByKey)。你可以在大多数并行系统的引擎盖下看到这些原语。
Reduce 对于汇总指标很有用。
我想说的是,Reduce 就是 Shuffle+Map,没有将中间结果(Shuffle 后的结果)具体化。
Shuffle 很有意思,我得好好读读。也许是我听 reduce 听得太久了,对它有太多的固有视觉感,但是……shuffle 这个名字似乎一点也不合适,我想象的是随机化某个集合 N,输入和输出的数量是相同的。
洗牌是将”{k1,v1},{k1,v2},{k2,v3}”转换为”{k1,[v1,v2]},{k2,[v3]}”的操作。
例如,kafka(可扩展流引擎)的灵感来源于 MR 的一般原理,但现在的用例和 API 已大不相同。
你是不是把 Kafka 和别的东西搞混了?Kafka 是一个持久写附加队列。
流式系统》一书回答了你的问题和更多问题:https://www.oreilly.com/library/view/streaming-systems/97814….。这本书为您介绍了批处理如何从 MapReduce 开始,以及如何通过转向流式系统来尝试扩展,从而为我们提供了所有后续框架(Spark、Beam 等)的历史。
至于 MapReduce 框架,它的使用率并不高,但其后代 https://beam.apache.org 的使用率却很高。现在,人们经常使用 “map reduce “作为在其基础上构建的批处理系统的简称。
这本书看起来很有趣,我是否应该买下来,还是其他人有更新的推荐?我有《设计数据密集型应用》(Designing Data-Intensive Applications)一书,它是一本非常棒的综述,现在仍然很好用。
这是 DDIA 之前该领域的””书籍之一。在我看来,Akidao 将处理事件的逻辑与流基础架构的实现混为一谈,因为他是根据自己的特定用例来写作的。在我与他交谈的过程中,他的影响似乎推动了谷歌系统和 GCP 的设计,使其没有正确地优先考虑顺序/线性/一致性要求。在这一点上,我对我的副本具有历史意义。
这本书对流媒体系统语义(如窗口和有状态流操作的相互作用)进行了最有趣/概念性/详细的讨论。至少在 Manning/O’Reilly 级别的书籍中是如此。所以我会把它和 DDIA 放在同一个书架上。
不过这本书有点偏向于 Beam,而不是 Spark/Flink。这使得它的实用性较弱,概念性较强。因此,只要它是你的那杯茶,那就买吧。
谢谢,我会去看看的!
我觉得这有点像说,既然有了 C 语言,我们就不再使用汇编语言了。
是的,我正是这样理解这个问题的,即类似于 “现在还有人用汇编编码吗,还是每个人都转而使用抽象概念了?”我认为这是一个非常有趣的问题。
这个问题更像是 “是否还有人在使用 goto”。
既然可以使用整个 DAG 进行扇出/扇入,为什么还要使用 map:reduce?
从高层次来看,大多数分布式数据系统都类似于 MapReduce,而这实际上只是花哨的分而治之。这很难进行推理,而且这种规模的数据大多是表格数据,所以你通常最好使用可以编写 SQL 查询的系统,让查询引擎来完成底层的 MapReduce 工作。
这个概念很有生命力,花哨的深度学习就有它:jax.lax.map、jax.lax.reduce。
它将继续存在,因为它很有用:
任何可以用关联行为表达的操作都可以自动并行化。在 Spark 和 Torch/Jax 中,这都意味着可扩展到集群,代码可扩展到数据。这就是解决更大问题的不公平优势。
如果您说的是 Hadoop 生态系统,那么是的,Spark 几乎做到了这一点,并且占据了主导地位(无需其他实现)。
这就是我的理解。MR 非常简单,而且笨拙/无法用它来表达许多问题,而像 Spark 和 Apache Beam 这样的数据流处理器支持创建复杂的 DAG,其中包含丰富的分组、窗口、连接等运算符,而 MR 中却没有这些运算符。您可以在 DAG 中执行 MR,因此可以说数据流是 MR 模型的概括或超集。
> 你可以在 DAG 中执行 MR,因此可以说数据流是 MR 模型的概括或超集。
我认为情况恰恰相反。MapReduce 是一种非常通用的机制,用于拆分计算,使其可以分布式进行。从 MapReduce 操作中构建 Spark/Beam 及其所有更高级别的 DAG 组件是可能的。
我的意思不是这样概括的。正如你所说,数据流运算符可以用 MR 作为底层原语来表达。但至少在原始论文中描述的 MR 本身,只有 map 和 reduce 两个阶段;它不是一个数据流系统。而事实证明,人们需要的是数据流系统,而不是手工编写 MR 代码并手动完成 DAG。
我不确定你所描述的是否相反?
我的意思是,你可以用 GOTO 和条件分支来实现函数调用(以及异常或循环等其他控制流操作符),编译器就是这么做的。
但这并不意味着将 GOTO 视为一般化就有用。
大多数时候,情况恰恰相反:你可以将 GOTO 视为一种非常特殊的函数调用,一种不带任何参数的尾调用。参见 https://www2.cs.sfu.ca/CourseCentral/383/havens/pubs/lambda-…
MapReduce 基本上是一种执行可扩展的、大于内存的按键聚合操作的非常冗长/费时的方法。
作为第一步,它是必要的,但当我们有了更好的抽象后,每个人都不再直接使用它了,当然传统维护除外。
抽象是第一位的。MapReduce 很快被用作大于机器的 SQL(Google Dremel 和 Hadoop Pig)的基础。当处理过程需要大量自定义代码,而这些代码又不能很好地融入 SQL 时(例如,因为你有分层记录,而不是纯粹的关系型记录),MapReduce 就单独派上用场了。
能否请您指出更好的抽象方法?
我想到了 SQL。
例如,每次在 BigQuery 上运行 SQL 查询时,都是在底层数据上执行相同的基本映射洗牌原语,只是界面截然不同而已。
现在,你已经很少使用基本的 MapReduce 基元了,你有了另一层抽象,可以在之前运行 MR 作业的基础架构上运行。这种基础架构可以根据内存/CPU/网络和其他限制条件,为大型集群中 “长期 “运行的任务有效分配计算资源。因此,从根本上说,MapReduce 作业的调度器和集群管理工具变得如此出色,是因为 MR 方法学的抽象概念微不足道,但需要高效的实施才能使其无缝运行。
现在,在这一基础架构之上的抽象层可以通过在可能的情况下将多个步骤合并为一个步骤、添加组合器(在洗牌前进行部分还原)来优化整个管道。这就要求在更具体的操作中定义整个处理管道。有些人建议使用 SQL 来制定任务,但也可以使用其他原语。与 MapReduce 相比,在 MapReduce 中,用户需要考虑所有优化,并在单个 map/reduce/(组合)操作中实现这些优化。
map reduce 的想法仍然很好。
随后,流式系统出现了许多有趣的创新,主要是围绕减少延迟、减少批量大小和故障策略。
即使是 hadoop,当遇到具有挑战性的工作负载的性能上限时,也很难进行调试。流式系统在这方面走得更远,火花系统(spark)在几个小时后又一次因为摆弄旋钮和祈祷下一个任务不会失败而声名狼藉。
我想了解不同工作负载的性能上限,而不需要所有密不透风的软件官僚层。事实证明,当你不再像烤宽面条那样随意添加层级时,现代网络和 CPU 的速度真的很快。
我认为,对于严肃的工作负载而言,数据的未来将是定制的。现在的原语实在是太好用了,而在可理解性方面所付出的代价往往是值得的。
1. https://github.com/nathants/s4
https://github.com/nathants/bsv
它无疑起到了点睛之笔的作用,让大多数精通函数的程序员了解到:map/filter/reduce 是数据处理管道的绝佳模型。
需要注意的是:像 Hadoop 这样的系统是通过添加键来实现并行化的,而那些 FP 结构并不具备这种能力。最好将其视为并行的 “分而治之”。
我觉得,即使在单机上,mapreduce 的许多底层概念在多线程应用中也能发挥巨大作用。
这绝对不是一个过时的概念,但我想它并不性感。
paradiagm非常有生命力。看看 elasticsearch 中的 Query_then_fetch
在我的印象中,Map:Reduce 基本上是基于 DAG 的管道的一种奇怪表现形式。
我想是因为它看起来有点像从字典到多线程的自动转换器,所以很受欢迎。但是,除非你知道如何拆分和处理数据,否则它非常没用。
基本上,如果你能将数据分割成队列,你就能使用 MapReduce。但是,大多数流水线比这更复杂,所以你可能需要一个适当的、带有依赖关系的 DAG。
一如既往,查询数据的正确语言是 SQL。没有人会关心实现细节。
“我有数据,我懂 SQL。你们的数据库是如何让数据检索变得更好的?
任何其他范例充其量只能算是小众,很可能会彻底失败。
Spark真的失败了。SQL 缺乏类型安全性、可测试性和可组合性。
想想我现在都多大年纪了,真让人抓狂。但再过 20 年,你就会明白了。
同意/不同意。我希望(也许这就是 “答案”)能将基本 SQL 查询 “反转 “为可组合组件。
在一些 “小数据 “黑客项目中,我经常做的一件事就是极其自由地使用 SQLite:select … union ( 选择 … …GROUP BY … ( UNION … etc ) ) … 绝对糟糕的 SQL,但它完成了工作,返回了我感兴趣的 100 多条记录。
如果我能写一些 SQL,然后将其输出为:fn_group001,fn_join(g1, g2, cols(c1, c2)), ……等等,那就太好了。
……然后,就可以用 group().chain().join(…) 的方式,获得 SQL-COBOL 语法所支持的可组合的子组件。
我觉得 DataLog 一直是我推荐的东西,当然 ProLog 也有一些相似之处。
没有什么足以让人放弃使用 SQL,但我确实同意祖辈们的意见:SQL(又名:COBOL)非常笨拙,而且不具备可组合性,这让你认为简单的交互式非编程使用变得复杂。
20 年前,SQL 缺乏类型安全性、可测试性和可组合性。如今也是如此。我怀疑 20 年后的情况会有所不同。
SQL 功能强大。但它也很老旧,有很大的缺陷。
所有数据查询语言最终都会简化为 SQL 或与之相当的语言。
行吗?即使这是真的–我也不完全确定你如何证明这一点–SQL 仍然缺乏类型安全性、可测试性和可组合性。
SQL 具有类型安全性。它的主要目的是拥有类型化模式。除了一些迂腐的理由,我想不出你为什么会这么说。像 Postgres 这样的 SQL 实现会很乐意在你的类型出现偏差时抛出错误。
可测试性–你使用通用语言来执行 SQL。我还是不明白你的意思。
可组合性–我想是的,但请记住 SQL 是一种检索数据的语言。我在通用语言中到处重复使用片段。
那就用更好的语言,让编译器来优化?
查询规划器会对其进行优化。为什么要让编译器优化 SQL?数据的性质会影响优化的方式!必须根据数据的性质来解释检索数据的声明语句。如果不了解数据的一些情况,就无法预先优化,在这种情况下,你基本上是在数据库之外存储了一些信息。
我的意思是根本不要使用 SQL。使用真正的编程语言,如 Scala,让 Spark(或 Flink 等)进行翻译和优化:https://www.databricks.com/glossary/catalyst-optimizer
我不明白为什么除了简单的 SQL 查询之外,还有人会选择 SQL。这不仅仅是我的观点:整个行业都在使用 Spark 进行复杂查询的生产。SQL 是为分析师准备的。
现在我完全糊涂了。SQL 是一种查询数据的语法。Spark SQL 就是 SQL。你说的是服务器的不同实现。
SQL 是为分析师准备的?每个人都使用 SQL。
您对 Spark 等软件熟悉吗?看起来就是这样:
https://spark.apache.org/examples.html
SQL 只是一个 DSL;它不是 Spark 唯一或主要的 API,也没有什么神奇之处。如果抛弃它,你就能重新获得类型安全性、可组合性和可测试性,就像这样:
https://medium.com/@sergey.kotlov/unit-testing-of-spark-appl…
看到那些整齐封装业务对象的案例类了吗?再加上能简洁表达过滤、映射等典型操作的功能转换,你就能得到比 SQL 更好的东西。
任何 ORM 都能为任何 SQL 数据库提供相同的功能。这里没有什么特别之处。如果数据库自动生成了一堆类,也许会很有趣?我想有些项目已经反省过数据库,并创建了所有模板语言类。
用语言类封装数据库对象并没有什么神奇之处。这种情况一直都在发生。
https://docs.sqlalchemy.org/en/20/orm/quickstart.html#select…
使用函数调用而不是原始 SQL 也没什么神奇的。
不,不会。此外,如果你使用 ORM,你就不再是在用 SQL 编程了。你使用的是穷人版的 Spark。Spark 的所有应用程序接口也都允许你下放到 SQL。
如果你喜欢使用 ORM,那我就不明白你的论点了。
我都不知道我们在争论什么。Spark 是用于大数据工作的,而不是你通常会用作应用程序的通用数据库。我最初的观点是,期望客户学习一种全新的数据存储和查询模式是一个错误的决定,而且会将你的工作限制在利基用例上。Spark 有一个很大的利基市场,但它无法与 MySQL / Postgres 或 Dynamo 等其他新型数据存储相提并论。
此外,任何有能力的工程师都知道 SQL,因为 ORM 除了基本用途外,对于其他任何东西来说都是繁琐而令人讨厌的。
我认为语言设计中最大的失误之一就是将强大的关系数据库和查询模型直接集成到现代语言中。不是作为一个附加组件或 ORM,而是与映射和数组一样,作为语言的首要组成部分。让语言以关系的方式处理数据,让关系查询成为语言的核心部分,让关系查询的执行融入语言的运行时。
如果持久性钩子也被嵌入其中,那么你就会拥有一种有点像数据库中存储过程的语言,但功能要强大得多,而且语法也更现代。再加上支持基于 CRDT 的最终一致性或通过 raft/paxos 实现同步的分布式数据库层,你将拥有一个令人惊叹的应用平台。
数据是我们所做一切的核心,但从几乎所有编程语言和运行环境的角度来看,数据却像是被附加的二等公民,这让我感到很无奈。”哦,你想处理数据?我们可没想到这一点……”访问数据需要奇怪的咒语和黑客手段,感觉就像进入了 20 世纪 70 年代的时空隧道,进入了 PDP-11 主机。
相反,语言和运行环境应该围绕数据构建。把数据放在中心,就像哥白尼对太阳所做的那样。
为什么没人这么做?有人尝试过吗?
数据访问是所有编程语言最关心的问题,可以使用内存或磁盘。磁盘上的所有文件都可视为数据库的一种形式。读写文件是所有语言的标准。
一旦文件开始变得越来越复杂,数据量越来越大,就需要特殊的读取方式。Postgres 数据库可以看作是磁盘上的一个大文件。Postgres 服务器需要以最有效的方式访问文件,以存储和随机访问海量的一般数据。
SQLite 的有趣之处在于它没有服务器,它只是一个特殊的库,可以实现对单个文件的高效随机访问,可以将其视为一个黑盒子,只有 SQLite 知道如何解释它。
除非你的意思是,让类似 SQL 的东西作为一等公民直接内置于语言中。Mumps 的做法是这样的 https://en.wikipedia.org/wiki/MUMPS
考虑到我几十年的经验和预期退休年龄,我觉得不太可能。
与其他人编写的 1000 多行 SQL 脚本打交道可不是什么好玩的事。为什么不使用 Scala 这样的表达式语言将其分解为可读、可测试的函数呢?
年纪大并不会自动让你更正确。智慧不是生日礼物。
但是,如果你做过很多事情,你就会知道哪些是行不通的,为什么行不通。与科普文章类似,没有人充分讨论过 “X 技术不适用于 Y 领域”,因此很多人试图 “重新发明轮子”,却发现 “X 技术不适用于 Y 领域”。偶尔也会有惊喜(因为某些技术的进步),但年长的人肯定会对可能出现的问题有更多的洞察力。
另一方面,你往往能从经验中获得智慧,而经验往往与年龄成正比。
这确实取决于经验,每个人都会以这样或那样的方式获得经验。
我不知道会不会自动,但肯定更有可能。
在我现在的工作中,有几个人在二十年的时间里重复着一到三年的工作经验。这种可能性可能比 HN 某些人希望的要小。
没有,但你确实积累了经验,就像三十年前有人 “发明 “这个想法时一样,完全是一盘散沙,不知道现在发生了什么变化?
哦,对了,新的语言:
既然新语言不能解决问题,那你还在用 COBOL、FORTRAN 和 BASIC 吗?
我知道我在回复一个巨魔的评论,但是:
> “我有数据,我懂 SQL。你们的数据库有什么地方能让检索数据变得更好?
因为我的数据来自各种非结构化的、可能是脏的数据源,这些数据需要先进行清理和转换,然后才能变得有意义。
> 因为我的数据来自各种非结构化的、可能很脏的来源,需要进行清理和转换,才能使它们变得有意义。
西雅图数据人最近发布了一个很棒的年终十大备忘录,其中一条是这样的
> 你聘请了一位数据科学家,所以你有了一系列可靠且易于查询的数据源,对吗?
> …
> 你确实有一批可靠且易于查询的数据源,对吗?
—
就像企业中的大多数情况一样……如果数据不能用 SQL 查询,那么它就不能被企业的其他部门使用。无论是仪表盘、监控、下游分析还是报告。数据工程师负责清理肮脏的数据。数据科学家负责实际的科学工作。
至少这是我从家长那里学到的。
显然,这取决于你的领域。ML 就是一个很好的例子,它可以直接对 wav 文件进行端到端语音到文本的处理。
没错。有了 dbt(=SQL+Jinja-Templating in an opionated framework),庞大的 SQL 代码库实际上变得可以维护了。如果可能的话,我通常会将原始数据加载到 OLAP 表(Snowflake、BigQuery)中,然后在那里进行所有转换。至少对于 JSON 数据来说,这样做效果非常好。将其与 dbt 测试相结合,就能确保安全。
请参见 https://www.getdbt.com/
你竟然认为我在耍花招!像新数据库这样极端的东西,要想获得更多客户,首要方法就是使用潜在客户已经熟悉并集成到他们系统中的工具。这就是 SQL。同样的逻辑也适用于任何新模式。
无视这种说法,打一场艰苦的战斗。
你不知道在 BigCorps 中,基于 MR 的传统每日统计汇总工作流程的尾巴有多长。
批量每日日志处理器工作的持续时间比 Fortran 更长。比 Cobol 还长。比地球本身还长。
> 日志处理器的批处理工作比 Fortran.比 Cobol 还长。
胡说八道…它们会在同一时间结束。大约与宇宙同时结束。
或 2037 年