定時で動かしているSparkバッチのコスト削減の為、スポットインスタンスを利用している。
落ちる対策のために定価の3倍で入札をいれていたのだが、それでも価格が高騰してEMRが起動できない事象が発生した。
見てみると ap-northeast-1a,ap-northeast-1cで値段がぜんぜん違う。
安い方使ったほうが得だなと思ったので制御入れた。
#!/bin/sh
TARGET_INSTANCE_TYPE="c4.large"
TARGET_AZ="ap-northeast-1a"
SINCE=`date -u -d '1 hours ago' +"%Y-%m-%dT%H:%M:%S"`
UNTIL=`date -u +"%Y-%m-%dT%H:%M:%S"`
aws ec2 describe-spot-price-history \
--instance-types ${TARGET_INSTANCE_TYPE} \
--product-description "Linux/UNIX (Amazon VPC)" \
--start-time ${SINCE} \
--end-time ${UNTIL} \
--availability-zone ${TARGET_AZ} \
| jq -r '.SpotPriceHistory[] | "\(.Timestamp)\t\(.SpotPrice)"' | \
sed s/.000z//g | awk '{print $2}' | head -n 1
↑で調べたいinstance_type,azの値段を調べて、一番安いAZを調べる。
# azごとにサブネットを作成し、価格の判定結果によって$TARGET_SUBNET_IDを切り替えた。
# EMR作成コマンド例:
EMR_CLUSTER_ID=`aws emr create-cluster \
--no-auto-terminate \
--region ap-northeast-1 \
--name SparkCluster \
--ami-version 3.8.0 \
--service-role EMR_DefaultRole \
--instance-groups InstanceCount=1,\
Name=sparkmaster,\
BidPrice=$BID_PRICE,\
InstanceGroupType=MASTER,\
InstanceType=$INSTANCE_TYPE InstanceCount=$INSTANCE_COUNT,\
Name=sparkworker,\
BidPrice=$BID_PRICE,\
InstanceGroupType=CORE,\
InstanceType=$INSTANCE_TYPE \
--ec2-attributes InstanceProfile=EMR_EC2_DefaultRole,SubnetId=$TARGET_SUBNET_ID,\
KeyName=fam \
--applications Name=Spark \
--query 'ClusterId' --output text`
便利。
これでも落ちるようであれば、落ちるまで1分間猶予ができたようなので定時監視して価格を釣り上げるロジックをいれるしかないかな・・・(詳細未調査