Yarn节点标签与AWS EMR机器类型映射错误



有人有在AWS EMR上使用Yarn节点标签的经验吗?如果是这样,请分享你的想法。我们希望在任务(Spot)机上运行所有的Spark执行器,在核心(on- demand)机上运行所有的Spark ApplicationMaster/Driver。以前我们在CORE机器上运行Spark executor和Spark Driver(按需)。

为了实现这一点,我们创建了"任务";yarn节点标签作为自定义AWS EMR引导操作的一部分。并绘制了相同的"任务"当任何Spot实例在单独的引导操作中注册到AWS EMR时,yarn标签。作为"CORE"是默认的yarn节点标签表达式,因此我们只是在bootstrap动作中注册节点时将其映射为一个按需实例。

我们正在使用"spark.yarn.executor.nodeLabelExpression": "TASK"spark conf在Task节点上启动spark executor。

. .我们正面临着Yarn节点标签与适当机器的错误映射的问题,即在短时间内(大约1-2分钟)的"任务";yarn节点标签与按需实例和"CORE"Yarn节点标签与spot实例映射。因此,在这段错误标签的短时间内,Yarn在按需实例上启动Spark执行程序,在Spot实例上启动Spark驱动程序。

这个与相应机器类型的标签的错误映射将持续到引导操作完成,之后映射将自动解析到正确的状态。

我们正在运行的脚本作为引导操作的一部分:

该脚本在所有新机器上运行,为该机器分配一个标签。脚本作为后台PID运行,因为只有在所有自定义引导操作完成后,yarn才可用

#!/usr/bin/env bash
set -ex
function waitTillYarnComesUp() {
IS_YARN_EXIST=$(which yarn | grep -i yarn | wc -l)
while [ $IS_YARN_EXIST != '1' ]
do
echo "Yarn not exist"
sleep 15
IS_YARN_EXIST=$(which yarn | grep -i yarn | wc -l)
done
echo "Yarn exist.."
}
function waitTillTaskLabelSyncs() {
LABEL_EXIST=$(yarn cluster --list-node-labels | grep -i TASK | wc -l)
while [ $LABEL_EXIST -eq 0 ]
do
sleep 15
LABEL_EXIST=$(yarn cluster --list-node-labels | grep -i TASK | wc -l)
done
}
function getHostInstanceTypeAndApplyLabel() {
HOST_IP=$(curl http://169.254.169.254/latest/meta-data/local-hostname)
echo "host ip is ${HOST_IP}"
INSTANCE_TYPE=$(curl http://169.254.169.254/latest/meta-data/instance-life-cycle)
echo "instance type is ${INSTANCE_TYPE}"
PORT_NUMBER=8041
spot="spot"
onDemand="on-demand"
if [ $INSTANCE_TYPE == $spot ];  then
yarn rmadmin -replaceLabelsOnNode "${HOST_IP}:${PORT_NUMBER}=TASK"
elif [ $INSTANCE_TYPE == $onDemand ]
then
yarn rmadmin -replaceLabelsOnNode "${HOST_IP}:${PORT_NUMBER}=CORE"
fi
}
waitTillYarnComesUp
# holding for resource manager sync
sleep 100
waitTillTaskLabelSyncs
getHostInstanceTypeAndApplyLabel
exit 0

yarn rmadmin -addToClusterNodeLabels "TASK(exclusive=false)"

这个命令在Master实例上运行,在创建集群时创建一个新的TASK yarn节点标签。

有没有人有线索来防止这种错误的标签映射?

我想提出下一个:

  1. 用一些默认标签创建每个节点,如LABEL_PENDING。您可以使用EMR分类;
  2. 在引导脚本中,您应该确定当前节点是On-Demand还是Spot实例;
  3. 之后,在每个节点上,您应该将/etc/hadoop/conf/yarn-site.xml中的LABEL_PENDING更新为ON_DEMANDSPOT;
  4. 在主节点上,您应该为YARN添加3个标签:LABEL_PENDING,ON_DEMANDSPOT

EMR分类示例:

[
{
"classification": "yarn-site",
"properties": {
"yarn.node-labels.enabled": "true",
"yarn.node-labels.am.default-node-label-expression": "ON_DEMAND",
"yarn.nodemanager.node-labels.provider.configured-node-partition": "LABEL_PENDING"
},
"configurations": []
},
{
"classification": "capacity-scheduler",
"properties": {
"yarn.scheduler.capacity.root.accessible-node-labels.ON_DEMAND.capacity": "100",
"yarn.scheduler.capacity.root.accessible-node-labels.SPOT.capacity": "100",
"yarn.scheduler.capacity.root.default.accessible-node-labels.ON_DEMAND.capacity": "100",
"yarn.scheduler.capacity.root.default.accessible-node-labels.SPOT.capacity": "100"
},
"configurations": []
},
{
"classification": "spark-defaults",
"properties": {
"spark.yarn.am.nodeLabelExpression": "ON_DEMAND",
"spark.yarn.executor.nodeLabelExpression": "SPOT"
},
"configurations": []
}
]

bootstrap脚本的附加部分示例

yarnNodeLabelConfig="yarn.nodemanager.node-labels.provider.configured-node-partition"
yarnSiteXml="/etc/hadoop/conf/yarn-site.xml"
function waitForYarnConfIsReady() {
while [[ ! -e $yarnSiteXml ]]; do
sleep 2
done
IS_CONF_PRESENT_IN_FILE=$(grep $yarnNodeLabelConfig $yarnSiteXml | wc -l)
while [[ $IS_CONF_PRESENT_IN_FILE != "1" ]]
do
echo "Yarn conf file doesn't have properties"
sleep 2
IS_CONF_PRESENT_IN_FILE=$(grep $yarnNodeLabelConfig $yarnSiteXml | wc -l)
done
}
function updateLabelInYarnConf() {
INSTANCE_TYPE=$(curl http://169.254.169.254/latest/meta-data/instance-life-cycle)
echo "Instance type is $INSTANCE_TYPE"
if [[ $INSTANCE_TYPE == "spot" ]];  then
sudo sed -i 's/>LABEL_PENDING</>SPOT</' $yarnSiteXml
elif [[ $INSTANCE_TYPE == "on-demand" ]]
then
sudo sed -i 's/>LABEL_PENDING</>ON_DEMAND</' $yarnSiteXml
fi
}
waitForYarnConfIsReady
updateLabelInYarnConf

最新更新