DynamoDBテーブルのAthena参照をServerlessFrameworkで構築
以前、参考記事通りにCDKで組んだことがあったのですが、CDKでできるならCFでできないか?エクスポート周りもCLI(シェル)でやってたので、SDKで組めないか?
そこから今回のを組みました。
クラメソさんの記事が思惑に完全一致でした。大感謝。
Exportのコスト回りや仕組みについては、下記に詳しくまとめている方がいたので、こちらを見ると非常にわかりやすいです。
全体設計
- dynamoのエクスポートが毎回新しいファイルを新しい階層に作る
- 参照不要なファイルが多々ある
って形でしたので、
- エクスポート→必要なファイルだけコピー→コピー先を参照
ってことしてます。
API設計
API(3つ)
- [GET]対応リージョン取得
- [GET]テーブル一覧取得(query: region)
- [POST]エクスポート実行(body: region & table)
- 1: エクスポート処理中チェック (DynamoDB: listExports)
- 2: 過去データ削除 (S3: listObjectsV2 & deleteObject)
- 3: ポイントインタイムリカバリ、オン(DynamoDB: updateContinuousBackups)
- 4: DynamoDBエクスポート開始(DynamoDB: exportTableToPointInTime)
- 5: ポイントインタイムリカバリ、オフ(DynamoDB: updateContinuousBackups)
※ロジックは割愛。上述のAPI使えばいけます。
S3イベント(1つ)
- ファイルコピー用Lambda
- Exportされたら発火。ファイルをコピーする
環境
nodejs14.x
Serverless Framework: 2.57.0
実装
serverless.yaml
※ポイントのみ、記載
・・・
iamRoleStatements:
- Effect: 'Allow'
Action:
- "dynamodb:ListTables"
- "dynamodb:ExportTableToPointInTime"
- 'dynamodb:ListExports'
- 'dynamodb:UpdateContinuousBackups'
- 'dynamodb:ExportTableToPointInTime'
Resource: '*'
- Effect: 'Allow'
Action:
- 's3:GetObject'
- 's3:CopyObject'
- 's3:DeleteObject'
- 's3:AbortMultipartUpload'
- 's3:PutObject'
- 's3:PutObjectAcl'
Resource:
- "arn:aws:s3:::${env:DYNAMO_ANALYTICS_BUCKET}/*"
- Effect: 'Allow'
Action:
- 's3:ListBucket'
Resource:
- "arn:aws:s3:::${env:DYNAMO_ANALYTICS_BUCKET}"
・・・
layers:
node:
path: layer/modules/node
name: ${self:service.name}-${sls:stage}-nodeLayer
description: Description of what the lambda layer does
compatibleRuntimes:
- nodejs14.x
package:
patterns:
- node_modules/**
・・・
functions:
api-export:
handler: dist/table-export/src/index.handler
events:
- http:
method: ANY
path: '{proxy+}'
private: true
- http:
method: ANY
path: '/'
layers:
- { Ref: NodeLambdaLayer }
dynamoExport:
handler: dist/table-export/src/standalone/main.dynamoExportHndler
layers:
- { Ref: NodeLambdaLayer }
events:
- s3:
bucket: ${env:DYNAMO_ANALYTICS_BUCKET}
event: s3:ObjectCreated:*
rules:
- prefix: exports/
- suffix: .json.gz
・・・
resources:
Resources:
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: !Sub glue-database-${sls:stage}
GlueTable:
Type: AWS::Glue::Table
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseName: !Ref GlueDatabase
TableInput:
Name: !Sub glue-table-${sls:stage}
TableType: EXTERNAL_TABLE
StorageDescriptor:
Location: !Sub s3://${env:DYNAMO_ANALYTICS_BUCKET}/athena/data
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Parameters:
EXTERNAL: true
Columns:
- Comment: "id test"
Name: 'Item'
Type: 'struct<id:struct<S:string>,name:struct<S:string>>'
SerdeInfo:
Parameters:
paths: "Item"
SerializationLibrary: org.apache.hive.hcatalog.data.JsonSerDe
- Glueテーブルは必要に応じて拡張させる。(Typeに増やすの微妙ですが、そこに追加していけばです。)
確認
参照が、Item.id.sと微妙ですが、view作っちゃえば綺麗に使えます。
まとめ
Glueの定義で正解がわからず、少し苦労しました。
Blackbelt調べたらあったので、そのうち見てみようかなと。
あと、ListBucket(削除時に利用)。どの権限が必要かで詰まったのと、フェッチ量が多いと1回で取れないってのが気付くまでに時間食いました。(1回目がうまくいってたが故にハマった。。。)
そう言うのは経験積んで減らしていきたいです。
Athenaでも、使いすぎるとお金かかるかもですが、小規模ならほぼ無料みたいなものなので、そういうところはAWS様様です。
参考
Author And Source
この問題について(DynamoDBテーブルのAthena参照をServerlessFrameworkで構築), 我々は、より多くの情報をここで見つけました https://qiita.com/aioa/items/162c2e51bc822b8a63e9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .