💭

DynamoDBとAuroraで作るミニマムなデータ基盤の事例紹介

2024/05/17に公開

はじめに

はじめまして。

CoeFont株式会社に業務委託として入社して、はや1年のsugasugaです。

CoeFontは「欲しい声が1秒で手に入る」をコンセプトに最新のAI技術を活用し、「声」を表現豊かな「フォント」として利用できるサービスになります。

https://coefont.cloud/

今回、ミニマムなデータ基盤を作成したので、紹介させていただきます。

全体像(簡易版)

作成したデータ基盤を簡易な図で示します。

CoeFontのサービスはAWS上で動いており、そのデータをGCPのBigQuery(以下BQ)に転送し、データ基盤を作成しています。

基盤の中身

これまではデータ基盤が存在しませんでした。そのため、分析ユーザーにとって使いやすく、かつ素早く簡単に作成することに焦点を当てました。

データウェアハウスの選定

Redshift、Athena、Snowflake、BQなどの選択肢がある中、BQを選びました。

理由は、BQが弊社の分析ユーザー・管理者視点から使いやすいと判断したからになります。前職などでBQの分析ユーザーだったエンジニアが何人いました。また、BQはサーバレスサービスのため管理コストが低く、特にデータ基盤をメインで管理していく私がBQを何年か使った経験がありました。

追加で、将来的にデータウェアハウス以外のサービス(Dataform、Cloud Composer、Cloud Runなど)を活用できる可能性も考慮しました。

Extract

CoeFontのサーバーはAWS上で動いており、データベースとしてAmazon AuroraとDynamoDBが採用されています。この2つのデータベースからデータをExtractする必要がありました。

Amazon Auroraの方は、S3 export機能を使っています。
DynamoDBの方もポイントタイムリカバリ機能を使ってS3にexportを行っています。
どちらもデータベースのパフォーマンスに影響することなく、exportが行えます。
データベースのレコードをS3にexportするコマンドを発行するLambda関数を、Cloud Watch Eventで1日1回実行しています。

Load

GCPのBigQuery Data Transfer Servieを使って、データをBQにロードしています。

Amazon Auroraの場合は、出力データがParquet形式になっており、テーブルを定義せずともData Transfer Serviceを実行できます。

しかし、DynamoDBの場合、ハマりポイントがありました。
exportされたデータは、Json形式になっており事前にテーブルとスキーマを定義しておく必要があります。(Data Transfer Servieはスキーマのauto detect機能が使えません)

そのため、テーブルの追加のためには、手動で事前に一時的なテーブルをauto detect機能を使って作成。その後、下記のコマンドでスキーマ情報を取得します。

bq show \
--schema \
--format=prettyjson \
プロジェクト名:temp.テーブル名 > schema.json

最後に、terraformでテーブルを手動で定義し、データ転送を行うような運用にしています。

resource "google_bigquery_table" "テーブル名" {
  dataset_id          = google_bigquery_dataset.データセット名.dataset_id
  table_id            = "テーブル名"
  deletion_protection = false

  schema = <<EOF
	~~~~
EOF
}

ここら辺は、マネージドな転送サービスやEmblukなどを使えば無くなる可能性がありますが、実装コスト・料金面から見送りました。

Transform

初期の見積もりでは、データ整形の工程は発生する予定はありませんでした。

しかし、DynamoDBのデータをBQに読み込ませてみると、スキーマがかなり複雑になることが判明しました。

結果、下記のような余計に複雑なクエリを書く必要がありました。

SELECT item.カラム名.S FROM テーブル

また、カラムの並び順が、分析で使う際に直感的にわかりにくいような並び方になりました。(例えば、主キーが10列ある中で7列目に並ぶなど)

そのため、データを整形し分析を行いやすくする必要がありました。初期段階だと複雑なパイプラインは必要ないと判断し、クエリを定期的に実行できるQuery Schedulerを使用しています。

下記のようなクエリを毎日実行することができ、先述の問題を解決することができています。

CREATE OR REPLACE TABLE 整形後のテーブル名
(
カラムA STRING OPTIONS(description="カラムに関する説明"),
  カラムB STRING,
  カラムC TIMESTAMP,
  カラムD FLOAT64
) OPTIONS( description = "テーブルに関する補足" ) as 
SELECT 
  Item.カラムA.S as カラムA,
  Item.カラムB.S as カラムB,
  TIMESTAMP_SECONDS(Item.カラムC.N) as カラムC,
  Item.カラムD.N as カラムD  
FROM 
  整形前のテーブル;

Query Scheduler以外の他の選択肢の一つであるCloud Composer(マネージドなAirflow) のようなワークフローツールの導入は、初期段階にしては料金が嵩張りそうであると判断しました。また、自前でホストするようなワークフローツールは、料金に加え実装コストがかかりそうなため、見送りました。

さらに、dbtやdataformを検証してみたりしたのですが、初期の作成コストやメンテナンスのコストを考慮し、見送っています。

依存関係のあるようなクエリが今のところはないため、そこまで困っていないですが、将来的には上記のツールを導入する予定です。その際に、Query Schedulerから移行するのは非常に簡単なため、かなり良い初期の実装ができたと感じています。

データの可視化

BQには可視化機能があります。また、Looker Studioを使って可視化することもできます。
スプレッドシートなどで可視化することもできます。一旦は、そういった機能を使ってデータの可視化を行う方針にしています。

インフラの管理

IaCのためにterraformを使っています。今回作成したリソースは全てterraformで管理することができました。具体的には、BigQuery Data Transfer ServiceやScheduled Queryなどの設定を行っています。加えて、ユーザーごと組織ごとのBQのスキャン量を制限し、慣れていないメンバーが意図しない課金を発生させてしまうことを防ぐことができています。

また、ポリシータグを設定することで、ユーザー情報などセンシティブなデータのアクセスを制限しています。

改めて詳細な全体像

以上の話を踏まえて、詳細な全体像は下記になります。

さいごに

将来の展望について話します。

現在、弊社はサービス拡大に向けて、データに基づいた施策立案・検証を行っています。この基盤を使い、さらにそのサイクルを加速させていきます。

データ基盤において、まだまだやるべきこと・やりたいことがたくさんあり、チャレンジングな環境です。正社員・副業に関わらず、エンジニアを募集しており、基盤を整備してサービス拡大を行いたいというエンジニアの方とお会いできるのを楽しみにしています。

カジュアル面談も実施しておりますので、お気軽に連絡ください。

CoeFont

Discussion