RDSスナップショットの S3 へのエクスポートを試してみた | SEEDS Creators' Blog | 株式会社シーズ

RDSスナップショットの S3 へのエクスポートを試してみた

クラウド事業部 インフラエンジニアの上野です。
先日、 Amazon RDSまたは Amazon Auroraのスナップショットを Apache Parquet 形式 でS3へエクスポートできるという機能が発表されました。

Amazon Relational Database Service (RDS) スナップショットの S3 へのエクスポートを発表

というわけでこちらの機能を早速試してみたいと思います。

対応バージョン

対応するAmazon RDSまたは Amazon Auroraのバージョンは次のとおりです。(2020年1月31日時点)

Aurora MySQL

  • MySQL 5.6と互換性のあるバージョン1.19.2、1.19.3、1.19.4、および1.19.5
  • MySQL 5.7と互換性のあるバージョン2.04.4、2.04.5、および2.04.6

Aurora PostgreSQL

  • PostgreSQL 9.6.11と互換性のあるバージョン1.4
  • PostgreSQL 9.6.12と互換性のあるバージョン1.5
  • PostgreSQL 10.6と互換性のあるバージョン2.2
  • PostgreSQL 10.7と互換性のあるバージョン2.3

MariaDB

  • 10.0.32 and higher
  • 10.1.26 and higher
  • 10.2.12 and higher
  • 10.3

MySQL

  • 5.6.40 and higher
  • 5.7.24 and higher
  • 8.0.13 and higher

PostgreSQL

  • 9.4.21 and higher
  • 9.5.16 and higher
  • 9.6.12 and higher
  • 10.7 and higher
  • 11.2 and higher

事前準備

利用方法はこちらになります。今回は Amazon Aurora を使います。
エクスポートの処理を行うための環境を準備します。
Exporting DB Snapshot Data to Amazon S3

まずはエクスポート先のS3バケットを作成します。

aws s3 mb s3://S3バケット名

暗号化用にAWS Key Management Service(AWS KMS)キーを作成します。作成時に表示されるKeyIdは後ほど使いますので、メモしておきましょう。

aws kms create-key

エクスポート処理に使用するIAMロールのためのIAMポリシー(ExportPolicy)を作成します。

aws iam create-policy  --policy-name ExportPolicy --policy-document '{
     "Version": "2012-10-17",
     "Statement": [
         {
             "Effect": "Allow",
             "Action": [
                 "s3:ListBucket",
                 "s3:GetBucketLocation"
             ],
             "Resource": [
                 "arn:aws:s3:::*"
             ]
         },
         {
             "Effect": "Allow",
             "Action": [
                 "s3:PutObject*",
                 "s3:GetObject*",
                 "s3:DeleteObject*"
             ],
             "Resource": [
                 "arn:aws:s3:::S3バケット名",
                 "arn:aws:s3:::S3バケット名/*"
             ]
         }
     ]
}' 

IAMロール(rds-s3-export-role)を作成し、先に作成したIAMポリシーを付与します。

aws iam create-role  --role-name rds-s3-export-role  --assume-role-policy-document '{
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
            "Service": "export.rds.amazonaws.com"
          },
         "Action": "sts:AssumeRole"
       }
     ] 
   }' 
aws iam attach-role-policy --policy-arn IAMポリシーのARN --role-name rds-s3-export-role

エクスポート実行

それではコマンドでエクスポート処理を実行しましょう。
事前に対応するバージョンのスナップショットを用意しておきましょう。
AWS CLIのバージョンが古い場合はコマンドが対応していないので、最新バージョンにアップデートしてください。

aws rds start-export-task \
    --export-task-identifier エクスポートタスクのID(任意の文字列) \
    --source-arn スナップショットのARN \
    --s3-bucket-name S3バケット名 \
    --iam-role-arn 作成したIAMロール(rds-s3-export-role)のARN \
    --kms-key-id 作成したKMSキーのKeyId

エクスポート結果を確認しましょう。Statusが “COMPLETE” となっていれば完了です。

$ aws rds describe-export-tasks
{
    "ExportTasks": [
        {
            "Status": "COMPLETE",
            "TaskEndTime": "2020-01-27T06:09:58.801Z",
            "SnapshotTime": "2020-01-27T03:27:29.511Z",
            "S3Prefix": "",
            "S3Bucket": "S3バケット名",
            "PercentProgress": 100,
            "KmsKeyId": "作成したKMSキーのKeyId",
            "ExportTaskIdentifier": "エクスポートタスクのID",
            "IamRoleArn": "作成したIAMロール(rds-s3-export-role)のARN",
            "TotalExtractedDataInGB": 1,
            "TaskStartTime": "2020-01-27T05:47:38.637Z",
            "SourceArn": "スナップショットのARN"
        }
}

参考程度にですが、処理にかかった時間は1GB以下のスナップショットで25分ほど、1.5TBほどのスナップショットで約2時間ほどでした。

AWSマネージメントコンソール を利用

今回はAWS CLIを利用して実行しましたが、もちろんAWSマネージメントコンソールからも利用することができます。
なお、AWS CLIを使ったのは、リリース直後にAWSマネージメントコンソールからS3エクスポートを実行したところ、なぜかうまく動作しなかったという経緯があります。。。色々Webブラウザも変えて実行してみましたが、うまくいきませんでした。現在は問題なく動作しています。

AWSマネージメントコンソールからS3エクスポート するには、RDSのスナップショットの画面からエクスポートするスナップショットを選択し、アクションから『Amazon S3 へのエクスポート』を選択します。

次の画面でエクスポートするための下記項目を設定して実行します。
・エクスポート識別子
・エクスポートするデータの量(DB全体 or 特定スキーマのみ等)
・エクスポート先のS3バケット
・エクスポート処理で利用するIAMロール
・暗号化のマスターキー

実行結果はRDSのスナップショットの画面から確認することができます。

エクスポート先のS3の状況

S3にエクスポートされたデータは以下の構造で保管されています。
S3バケット
 └エクスポート識別子
   └DB名
     └テーブル名
       └データ

保管されたファイルはバイナリデータとなり、直接ファイルを開いても中身はわかりません。
ということで中身を確認するためにS3 Selectを使ってみましょう。
ファイル形式を Parquet に指定して、SQLを実行してみます。

気になるお費用は?

2020年1月31日時点 の費用はAuroraの場合、東京リージョンで下記の金額となります。

 MySQL 互換エディション / PostgreSQL 互換エディション
 スナップショットサイズ 1 GB あたりの料金: 0.012USD

注意が必要なのは100GBのスナップショットから、10GBのテーブルだけエクスポートした場合でも、100 GB * スナップショットサイズ 1 GB あたり 0.012USDの料金が発生します。つまりS3へエクスポートしたデータ量ではなく、エクスポート元のスナップショットの容量で料金が発生します。
100GBにすると下記の金額が発生します。

 100GB * 0.012USD = 1.2USD(日本円で約132円)

ただし、それ以降は同じスナップショットからデータをエクスポートしても料金が毎回加算されることはありません。

制限事項

エクスポート先S3バケットのリージョンの制限
S3バケットは、スナップショットと同じAWSリージョンにある必要があります。

利用できるスナップショットの制限
他のAWSアカウントから共有されたスナップショットは利用できません。
他のAWSアカウントから共有されたスナップショットをS3エクスポートするには、スナップショットをコピーし、コピーされたスナップショットを使ってS3エクスポートする必要があります。

テーブルの列名の文字の制限
列名に次の文字が含まれるテーブルは、エクスポート中にスキップされます。
,;{}()\n\t=

データのサイズの制限
データに500 MBに近い、または500 MBを超える値が含まれている場合、エクスポートは失敗します。
このデータという単語がどこまでを指すのか分からなかったので、AWSへ質問してみました。

当方にて確認させて頂きましたところ、テーブルにおいて 500 MB に近い値、もしくは 500 MB 以上の値がある際、エクスポートに失敗する原因の一つとなるものでございました。
恐れ入りますが、上記以上の詳細につきましては、現状当方にてご案内可能な情報がございませんでした。

という回答を頂きました。この点については現在はまだ不明瞭な部分ですので注意が必要です。

partial exportするときの制限
データベース、スキーマ、またはテーブル名にスペースが含まれる場合、partial export(特定のテーブルやスキーマだけエクスポートする方法)はサポートされていません。
スナップショット全体のエクスポートする場合はこの制限を受けません。

同じスナップショットを複数同時にS3にエクスポートできない
同じスナップショットを使って複数同時にエクスポートすることはできませんでした。

まとめ

RDSにあるデータをS3へ保管する方法はいくつかありますが、今回追加されたスナップショットからのS3エクスポートの機能は、
・運用中のDBからエクスポートの処理を行わないのでDBに負荷がかからない
・エクスポートの処理が他の手法と比較すると早い
というメリットを感じました。

S3に置いてしまえば、あとはAmazon Athenaを使って解析などもお手軽にできます。今後色々と活用する機会がありそうな機能ですね。