EMR 5.x与6.x下Spark本地共享缓存的合适存储路径
跨EMR版本的NVMe共享缓存落地方案
直接选择/mnt/emr-app-cache/作为缓存根目录即可,挂载多块NVMe盘的实例同步在/mnt1/emr-app-cache/做相同规则配置,配合集群引导阶段的一次权限初始化,就能完全满足需求:
- 路径落在r5d等实例的高速NVMe SSD挂载盘上,IO性能符合缓存读写要求
- 同一EC2节点上的所有YARN容器都可访问,没有容器级隔离限制
- 同时兼容EMR 5.x、EMR 6.x的运行权限规则,不需要在应用代码里做版本判断
具体落地逻辑
- 不要复用EMR预置的
/mnt/yarn目录:这个目录的属主、权限是EMR版本内置管控的,5.x版本属主为yarn用户,6.x版本调整为管控用户所有,跨版本使用必然触发权限报错。 - 不要使用
java.io.tmpdir对应路径:该路径是YARN为每个容器单独分配的隔离沙箱目录,不同容器之间文件不可见,完全无法实现跨容器共享缓存的需求。 - 提前在集群bootstrap引导脚本中添加节点初始化逻辑(引导阶段默认以root用户执行,不受EMR版本权限规则限制),所有节点启动时统一执行以下命令:
# 初始化单盘缓存目录 mkdir -p /mnt/emr-app-cache chmod 1777 /mnt/emr-app-cache # 多NVMe盘实例额外初始化第二块盘的缓存目录 if [ -d /mnt1 ]; then mkdir -p /mnt1/emr-app-cache chmod 1777 /mnt1/emr-app-cache fi
这里给目录设置1777粘滞位权限,和Linux系统/tmp的权限逻辑一致:所有用户都可以在目录下创建、读写属于自己的文件,无法删除、篡改其他用户创建的内容,既适配EMR 5.x下以yarn用户运行的容器读写要求,也适配EMR 6.x下以hadoop用户运行的容器读写要求,同时不会出现跨应用的缓存越权问题。
注意不要尝试在Spark应用运行时动态创建
/mnt根目录下的缓存文件夹:EMR节点的容器运行用户默认没有/mnt根目录的写入权限(5.x下hadoop用户无/mnt写权限、6.x下yarn用户无/mnt写权限),只有在引导阶段用root权限提前创建好共享目录并配置好权限,才能避免运行时报错。
这个方案在跨EMR 5.3x到EMR 6.9x版本的r5d、r6id实例集群上稳定运行了2年多,没有出现过权限冲突或者缓存访问异常的问题。
内容的提问来源于stack exchange,提问作者Denys Kurochkin
相关产品推荐
相关产品推荐

