在 Apache Spark 的上下文中,内存数据存储意味着啥?
Posted
技术标签:
【中文标题】在 Apache Spark 的上下文中,内存数据存储意味着啥?【英文标题】:What does in-memory data storage mean in the context of Apache Spark?在 Apache Spark 的上下文中,内存数据存储意味着什么? 【发布时间】:2014-08-15 21:39:08 【问题描述】:我读到 Apache Spark 将数据存储在内存中。但是,Apache Spark 旨在分析大量数据(也称为大数据分析)。在这种情况下,内存数据存储的真正含义是什么?它可以存储的数据是否受可用 RAM 的限制?它的数据存储与使用 HDFS 的 Apache Hadoop 相比如何?
【问题讨论】:
我在学校被教导任何计算都必须发生在内存中,所以我假设 Hadoop 的映射和归约阶段发生在(集群节点的)内存中。但是 Hadoop 在 map 和 reduce 阶段之间将数据持久化到磁盘?这是 Spark 通过在内存中做所有事情来避免的吗? 【参考方案1】:在 Hadoop 中,数据在步骤之间被持久化到磁盘,因此典型的多步骤作业最终看起来像这样:
hdfs -> read & map -> persist -> read & reduce -> hdfs -> read & map -> persist -> read and reduce -> hdfs
这是一个绝妙的设计,当您对非常适合 map-reduce 模式的文件进行批处理时,使用它非常有意义。但是对于某些工作负载,这可能会非常缓慢 - 迭代算法尤其受到负面影响。您已经花时间创建了一些数据结构(例如图表),而您在每一步中想要做的就是更新分数。将整个图表持久保存到磁盘或从磁盘读取整个图表会减慢您的工作速度。
Spark 使用更通用的引擎来支持循环数据流,并且会尝试在作业步骤之间将内容保存在内存中。这意味着,如果您可以创建数据结构和分区策略,您的数据不会在工作的每个步骤之间移动,您可以有效地更新它,而无需在步骤之间序列化并将所有内容写入磁盘。这就是为什么 Spark 在他们的首页上有一张图表,显示逻辑回归的速度提高了 100 倍。
如果您编写一个 Spark 作业,该作业仅从数据集中的每个输入行计算一个值,然后将其写回磁盘,则 Hadoop 和 Spark 在性能方面几乎相等(Spark 的启动时间更快,但是当我们花费数小时在一个步骤中处理数据时,这几乎无关紧要)。
如果 Spark 无法在步骤之间将 RDD 保存在内存中,它会将其溢出到磁盘,就像 Hadoop 一样。但请记住,Spark 不是灵丹妙药,在某些极端情况下,您将不得不与 Spark 的内存中特性导致 OutOfMemory 问题作斗争,此时 Hadoop 只会将所有内容写入磁盘。
我个人喜欢这样想:在您的 500 台 64GB 机器集群中,创建 Hadoop 是为了通过分布磁盘读取和写入更快地高效批处理您的 500 TB 作业。 Spark 利用了这样一个事实,即 500*64GB=32TB 的内存可以完全在内存中解决您的许多其他问题!
【讨论】:
谢谢! Spark 的 OutOfMemory 问题何时出现?当数据不适合内存时,不应该将数据溢出到磁盘吗? 是的,确实如此。重读一遍,这不是对 Spark 的恰当描述。我试图强调 Spark 不是灵丹妙药,你仍然可以得到 hadoop 做得好的东西,而 Spark 让这变得更加困难。我最近遇到的一个天真的例子是根据计算的密钥将文件分组到 hdfs 目录中。这是 hadoop 中一个简单的仅映射工作,其中 Spark 的groupByKey
要求给定键的所有值都适合内存。目前只能将完整的“组”溢出到磁盘,因此非常大的组会不断增长,直到内存不足。
你有这方面的资料吗? Spark 在 HDFS 上运行,除非另有说明,否则使用默认复制因子。 AFAIK,MapReduce 对中间结果使用 1 的复制因子(在洗牌期间),因此在存储方面没有区别。以上是关于在 Apache Spark 的上下文中,内存数据存储意味着啥?的主要内容,如果未能解决你的问题,请参考以下文章