はじめに
株式会社ネクスト(株式会社LIFULL)でインフラエンジニアを担当している 青木 直之 と申します。
この記事は 株式会社ネクスト(LIFULL) Advent Calendar 2016 の19日目の記事になります。
AWS(Amazon Web Services)には便利なサービスが多々ありますが、その中には、マネージドデータベースサービス というものがあります。
これらのマネージドデータベースサービスは優れたスケーラビリティや耐障害性を持っております。
しかし、マネージドデータベースサービスを利用する場合でも、何らかの操作ミスやプログラム誤動作といった要因によって、保存していたデータが消えてしまう可能性がありますので、定期的にデータをバックアップする事が大切と考えております。
本日はAWSのデータベースサービスやストレージサービスのうち一部サービスについて、バックアップの設定や方法についてお話させて頂きたいと思います。
・Amazon RDS
・Amazon ElastiCache for Redis
・Amazon S3
参考資料
以下の資料を参考にさせて頂きました。
Amazon APIリファレンス類
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDS.html#createDBSnapshot-property
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/ElastiCache.html#createSnapshot-property
http://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/Snapshots.html
http://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBSnapshot.html
リレーショナルデータベースのバックアップについて
オンプレミスでデータベースサーバを構築・運用していた時代、私は以下のようなDBMS用のバックアップコマンドを利用して、データのバックアップを行っておりました。
DBMS | バックアップコマンドの例 |
---|---|
Oracle | rmanコマンド, expコマンド, expdpコマンド |
MySQL | mysqldumpコマンド, xtrabackupコマンド |
PostgreSQL | pg_dumpコマンド, pg_dumpallコマンド |
これらのバックアップコマンドを定期的に自動実行する事で、データベースサーバ以外のストレージにバックアップデータを保存しておりました。実際に何度かデータを復元した事があり、バックアップは心強い存在でした。
しかし、バックアップの設定やデータ復元には、DBMSや各コマンド等の知識が必要であり、データベースをもっと簡単にバックアップ出来る方法はないか探しておりました。
前置き長くなりましたが、Amazon RDSには標準的なバックアップ機能(DBスナップショット取得機能)が備わっており、容易に自動バックアップを設定出来るようになりました。
Amazon RDSのバックアップについて
(1) Amazon RDSインスタンス作成時の自動バックアップ設定
Amazon RDSはデータを自動バックアップする設定が可能です。
自動バックアップを設定すると、Amazon RDSインスタンスのDBスナップショットが自動的に作成されて、RDSインスタンスに保存したデータがバックアップされるようになります。
(1-1) AWSマネジメントコンソールにログインして「RDS」をクリックします。

(1-2)「RDSダッシュボード」の「DBインスタンスの起動」をクリックして、Amazon RDSインスタンスを作成します。

(1-3)「MySQL」の「選択」をクリックします。

(1-4)「開発/テスト」の「MySQL」を選択して「次のステップ」をクリックします。

(1-5) 作成するAmazon RDSインスタンスの設定を入力して「次のステップ」をクリックします。


(1-6)「バックアップの保存期間」を設定します。
「バックアップ」の「バックアップの保存期間」を0から1日以上に変更する事で、自動的にAmazon RDSインスタンスのバックアップが実行されるようになります。


(2) 稼働中のAmazon RDSインスタンスの自動バックアップ設定
稼働中のAmazon RDSインスタンスに対しても、自動バックアップを設定したり、バックアップ保存期間を変更可能です。
(2-1) AWSマネジメントコンソールにログインして「RDS」をクリックします。

(2-2)「RDSダッシュボード」からバックアップ設定を変更したいAmazon RDSインスタンスを選択して「変更」をクリックします。

(2-3) RDSインスタンスの設定変更画面が表示されます。

(2-4)「バックアップの保存期間」を設定します。
「バックアップ」の「バックアップの保存期間」を変更する事で、0から1日以上に変更する事で、自動的にAmazon RDSインスタンスのバックアップが実行されるようになります。
また、バックアップ保存期間は1日〜35日の間で選択出来ます。


(2-5) バックアップ設定変更を適用する場合は「すぐに適用」にチェックをつけて「次へ」をクリックします。

(3) Amazon LambdaによるAmazon RDSの自動バックアップ
前述の設定により、毎日Amazon RDSの自動バックアップが作成されるようになります。
この自動バックアップの保存期間は最大35日間という制限があり、古いバックアップは自動的に削除されます。
しかし、例えば、毎月1日といった特定の間隔で自動バックアップを取得したい、35日経過してもバックアップを残しておきたいといった事があるかもしれません。
そのような場合、Amazon Lambdaファンクションで、Amazon RDSインスタンスのDBスナップショットを作成するようスケジュール設定する事で、毎月1日といった特定の間隔で自動バックアップを取得する事が可能です。
なお、RDSスナップショットによるRDSバックアップデータについては、AWS公式ドキュメント上ではS3に保存されると書かれていますが、S3バケット内のどこに保存されるかは明記されておらず、私の方でも具体的にバケット内のどの場所に保存されているかまでは確認できませんでした。
ただし、RDSバックアップデータ(スナップショット)については、AWSマネジメントコンソールの「RDS」→「スナップショット」画面上で検索し、データを復元する事が可能ですので、ご安心下さい。
RDSバックアップデータの復元方法は後述します。
AWS公式ドキュメント(Amazon RDS のよくある質問)
Q: 自動バックアップと DB スナップショットの保存場所と保存内容を管理する方法について教えてください。
↓
回答: Amazon RDS DB スナップショットと自動バックアップは S3 に保存されます。
(3-1) Amazon Lambdaファンクション用のIAMロールを作成します。
IAMロール「example-rds-backup」を作成します。






(3-2) Amazon RDSバックアップ用Amazon Lambdaファンクションを作成します。
「Create Lambda Functions」をクリックします。

「Select blueprint」では「hello world」をクリックして選択します。

「Next」をクリックします。

「Configure function」で以下のように入力して、Lambdaファンクション「example-rds-backup」を作成します。
設定項目 | 選択 または 入力する内容 |
---|---|
Name | example-rds-backup |
Description | example-rds-backup |
Runtime | Node.js 4.3 |
Code entry type | Edit code inline |
Environment variables | RDS_DBINSTANCE_IDENTIFIER とRDS_DBSNAPSHOT_IDENTIFIER の2つの環境変数を設定する。環境変数の値は example-rds-backup と設定する。 |
Handler | index.handler |
Role | Choose an existing role |
Exitsing Role | example-rds-backup |
Memory | 128 MB |
Timeout | 0 min 3 sec |
VPC | No VPC |
KMS Key | (default) aws/lambda |
「Code」に入力するLambdaファンクションのコードは以下になります。
'use strict';
// http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDS.html#createDBSnapshot-property
var AWS = require('aws-sdk'), rds = new AWS.RDS({ apiVersion: '2014-10-31' });
exports.handler = (event, context) => {
console.log('Start Amazon RDS Database Snapshot Backup');
var dbInstanceIdentifier = process.env.RDS_DBINSTANCE_IDENTIFIER;
var dbSnapshotIdentifier = process.env.RDS_DBSNAPSHOT_IDENTIFIER;
// Add timedate to description
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var minutes = date.getMinutes();
if ( day < 10 ) {
day = '0' + day;
}
// UTC to JST
hour += 9;
if ( hour < 10 ) {
hour = '0' + hour;
}
if ( minutes < 10 ) {
minutes = '0' + minutes;
}
var backupRunDate = '-' + year.toString() + month.toString() + day.toString() + '-' + hour.toString() + minutes.toString();
var params = {
DBInstanceIdentifier: dbInstanceIdentifier,
DBSnapshotIdentifier: dbSnapshotIdentifier + backupRunDate
};
console.log(params);
rds.createDBSnapshot(params, function(err, data) {
if (err) context.done(err, err.stack);
else context.done(null, data);
});
};


「Next」をクリックします。

「Create function」をクリックします。


(3-3) Amazon RDSバックアップ用Amazon Lambdaファンクションを実行します。
「Test」をクリックして、Lambdaを実行します。

「Save & Test」をクリックします。


(3-4) Amazon LambdaファンクションによりAmazon RDSのバックアップが開始されます。



(3-5) Amazon Lambdaファンクションを定期的に実行するよう設定します。
Amazon Lambdaファンクションを定期的に実行するよう設定し、Amazon RDSの自動バックアップを設定します。
Amazon Lambdaファンクションの実行スケジュールを設定する手順については、以下を参考にしてみて下さい。
Amazon RDSスナップショットによるバックアップデータの復元方法
参考までに、前述の(3-5)までに取得したRDSバックアップデータ(スナップショット)の復元方法を記載致します。
(3-6) AWSマネジメントコンソールにログインして「RDS」→「スナップショット」をクリックします。
(3-7) 復元したいRDSバックアップデータ名(スナップショット名)を検索します。

(3-8) 復元したいRDSバックアップデータ名(スナップショット名)を選択し、「スナップショットのアクション」→「スナップショットの復元」をクリックします。

(3-9) 「DBインスタンスの復元」画面が表示されます。RDSバックアップデータ復元にあたり必要な設定を指定します。
選択したRDSバックアップデータ(スナップショット)で、新しいRDSインスタンスを作成し、データを復元することができます。
以下の例では、RDSバックアップデータ名(スナップショット名)を復元する為、最低限設定が必要な項目を記します。
設定項目 | 選択 または 入力する内容 |
---|---|
DBインスタンスのクラス | db.t2.micro -- 1 vCPU, 1 GiB RAM |
DBインスタンス識別子 | example-rds-mysql-server-2020112-0635 |


(3-9) 「DBインスタンスの復元」画面で、「DBインスタンスの復元」をクリックします。
「DBインスタンスの復元」画面をスクロールし、「DBインスタンスの復元」をクリックします。
これにより、選択したRDSバックアップデータ(スナップショット)で、新しいRDSインスタンス作成とデータ復元が開始されます。

(3-10) AWSマネジメントコンソールの「RDS」→「データベース」をクリックします。RDSインスタンス作成とデータ復元が開始されています。ステータスが「作成中」となりますので、「利用可能」になるまで待ちます。

(3-11) AWSマネジメントコンソールの「RDS」→「データベース」をクリックします。選択したRDSバックアップデータ(スナップショット)の復元が完了すると、RDSインスタンスのステータスが「利用可能」になれば、データ復元完了です。

Redisのバックアップについて
オンプレミスでRedisサーバを構築・運用していた時代、Redisをマスターとスレーブの2台構成とし、マスターの変更をスレーブへレプリケーションするよう設定していました。
そして、Redisスレーブサーバのrdbファイルをバックアップ用ストレージへコピーする事で、 Redisのデータをバックアップしておりました。
Amazon ElastiCache(Amazon ElastiCache for Redis)のバックアップについて
(4) Amazon ElastiCacheクラスタ作成時の自動バックアップ設定
Amazon ElastiCacheのRedisはデータを自動バックアップする設定が可能です。
(4-1) AWSマネジメントコンソールにログインして「ElastiCache」をクリックします。

(4-2)「ElastiCacheダッシュボード」の「Redis」の「Create」をクリックして、Amazon ElastiCacheクラスタ(Redisクラスタ)を作成します。

(4-3) Amazon ElastiCacheクラスタの自動バックアップを設定します。
Amazon ElastiCacheクラスタ(Redis)作成時に「Backup」の「Enable automatic backups」にチェックをつける事で、Amazon ElastiCacheクラスタ(Redis)に保存したデータを自動バックアップするよう設定出来ます。


(5) 稼働中のAmazon ElastiCacheクラスタの自動バックアップ設定
稼働中のAmazon ElastiCacheクラスタ(Redis)に対しても、自動バックアップを設定可能です。
(5-1) AWSマネジメントコンソールにログインして「ElastiCache」をクリックします。
(5-2)「ElastiCacheダッシュボード」から自動バックアップを設定したいRedisクラスタの「Modify」をクリックします。

(5-3)「Enable Automatic Backups」を設定します。
「Enable Automatic Backups」を「Yes」と選択する事で、Amazon ElastiCacheクラスタ(Redis)の自動バックアップを設定出来ます。
また「Backup Retention Period」を変更する事で、バックアップ保存期間は1日〜35日の間で選択出来ます。


(6) Amazon LambdaによるAmazon ElastiCache(Redis)の自動バックアップ
前述の設定により、毎日Amazon ElastiCache(Redis)の自動バックアップが作成されるようになります。
この自動バックアップの保存期間は最大35日間という制限があり、古いバックアップは自動的に削除されます。
しかし、例えば、毎月1日といった特定の間隔で自動バックアップを取得したい、35日経過してもバックアップを残しておきたいといった事があるかもしれません。
そのような場合、Amazon Lambdaファンクションで、Amazon ElastiCache(Redis)クラスタのスナップショットを作成するようスケジュール設定する事で、毎月1日といった特定の間隔で自動バックアップを取得する事が可能です。
設定自体は前述の「Amazon LambdaによるAmazon RDSの自動バックアップ」とほとんど変わりません。
作成するAmazon LambdaファンクションのコードをAmazon ElastiCache(Redis)用に少し修正するだけで、バックアップを行う事が可能です。
(6-1) Amazon Lambdaファンクション用のIAMロールを作成します。
IAMロール「example-elasticache-redis-backup」を作成します。

(6-2) Amazon ElastiCache(Redis)バックアップ用Amazon Lambdaファンクションを作成します。
「Create Lambda Functions」をクリックします。
「Select blueprint」では「hello world」をクリックして選択します。
「Next」をクリックします。
「Configure function」で以下のように入力して、Lambdaファンクション「example-rds-backup」を作成します。
設定項目 | 選択 または 入力する内容 |
---|---|
Name | example-elasticache-redis-backup |
Description | example-elasticache-redis-backup |
Runtime | Node.js 4.3 |
Code entry type | Edit code inline |
Environment variables | ELASTICACHE_SNAPSHOT_NAME とELASTICACHE_CLUSTER_NAME の2つの環境変数を設定する。環境変数の値は example-redis1-001 と設定する。 |
Handler | index.handler |
Role | Choose an existing role |
Exitsing Role | example-elasticache-redis-backup |
Memory | 128 MB |
Timeout | 0 min 3 sec |
VPC | No VPC |
KMS Key | (default) aws/lambda |
「Code」に入力するLambdaファンクションのコードは以下になります。
'use strict';
// http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/ElastiCache.html#createSnapshot-property
var AWS = require('aws-sdk'), elasticache = new AWS.ElastiCache({ apiVersion: '2015-02-02' });
exports.handler = (event, context) => {
console.log('Start Amazon ElastiCache Snapshot Backup');
var elasticacheClusterName = process.env.ELASTICACHE_CLUSTER_NAME;
var elasticacheSnapshotName = process.env.ELASTICACHE_SNAPSHOT_NAME;
// Add timedate to description
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var minutes = date.getMinutes();
if ( day < 10 ) {
day = '0' + day;
}
// UTC to JST
hour += 9;
if ( hour < 10 ) {
hour = '0' + hour;
}
if ( minutes < 10 ) {
minutes = '0' + minutes;
}
var backupRunDate = '-' + year.toString() + month.toString() + day.toString() + '-' + hour.toString() + minutes.toString();
var params = {
SnapshotName: elasticacheSnapshotName + backupRunDate,
CacheClusterId: elasticacheClusterName
};
console.log(params);
elasticache.createSnapshot(params, function(err, data) {
if (err) context.done(err, err.stack);
else context.done(null, data);
});
};



「Next」をクリックします。

「Create function」をクリックします。


(6-3) Amazon ElastiCache(Redis)バックアップ用Amazon Lambdaファンクションを実行します。
「Test」をクリックして、Lambdaを実行します。

「Save & Test」をクリックします。


(6-4) Amazon LambdaファンクションによりAmazon ElastiCache(Redis)のバックアップが開始されます。




(6-5) Amazon Lambdaファンクションを定期的に実行するよう設定します。
Amazon Lambdaファンクションを定期的に実行するよう設定し、Amazon ElastiCache(Redis)の自動バックアップを設定します。
Amazon Lambdaファンクションの実行スケジュールを設定する手順については、以下を参考にしてみて下さい。
Amazon S3のバックアップについて
(7) Amazon S3のバックアップ(バージョニング)設定
Amazon S3は 99.99% の可用性を備えた、極めて耐障害性が高いオブジェクトストレージです。
基本的には、ユーザが誤ってS3バケット上に保存したデータ(オブジェクト)を消さない限り、データが消失する可能性は極めて低いと思います。
今回はS3に保存したオブジェクトを誤って消してしまった場合に備えて、オブジェクトをバックアップ(バージョニング)する設定をご説明します。
(7-1) AWSマネジメントコンソールにログインして「S3」をクリックします。

(7-2) S3のバックアップ(バージョニング)を設定したいS3バケット名をクリックします。
今回の例では、example-search-crontabバケットをクリックします。

(7-3)「バージョニング」の「バージョニングの有効化」をクリックし、S3のオブジェクトについて、全てのバージョンを保持するよう設定します。
「バージョニングの有効化」をクリックします。

「OK」をクリックします。

以下のように「バージョニングは現在、このバケットで有効になっています」と表示されれば、S3のバックアップ(バージョニング)設定は終わりです。

(7-4) S3バケットに保存したオブジェクトを削除します。バージョニング有効化により古いバージョン(削除前)のオブジェクトが残るようになったのを確認します。


「OK」をクリックして、S3に保存しているオブジェクトを削除します。

画面上の「バージョン」の「表示」をクリックします。
S3バケットから削除したオブジェクトについて、削除前のオブジェクトが残るようになりました。

削除前のオブジェクトをクリックすると、オブジェクトの内容も確認する事が出来ます;。

(8) Amazon S3のバックアップ(クロスリージョン レプリケーション)設定
次はどちらかといえばディザスタリカバリ用途で利用されるものと思いますが、Amazon S3のバックアップ(クロスリージョン レプリケーション)設定についてご説明します。
これは、例えばTokyoリージョンのS3バケットに対して、別のリージョンにバックアップ用S3バケットを作成しておく事で、TokyoリージョンのS3バケットにファイルを保存すると、別リージョンのS3バケットへファイルをレプリケーションするというバックアップ設定になります。
(8-1) AWSマネジメントコンソールにログインして「S3」をクリックします。
(8-2) S3のバックアップ(バージョニング)を設定したいS3バケット名をクリックします。

(8-3)「クロスリージョン レプリケーション」をクリックします。

(8-4)「クロスリージョン レプリケーションを有効化」を行い、S3バケットへファイルを保存した時、別のリージョンのS3バケットへ自動的にバックアップするよう設定します。
「クロスリージョン レプリケーションを有効化」を選択します。
以下のように設定します。



「IAMロールの作成/選択」をクリックします。

「詳細を表示」をクリックします。ポリシードキュメントはデフォルトのままで「許可」をクリックします。

{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::example-search-crontab"
]
},
{
"Action": [
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::example-search-crontab/*"
]
},
{
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::example-search-crontab-backup/*"
}
]
}
「保存」をクリックします。

「このバケットではクロスリージョン レプリケーションは現在有効化されています。」と表示されれば、設定完了です。

(8-5) S3バケットへファイルを保存し、別リージョンのS3バケットへ自動的にファイルがバックアップされている事を確認します。
まず、Tokyoリージョンの「クロスリージョン レプリケーション」を有効化したS3バケットに対して、ファイルをアップロードします。


次にバックアップ先として指定したSingaporeリージョンのS3バケットに対して、TokyoリージョンのS3バケットへアップロードしたファイルがレプリケーションされている事を確認します。

TokyoリージョンのS3バケットへアップロードしたファイルについて、SingaporeリージョンのS3バケットへレプリケーションされている事を確認します。これでバックアップ確認完了です。

まとめ
Amazon RDS, Amazon ElastiCache for Redis, Amazon S3は簡単な設定で、データをバックアップするよう設定する事が出来ます。
Amazon Lambdaを組み合わせると、バックアップ間隔を細かく制御する事も可能です。
不測のデータ消失に備えて、データのバックアップを行うようにしておきたいですね。
株式会社ネクスト(LIFULL) Advent Calendar 2016 の20日目は @wakuteka さんの記事になります。
よろしくお願い致します。