硬件配置
Spark 开发者经常被问到的一个问题是如何为其配置硬件。虽然合适的硬件配置会因情况而异,但我们仍提出以下建议。
存储系统
由于大多数 Spark 作业可能需要从外部存储系统(例如 Hadoop 文件系统或 HBase)读取输入数据,因此将其放置在尽可能靠近此系统非常重要。我们建议如下:
-
如果可能,请在与 HDFS 相同的节点上运行 Spark。最简单的方法是在同一节点上设置 Spark 独立模式集群,并配置 Spark 和 Hadoop 的内存及 CPU 使用,以避免干扰(对于 Hadoop,相关的选项包括用于每个任务内存的
mapred.child.java.opts
,以及用于任务数量的mapreduce.tasktracker.map.tasks.maximum
和mapreduce.tasktracker.reduce.tasks.maximum
)。或者,您可以在像 Hadoop YARN 这样的通用集群管理器上运行 Hadoop 和 Spark。 -
如果无法实现,请在与 HDFS 位于同一局域网的不同节点上运行 Spark。
-
对于像 HBase 这样的低延迟数据存储,最好在与存储系统不同的节点上运行计算作业,以避免干扰。
本地磁盘
虽然 Spark 可以在内存中执行大量计算,但它仍然使用本地磁盘来存储不适合 RAM 的数据,以及保存阶段之间的中间输出。我们建议每个节点配置 4-8 个磁盘,并且不使用 RAID(仅作为独立的挂载点)。在 Linux 中,使用 noatime
选项挂载磁盘以减少不必要的写入。在 Spark 中,配置 spark.local.dir
变量为一个逗号分隔的本地磁盘列表。如果您正在运行 HDFS,使用与 HDFS 相同的磁盘是没有问题的。
内存
一般来说,Spark 在每台机器拥有 8 GB 到数百 GB 的内存时都能良好运行。在所有情况下,我们建议最多只为 Spark 分配 75% 的内存;将剩余部分留给操作系统和缓冲区缓存。
您所需的内存量将取决于您的应用程序。要确定您的应用程序在特定数据集大小下使用了多少内存,请将部分数据集加载到 Spark RDD 中,并使用 Spark 监控 UI(http://<driver-node>:4040
)的存储选项卡来查看其在内存中的大小。请注意,内存使用量受存储级别和序列化格式的影响很大——有关如何减少内存使用量的技巧,请参阅调优指南。
最后,请注意,Java VM 在 RAM 超过 200 GB 时并不总是表现良好。如果您购买的机器内存超过此限制,您可以在单个节点中启动多个执行器。在 Spark 的独立模式中,一个 worker 负责根据其可用内存和核心数量启动多个执行器,并且每个执行器将在单独的 Java VM 中启动。
网络
根据我们的经验,当数据在内存中时,许多 Spark 应用程序都受限于网络。使用 10 千兆 或更高速度的网络是提高这些应用程序速度的最佳方式。对于“分布式归约”应用程序(例如 group-by、reduce-by 和 SQL join)来说,这一点尤其重要。在任何给定应用程序中,您都可以从应用程序的监控 UI(http://<driver-node>:4040
)中查看 Spark 在网络中传输了多少数据。
CPU 核心
Spark 可以很好地扩展到每台机器数十个 CPU 核心,因为它在线程之间执行的共享操作很少。您可能应该为每台机器至少配置 8-16 个核心。根据您的工作负载的 CPU 成本,您可能还需要更多:一旦数据进入内存,大多数应用程序都受限于 CPU 或网络。