如何防止 Hadoop 或 Spark 作业用户缓存在 Amazon EMR 中使用太多磁盘空间?
上次更新时间:2020 年 2 月 11 日
我的 Apache Hadoop 或 Apache Spark 作业的用户缓存占用了分区上所有的磁盘空间。Amazon EMR 作业失败或 HDFS NameNode 服务处于安全模式。如何解决此问题?
简短描述
在 Amazon EMR 集群上,YARN 被配置为允许作业将缓存数据写入 /mnt/yarn/usercache 中。当您处理大量数据或运行多个并行作业时,/mnt 文件系统可能会满载。这会导致某些节点上的节点管理器发生故障,然后导致作业挂起或失败。
使用以下任意一种方法来解决此问题:
调整 YARN NodeManager 的用户缓存保留设置。如果您没有长期运行的作业或流作业,请选择此选项。 向上扩展 Amazon Elastic Block Store (Amazon EBS) 卷。如果您有长期运行的作业或流作业,请选择此选项。解决方法
选项 1:调整 NodeManager 的用户缓存保留设置
以下属性定义缓存清理设置:
yarn.nodemanager.localizer.cache.cleanup.interval-ms:这是缓存清理间隔时间。默认值为 600000 毫秒。此间隔时间后,如果缓存大小超出 yarn.nodemanager.localizer.cache.target-size-mb 中设置的值,则将删除未被运行容器使用的文件。 yarn.nodemanager.localizer.cache.target-size-mb:这是缓存允许的最大磁盘空间。默认值为 10240 MB。当缓存磁盘大小超出此值时,将按照 yarn.nodemanager.localizer.cache.cleanup.interval-ms 中设置的时间间隔删除未被运行容器使用的文件。要在正在运行的集群上设置清理间隔时间和最大磁盘空间大小:
1. 打开每个核心和任务节点上的 /etc/hadoop/conf/yarn-site.xml,然后减小 yarn.nodemanager.localizer.cache.cleanup.interval 和 yarn.nodemanager.localizer.cache.target-size-mb 的值。示例:
sudo vim /etc/hadoop/conf/yarn-site.xml
yarn.nodemanager.localizer.cache.cleanup.interval-ms 400000
yarn.nodemanager.localizer.cache.target-size-mb 5120
2. 要重启 NodeManager 服务,在每个核心和任务节点上运行以下命令:
sudo stop hadoop-yarn-nodemanager
sudo start hadoop-yarn-nodemanager
注意:在 Amazon EMR 发行版本 5.21.0 和更高版本中,您还可以使用类似以下内容配置项目来覆盖集群配置或为正在运行的集群指定其他配置分类。有关更多信息,请参阅为正在运行的集群中的实例组提供配置。
要在新集群上设置清理间隔时间和最大磁盘空间大小,请在启动集群时添加类似以下内容的配置对象:
请记住,删除服务不会在正在运行的容器上执行。这意味着即使您调整用户缓存保留设置,数据仍然可能会溢出到以下路径并载满文件系统:
{'yarn.nodemanager.local-dirs'}/usercache/user/appcache/application_id ,
选项 2:向上扩展 EMR 集群节点上的 EBS 卷
要向上扩展正在运行的 EMR 集群上的存储空间,请参阅动态扩展 Amazon EMR 集群上的存储空间。
要向上扩展新 EMR 集群上的存储空间,请在创建 EMR 集群时指定一个较大的卷大小。您也可以在将节点添加到现有集群时执行此操作:
Amazon EMR 发行版本 5.22.0 及更高版本:默认的 EBS 存储量基于 Amazon Elastic Compute Cloud (Amazon EC2) 实例的大小增加。有关每种实例类型的默认分配卷的存储量和数量的更多信息,请参阅实例的默认 EBS 存储。 Amazon EMR 发行版本 5.21 及更低版本:默认的 EBS 卷大小为 32GB。为 /mnt 分区预留 27GB。HDFS、YARN、用户缓存和所有应用程序都使用 /mnt 分区。根据需要增加您的 EBS 卷大小(例如 100-500 GB 或以上)。您还可以指定多个 EBS 卷。多个 EBS 卷将被挂载为 /mnt1、/mnt2 等。对于 Spark 流作业,您还可以在处理完成且不再需要数据时执行 unpersist (RDD.unpersist())。或者,在 Scala(Python 中的 sc._jvm.System.gc())中显式调用 System.gc() 以启动 JVM 垃圾收集并删除中间随机文件。