本文翻译整理自官网Hardware Provisioning - Spark 3.3.2。在Spark调优指南中讲述了程序运行的一般调优逻辑(软件),但Spark开发者有一个最普遍的问题是如何为Spark配置合适的硬件。
硬件配置本来是多多益善的,但多数情况下讨论的是性价比。
存储系统
原则是离数据越近越好。
- HDFS类存储仍然是建议存算一体的。Spark的工作节点最好与HDFS的data节点相一致。
- 退而求其次,两者应在一个本地区域网络内,也即相同的机房。
- 对于HBase,由于前者是低延迟系统,为了避免相互影响,可以错开部署。
本地磁盘
虽然Spark设计为内存计算,但它仍然会用本地磁盘存储内存溢出的数据以及中间阶段数据。**推荐每个节点4~8个磁盘,不使用RAID(单独的挂载点)。
- 在Linux上挂载磁盘时带上
noatime选项以减少不必要的写入。 - 在Spark配置
spark.local.dir,多个目录以逗号分隔。最好与HDFS数据盘一致。
内存
通常,Spark可以在每台机器有8GB到数百GB内存的情况下运行良好。在所有情况下,我们建议最多只为Spark分配75% 的内存,其余的留给操作系统和缓冲区缓存。
你需要多少内存将取决于你的应用程序。要确定你的应用程序对某个数据集的大小使用多少内存,可以在Spark的RDD中加载部分数据集,并使用Spark的监控用户界面(http://:4040)的“Storage”标签来查看其在内存中的大小。请注意,内存使用量受存储级别和序列化格式的影响很大--关于如何减少内存使用量的建议,请参见调优指南。
最后,请注意,Java VM在超过200GiB的内存中并不总是表现良好。如果你购买的机器的内存比这个大,你可以在一个节点上启动多个执行器。在Spark的独立模式中,一个工作者负责根据其可用的内存和内核来启动多个执行器,每个执行器将在一个单独的Java VM中启动。
网络
根据我们的经验,当数据在内存中时,很多Spark应用是受网络约束的。使用万兆或更高的网络是使这些应用更快速的最好方法。 这对于 "分布式reduce "应用来说尤其如此,比如group-bys, reduce-bys, 和 SQL joins。在任何给定的应用中,你可以从应用的监控界面(http://:4040)看到Spark在网络中Shuffle了多少数据。
CPU核心
Spark可以很好地扩展到每台机器上的几十个CPU核心,因为它在线程之间执行最小的共享。你可能应该为每台机器提供至少8-16个内核。根据你的工作负载的CPU成本,你可能还需要更多:一旦数据在内存中,大多数应用程序性能都是由CPU或网络限定的。