EMR BootstrapActions创建HDFS目录失败求助
问题:EMR引导脚本创建HDFS目录失败,SSH执行正常
我需要创建HDFS目录/apps/hudi/lib以保证run_job_flow正常运行,但在Shell引导脚本中执行命令sudo -u hdfs hdfs dfs -mkdir -p /apps/hudi/lib时,出现错误:mkdir: '/apps/hudi/lib': Input/output error。通过SSH连接集群后执行相同命令却能正常运行,尝试过不使用sudo、切换不同sudo用户的方式,均未解决问题。
以下是我的jobflow配置:
client.run_job_flow( Name="BackupJob", ReleaseLabel="emr-6.15.0", Instances={ "InstanceGroups": [my-nodes], "Ec2KeyName": ec2_config["KeyName"], "EmrManagedMasterSecurityGroup": ec2_config["EmrManagedMasterSecurityGroup"], "EmrManagedSlaveSecurityGroup": ec2_config["EmrManagedSlaveSecurityGroup"], "Ec2SubnetId": ec2_config["SubnetId"], "AdditionalMasterSecurityGroups": ec2_config["AdditionalMasterSecurityGroups"], "AdditionalSlaveSecurityGroups": ec2_config["AdditionalSlaveSecurityGroups"], "KeepJobFlowAliveWhenNoSteps": True, }, Applications=[ {"Name": "Hadoop"}, {"Name": "Hive"}, {"Name": "Spark"}, {"Name": "JupyterEnterpriseGateway"}, {"Name": "Livy"}, ], Configurations=[ { "Classification": "livy-conf", "Properties": { "livy.file.local-dir-whitelist": "/usr/lib/hudi", "livy.server.session.timeout": "6h", }, }, { "Classification": "hadoop-env", "Configurations": [ { "Classification": "export", "Properties": {"JAVA_HOME": "/usr/lib/jvm/jre-17"}, } ], "Properties": {}, }, { "Classification": "spark", "Properties": {"maximizeResourceAllocation": "true"}, }, { "Classification": "hive-site", "Properties": { "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory" }, }, { "Classification": "spark-hive-site", "Properties": { "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory" }, }, ], BootstrapActions=[ { "Name": "Set up hudi", "ScriptBootstrapAction": { "Path": "s3_path_to_my_script" }, }, ] )
解决思路
1. 等待HDFS服务完全就绪
引导脚本执行时,HDFS集群可能还在初始化阶段,导致IO错误。在脚本中添加等待逻辑:
# 循环等待HDFS根目录可访问 until hdfs dfs -test -d /; do echo "等待HDFS服务启动..." sleep 10 done # 执行目录创建命令 sudo -u hdfs hdfs dfs -mkdir -p /apps/hudi/lib
2. 改用EMR Step执行目录创建
引导脚本执行时机过早,可将目录创建操作转为EMR Step,集群稳定后自动执行:
# 在run_job_flow参数中添加Steps字段 Steps=[ { 'Name': 'Create Hudi HDFS Directory', 'ActionOnFailure': 'CONTINUE', 'HadoopJarStep': { 'Jar': 'command-runner.jar', 'Args': ['hdfs', 'dfs', '-mkdir', '-p', '/apps/hudi/lib'] } } ]
该Step自动以hdfs用户执行,无需sudo。
3. 修正引导脚本的权限与环境变量
EMR引导脚本默认以hadoop用户执行,尝试直接执行命令(hadoop用户默认拥有HDFS操作权限),或保留环境变量执行sudo:
# 方案1:直接执行 hdfs dfs -mkdir -p /apps/hudi/lib # 方案2:保留环境变量执行sudo sudo -E -u hdfs hdfs dfs -mkdir -p /apps/hudi/lib
4. 检查HDFS集群状态
在引导脚本中添加状态检查,确认DataNode正常运行:
hdfs dfsadmin -report
若输出显示DataNode未就绪,说明集群初始化未完成,需延长等待时间。
内容的提问来源于stack exchange,提问作者Lucas Vaz
相关产品推荐
相关产品推荐

