はじめに
こんにちは。プロダクト開発部でインフラエンジニアをしている佐野です。
コロナの影響でここ数ヵ月、家に籠ってリモートワークで作業を行っていますが、椅子とモニターを新調して、やっと快適な作業環境が整ってきた今日この頃です。
さて、今回のテーマは「データのバックアップ」についてです。
昨年の夏 AWS 東京リージョンにて Amazon EC2/ Amazon EBS の障害が発生し、残念ながら Sansan も影響を受けてしまいました。その後、より可用性が高まるように改修を行ってきたのですが、特に重要なデータとなるデータベース周りバックアップデータについては、より深刻な事態を想定しディザスタリカバリ対策を進めましたので、その内容について紹介します。
今回の要件
まず、ディザスタリカバリを進めるにあたり、以下5つの要件を定義しました。
- 既存の仕組みを活かし費用を抑え、直ぐに実施できる対策を進める
- バックアップデータは国内に配置したい
- スナップショットを東京以外のリージョンにバックアップする
- PostgreSQL はデータのみではなく WAL も東京以外のリージョンにバックアップする
- バックアップしたデータの自動リストアテストも行いたい
これらを実現するために、まずは既存の仕組みを見てみます。
既存のバックアップの仕組み
ディザスタリカバリ対策を進めるにあたり、まず既存の構成を見ていきます。
DB サーバーはオーソドックスな Master, Slave の冗長構成となっています。
ストレージ(Amazon EBS)は RootDevice、Data(RAID0 にて IO を分散) 、PG_LOG、PG_XLOG で構成され Data, PG_LOG, PG_XLOGはAWS KMS(CMK) で暗号化されており、ストレージの総データ容量は数テラバイトになります。
EBS のスナップショットは日次で DB サーバーの Slave 側から取得し、取得したSnapshot ID を Amazon S3 へリストを保存しています。取得したスナップショットは毎日自動でリストアテストを行っています。このような頻度でリストアテストしているのは珍しいと思いますが、日々健全性が確認出来ることは安心感があります。
大阪リージョン利用申請
私は今回の対応を進めていく中で、初めてその存在を知りましたが、大阪にもリージョンが存在します。
現時点では、ディザスタリカバリ向けのリージョンという位置づけで、利用できる機能等は限定的で申請を行わないと利用する事が出来ないリージョンになりますが、データは国内にのみ配置したいので、今回はこちらの大阪リージョンの利用申請を出してディザスタリカバリ対策を進めます。
東京リージョンから大阪へスナップショットをコピー
今回、既存の仕組みを活かして、スピーディーに実装を進めていくため以下のような実装を行いました。
既存のバックアップ処理にて東京リージョンでスナップショットが作成されると Amazon S3 にSnapshot ID リストが生成されるので、そのリストを元にスナップショットをコピーします。
こちらの処理は Amazon CloudWatch Events の CRON にて Lambda Fucntion を起動しています。また、スナップショットを大量にコピーすると同時コピー数制限に抵触するためデフォルトの5から50へ引き上げています。
大阪リージョンから再び東京へスナップショットをコピー
大阪リージョンでもEC2は構築可能ですがオンデマンドインスタンスの提供が無いため、コスト面を考慮して東京にスナップショットを再度コピーしてリストアテストを行う設計としています。
そのため、大阪から東京へコピー処理は東京リージョン側の Amazon CloudWatch Events の CRON にて、上の処理でも利用した Lambda Fucntion を起動しスナップショットをコピーします。
東京に再び戻ってきたスナップショットを利用してリストアテストを行います。
Sansan では、AWS EBS を AWS KMS(CMK) で暗号化しており復号するために、再度同じ AWS KMS(CMK) を指定する必要があります。
そのため、スナップショットのDescription 内に必要な情報を書き込んで元の AWS KMS(CMK) に戻せるようにしています。
Description 内の記述例:
Daily Snapshot,i-xxxxxxxx,data-00x,/dev/xvdbf,2020-05-01,arn:aws:kms:ap-northeast-1:xxxxxxxxxx:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
S3 のバックアップ
既存の仕組みにて WAL ファイルは、DB サーバーから短い間隔で Amazon S3 へアップロードしており、ライフサイクル設定で定期的にファイルを削除しています。
今回は Amazon S3 のクロスリージョンレプリケーションを用いてバケットのバックアップを行います。
1. 大阪リージョンにバックアップ向けのバケットを作成
2. 両方のバケットのバージョニングを有効化
3. IAM のロール設定を行い、レプリケーション時コピー元のバケットへ参照権限を付与
4. ライフサイクルにてオブジェクトの削除設定
注意点として、バージョニング設定しているので以下のように Current versions, Previous versions をチェックし不要なファイルを確実に削除するよう指定が必要です。
スナップショットコピーの転送費用
リージョン内通信(OUT)の費用: $0.01 per GB
リージョン間通信(OUT)の費用: $0.09 per GB
上記のようにリージョンを跨ぐか否かで9倍価格が変わります。
一見すると、どちらも安いように思いますが、数テラバイトのデータを転送すると、この9倍の価格差は大きく、想像以上にバックアップのコストが掛かります。
当初この点を考慮していなかったので予算をオーバーしてしまい、予算内に収めるよう実施間隔を調整する事でコストの調整を行いました。
スナップショットの転送量を抑えるには
AWSのスナップショットコピーには2種類あり初回フルコピーと増分コピーの2種類があり、確認方法としてはスナップショット完了時に Lambda が起動するように CloudWatdch Event のイベントパターンにて createSnapshot 成功時のイベント登録を行い Lambda 内で Event 変数の値をログ出力することで確認が可能です。
Incremental : True 増分コピー
Incremental : False 初回フルコピー
今回、リストアテストを行うために、大阪にコピーしたスナップショットを再度東京にコピーしたのですが、直ぐにスナップショットを削除していた為、毎回初回フルコピーで動作していました。前回実施分のスナップショットを直ぐに削除せずに、次回実行時まで保存しておくと増分バックアップとなり、今回のケースではトータルでコストが安くなりました。
まとめ
上記のようなディザスターリカバリー対応を行い、リカバリ可能なバックアップを東京・大阪リージョンに配置したことで、以前より事業継続性が増したと思います。
来年2021年には大阪リージョンは通常のリージョン同様に利用できるようになるそうなので、事業の成長・事業の継続という両面でAWSを活用して対応を進めていきたいと思っています。
buildersbox.corp-sansan.com
buildersbox.corp-sansan.com
buildersbox.corp-sansan.com