LoginSignup
1
0

More than 1 year has passed since last update.

DynamoDBテーブルのAthena参照をServerlessFrameworkで構築

Posted at

以前、参考記事通りにCDKで組んだことがあったのですが、CDKでできるならCFでできないか?エクスポート周りもCLI(シェル)でやってたので、SDKで組めないか?

そこから今回のを組みました。

クラメソさんの記事が思惑に完全一致でした。大感謝。

Exportのコスト回りや仕組みについては、下記に詳しくまとめている方がいたので、こちらを見ると非常にわかりやすいです。

全体設計

image.png

  • 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に増やすの微妙ですが、そこに追加していけばです。)

確認

連携がうまくいけば、画像の感じに確認できます。
image.png

参照が、Item.id.sと微妙ですが、view作っちゃえば綺麗に使えます。

まとめ

Glueの定義で正解がわからず、少し苦労しました。
Blackbelt調べたらあったので、そのうち見てみようかなと。

あと、ListBucket(削除時に利用)。どの権限が必要かで詰まったのと、フェッチ量が多いと1回で取れないってのが気付くまでに時間食いました。(1回目がうまくいってたが故にハマった。。。)
そう言うのは経験積んで減らしていきたいです。

Athenaでも、使いすぎるとお金かかるかもですが、小規模ならほぼ無料みたいなものなので、そういうところはAWS様様です。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0