FURYU Tech Blog - フリュー株式会社

フリュー株式会社の開発者が技術情報を発信するブログです。

AWS 1ヶ月導入記 part 8 バックアップ編

みなさん、あけましておめでとうございます!フリューでモバイルサイト開発を行っている鷲見といいます。

今年も昨年から引き続き、クラウド環境の導入状況をそのまま記事にしていきたいと思います。

前回はSimpleDBの性能について解説させていただきました。

今回は前回の予告通りAWSでのバックアップについて紹介させていただきたいと思います。

各種AWSサービスのバックアップ

EC2

EC2インスタンス上でインストールしたミドルウェアやその設定をバックアップし、EC2インスタンスに障害が発生した場合でも、ただちに別のEC2インスタンスを立ち上げられるようにAMIを作成します。

AMIとはAmazon Machine Imageの略で、EC2のための設定済みのマシンイメージです。AMIを作成しておくと、AMI作成時点の状態で、EC2インスタンスを新規に立ち上げることができます。

AMIの作成は、AWSのManagementConsoleから実施するか、Amazon EC2 API Toolsでコマンドラインから実施します。

Amazon EC2 API Tools

EC2 API ToolsでのコマンドラインからのAMIの作成は以下のブログが詳しいので参照してください。

参考元

Cloudpackブログ EC2インスタンスをリブート/停止しないでAMI作成

EBS

現在利用しているEC2インスタンスはRoot DeviceがEBSのAMIを利用しています。

EBSとはElastic Blogck Storageの略で、EC2用のブロックストレージです。外付けハードディスクをイメージしてもらうとわかりやすいかと思います。

このEBSにはスナップショットを作成する機能があります。この機能を利用することで、特定時点でのEBSのバックアップをS3上に作成することができます。また、スナップショットからEBSボリュームを作成することも簡単にできるようになっています。

EBSのスナップショットを毎日1回作成し、10日前の状態まで遡れるようにしたいと思います。

以下のブログの記事を参考に、少し改造してスナップショット作成&世代管理用のスクリプトを作成し、毎日cronで定期的に実行するようにしました。

参考元

RX-7乗りの適当な日々 – Amazon EBSのスナップショット(バックアップ)を取得しつつ世代管理も行うスクリプト

#!/bin/sh
BACKUP_DATE=`date +%Y-%m-%d`
EBS_VOLUME_INFO_FILE=/tmp/ebs_volume_info.txt

export JAVA_HOME=/usr/local/java/jdk1.6.0_24
export EC2_HOME=$HOME/aws-tools/ec2-api-tools
export PATH=$EC2_HOME/bin:$PATH
export EC2_CERT=$HOME/aws-tools/pem/cert-KIGSJRZSKQYEOTSSZTQIC2IPZEW3P7C3.pem
export EC2_PRIVATE_KEY=$HOME/aws-tools/pem/pk-KIGSJRZSKQYEOTSSZTQIC2IPZEW3P7C3.pem
export EC2_URL=http://ec2.ap-northeast-1.amazonaws.com

# 稼働中のEC2のインスタンスIDを取得
INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
echo INSTANCE_ID=${INSTANCE_ID}

# 稼働中のEC2に割り当てられているEBSボリュームIDを取得
EBS_VOLUME_IDS=`ec2-describe-volumes --filter attachment.instance-id=${INSTANCE_ID} | awk 'NR%3==1{print $2}'`
echo EBS_VOLUME_IDS=${EBS_VOLUME_IDS}

# EBSスナップショットの世代管理数
EBS_GENERATION_COUNT=10

# 稼働中のEC2に割り当てられているEBSボリューム毎にスナップショットの作成と世代管理を行う。
for EBS_VOLUME_ID in ${EBS_VOLUME_IDS}; do
    echo EBS_VOLUME_ID=${EBS_VOLUME_ID}

        # 稼働中のEC2に割り当てられているEBSボリュームの名前を取得
        EBS_VOLUME_NAME=`ec2-describe-volumes --filter volume-id=${EBS_VOLUME_ID}  | awk 'NR==3{print $5}'`
        echo EBS_VOLUME_NAME=${EBS_VOLUME_NAME}

        # スナップショットの取得volume-id
        echo -n "[creating...] "
        ec2-create-snapshot ${EBS_VOLUME_ID} -d "Daily Backup Of ${EBS_VOLUME_NAME} ON ${BACKUP_DATE}"

        # スナップショットの一覧を取得
        SNAPSHOTS=`ec2-describe-snapshots | grep ${EBS_VOLUME_ID} | sort -k5 -r | awk '{print $2}'`

        # 世代保管分の調整(過去スナップショットのクリア)
        COUNT=1
        for SNAPSHOT in ${SNAPSHOTS}; do
          if [ ${COUNT} -le ${EBS_GENERATION_COUNT} ]; then
            # 保管対象なのでN/A
            echo "[keeping] " ${SNAPSHOT}
          else
            # 保管対象外なので削除
            echo -n "[deleting...] "
            ec2-delete-snapshot ${SNAPSHOT}
          fi
          COUNT=`expr ${COUNT} + 1`
        done
done

参考元のコードでは、1つのEC2インスタンスに複数のEBSボリュームがアタッチされている場合にバックアップが取れないのですが、全てのEBSボリュームのバックアップを取れるように改造させていただきました。

SimpleDBのバックアップ

SimpleDBにはバックアップ機能が存在しません。なので、バックアップが必要な場合は、自前でバックアップ用のプログラムを作成する必要があります。

データにもたせている更新日時がバックアップ対象日であるデータを取得し、取得したデータをシンガポールリージョンのSimpleDBに転送しています。

このプログラムによって、前日の午前0時時点でのSimpleDBのスナップショットがシンガポールリージョンのSimpleDBに作成されることになります。

リージョン全体の障害への対策

基本的に同一リージョン内のAvailability Zoneはそれぞれネットワーク・電気系統が異なるため、リージョン全体での障害というのは発生しにくいと思われます。しかし、2011年4月に米国東リージョン全体に渡る障害が発生したということもあり、今回は念の為、リージョン全体に障害が発生した場合にも、すぐにサービスが再開できるように準備しておきます。

今回は東京リージョン全体の障害が発生した場合に、シンガポールリージョンでサービス再開をできるように準備します。

AMIのシンガポールリージョンへの移行

通常EC2で作成したAMIは、AMIを作成したリージョン内でしか使えませんが、他のリージョンに移行することもできます。

今回はEC2のバックアップ用に東京リージョンで作成したAMIを、シンガポールリージョンに移行します。これによりシンガポールリージョンで東京リージョンと同じ内容のEC2インスタンスを生成することが出来るようになります。

移行手順は以下のブログが詳しいのでご参照ください。

参考元

サーバーワークス エンジニアブログ – EBSタイプのインスタンスを他リージョンへ移行する手順

SimpleDBデータのスナップショット

上述のバックアップ手順でSimpleDBの前日午前0時時点でのスナップショットがシンガポールリージョンにある状態となっています。サービス再開時にはこのスナップショットのデータを利用して再開します。

まとめ

今回はAWSサービスに関するバックアップ方法についてまとめました。

弊社で実施しているバックアップは以下のとおりです。

  • EC2のバックアップはAMIの作成で実施する。
  • EBSのバックアップはスクリプトで毎日スナップショット作成を実施する。
  • SimpleDBのバックアップはプログラムを作成し、他リージョンにデータを転送する。

これだけ準備しておけば、障害なんて怖くないはず!

さぁこれで準備も整ったので、次回はサービス開始後の運用や障害についてお話させていただきたいと思います。