Я использую кластер HPC, где диспетчером заданий является SLURM.При получении 6 заданий на слерм с помощью следующей команды:
#SBATCH -p batch
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=3
#SBATCH --cpus-per-task=4
Я хотел бы развернуть 1 узел Spark Master и 5 узлов Spark Worker.
В настоящее время я использую сценарий, в котором один главный и один подчиненный будут развернуты на узле (с помощью одной задачи Slurm), а остальные задачи развернут только по одному рабочему узлу каждый.Как бы я изменил этот сценарий для развертывания нескольких рабочих узлов на задачу?В текущем сценарии рабочим узлам будет назначен заранее определенный статический номер порта, так что только IP-адрес вместе с номером порта может дифференцировать работника.По той же причине не более одного работника может быть однозначно идентифицировано в одном узле.Поэтому текущий сценарий полезен только в том случае, если --ntasks-per-node равен 1.
Как бы я динамически распределял порты, следя за тем, чтобы остальная часть сценария работала должным образом?
#!/bin/bash -l
#SBATCH -J bda-job
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=28
#SBATCH --time=01:30:00
#SBATCH -p batch
#SBATCH --qos qos-batch
#SBATCH -o %x-%j.log
### Load latest available Spark
module load devel/Spark
### If you do not wish tmp dirs to be cleaned
### at the job end, set below to 0
export SPARK_CLEAN_TEMP=1
### START INTERNAL CONFIGURATION
## CPU and Memory settings
export SPARK_WORKER_CORES=${SLURM_CPUS_PER_TASK}
export DAEMON_MEM=4096
export NODE_MEM=$((4096*${SLURM_CPUS_PER_TASK}-${DAEMON_MEM}))
export SPARK_DAEMON_MEMORY=${DAEMON_MEM}m
export SPARK_NODE_MEM=${NODE_MEM}m
## Set up job directories and environment variables
export BDA_HOME_DIR="$HOME/bda"
export SPARK_JOB_DIR="$BDA_HOME_DIR/spark-jobs"
export SPARK_JOB="$BDA_HOME_DIR/spark-jobs/${SLURM_JOBID}"
mkdir -p "${SPARK_JOB}"
export SPARK_HOME=$EBROOTSPARK
export SPARK_WORKER_DIR=${SPARK_JOB}
export SPARK_LOCAL_DIRS=${SPARK_JOB}
export SPARK_MASTER_PORT=7077
export SPARK_MASTER_WEBUI_PORT=9080
export SPARK_SLAVE_WEBUI_PORT=9081
export SPARK_INNER_LAUNCHER=${SPARK_JOB}/spark-start-all.sh
export SPARK_MASTER_FILE=${SPARK_JOB}/spark_master
export HADOOP_HOME_WARN_SUPPRESS=1
export HADOOP_ROOT_LOGGER="WARN,DRFA"
export SPARK_SUBMIT_OPTIONS="--conf spark.executor.memory=${SPARK_NODE_MEM} --conf spark.worker.memory=${SPARK_NODE_MEM}"
## Generate spark starter-script
cat << 'EOF' > ${SPARK_INNER_LAUNCHER}
#!/bin/bash
## Load configuration and environment
source "$SPARK_HOME/sbin/spark-config.sh"
source "$SPARK_HOME/bin/load-spark-env.sh"
if [[ ${SLURM_PROCID} -eq 0 ]]; then
## Start master in background
export SPARK_MASTER_HOST=$(hostname)
MASTER_NODE=$(scontrol show hostname ${SLURM_NODELIST} | head -n 1)
echo "spark://${SPARK_MASTER_HOST}:${SPARK_MASTER_PORT}" > "${SPARK_MASTER_FILE}"
"${SPARK_HOME}/bin/spark-class" org.apache.spark.deploy.master.Master \
--ip $SPARK_MASTER_HOST \
--port $SPARK_MASTER_PORT \
--webui-port $SPARK_MASTER_WEBUI_PORT &
## Start one slave with one less core than the others on this node
export SPARK_WORKER_CORES=$((${SLURM_CPUS_PER_TASK}-1))
"${SPARK_HOME}/bin/spark-class" org.apache.spark.deploy.worker.Worker \
--webui-port ${SPARK_SLAVE_WEBUI_PORT} \
spark://${MASTER_NODE}:${SPARK_MASTER_PORT} &
## Wait for background tasks to complete
wait
else
## Start (pure) slave
MASTER_NODE=spark://$(scontrol show hostname $SLURM_NODELIST | head -n 1):${SPARK_MASTER_PORT}
"${SPARK_HOME}/bin/spark-class" org.apache.spark.deploy.worker.Worker \
--webui-port ${SPARK_SLAVE_WEBUI_PORT} \
${MASTER_NODE}
fi
EOF
chmod +x ${SPARK_INNER_LAUNCHER}
## Launch SPARK and wait for it to start
srun ${SPARK_INNER_LAUNCHER} &
while [ -z "$MASTER" ]; do
sleep 5
MASTER=$(cat "${SPARK_MASTER_FILE}")
done
### END OF INTERNAL CONFIGURATION