この記事は BASE アドベントカレンダー 16日目の記事です。
はじめに
こんにちは、CSE Group ※1 で社内の業務効率化の開発をしている上野です。
アドベントカレンダー15日目は @miyachin_87 さんの記事でした、みなさんもうお読みでしょうか?私は特に業務効率化の開発をしているので Notion での自動タスク生成の話はとても参考になりました。まだの方はぜひお読みください!
さて、アドベントカレンダー16日目の本日は、レポートシステムの安定稼働をするための取り組みについて紹介します!
レポートシステムとは
BASEではJ-SOX対応の一環として、
- BASEショップの売上金と決済サービス側の入金データ
- BASEショップの売上金とBASE側の決済データ
- BASE側の決済データと決済サービス側の入金データ
- 決済サービス側の入金データと実際の入金額
これら4点の整合性が取れていることを確認することで財務報告上の信頼性を担保しています。 月初処理は月次でこれらの整合性が取れていることの確認を行うことを指しています。 (※2 より引用)
この整合性を取るためのデータ収集と、各種確認のクエリ実行を行うのがレポートシステムです。
具体的には以下のような処理を行っています。
- BASE の DB を日時で取得し Amazon Athena にデータを登録する
- 各決済システムからデータをダウンロードし、Amazon Athena にデータを登録する
- クエリでデータを突き合わせ、整合性が取れていることを確認する
簡単なアーキテクチャ図はこのようになります。
レポートシステムの問題点
上記の処理のうち 1. の DB のデータを Embulk で Athena に取り込む処理で、次のような課題がありました。
- 実行時間が長くなっていった
- ECS で分散処理をしていましたが、それでも午前2時に実行を開始して、午前9時過ぎまでかかることもあり、朝9時の日次レポートに処理が間に合わないことも多くなっていました。
- また、何かしらで処理が詰まってしまい、翌日まで実行が完了していないなども目立ってきていました。
- エラーが頻発するようになった
- 上記の遅延が目立つ様になってきたころから、エラーとなることが多くなっていました。(翌日までかかっても終わらず処理がバッティングする、コピーされた DB の削除処理が正常に動作できない、など)
- また、リカバリも再実行に 6~8 時間ほどかかってしまうため、朝にエラーに気づいて夕方にようやくデータが渡せる状況になってしまっていました。
- Embulk のメンテナンスなどに工数が割けない
そのため、処理速度の向上とメンテナンスコスト削減のため、マネージド・サービスを利用したETL機構に置き換え、安定稼働を目指しました。
技術選定
BASE では DB に Aurora MySQL を使用しています。 Aurora MySQL では 2022年に S3 にエクスポートする機能がリリースされていたため、これを使用することにしました。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/export-cluster-data.html
https://dev.classmethod.jp/articles/aurora-cluster-export-s3/
その他、AWS Glue で Aurora のデータを出力する方法などもありそうでしたが、BASE 社内でも Data Platformチームでの利用実績もあったことや、今までのレポートシステムが Step Functions と Lambda を SAM で管理をしており知見があったため、Lambda で Aurora S3 Export を実行する形を選定しました。
検討したこと
データのエクスポートの技術を選定しましたが、具体的な方法について以下のようにな選択肢がありそれぞれ検討しました。
- BASE の本番アカウントで DB を直接エクスポートする
- 今まで通り BASE の本番アカウントからレポートシステムにDBをコピーし、コピーされたDBからエクスポートする
1.の方法でのメリットは、2.の方法と比べるとレポートシステムのアカウントで DB を建てる必要がなくなるため、コストが削減できるという点です。対してデメリットは、レポートシステムのアカウント外での処理をワークフローに組み込む必要があることなど、複雑性が上がってしまう点でした。
2.の方法のメリットは1.の逆で、すべてレポートシステムのアカウント内で完結するため比較的複雑性が低く、CSE チーム内ですべて完結できる点で、デメリットは DB のコストでした。
しかし、2. の方法でのデメリットのコストについては、今までも同様に DB をコピーしているため大幅なコスト増加はないであろうこと、エクスポートの処理のほうが高速になるため、DB インスタンスの立ち上がっている時間の短縮ができ、結果としてある程度のコスト削減は見込めるため大きなデメリットにはならないだろうということで、2. の方法で実施することにしました。
最終的なアーキテクチャ
前述の事項を考慮した最終的なアーキテクチャは以下のようになります。
図式化する関係で簡略化しておりいくつか盛り込めていない点があるので、その点についてもいくつか紹介します。
- コピーしてきた DB を一度 Snapshot を取得して、Snapshot に対して、エクスポートを実行している
- 原因がはっきりしていませんが、コピーしてきた DB クラスタに対して直接エクスポートをするとエラーとなってしまったため Snapshot を経由してエクスポートする処理になりました。
- Snapshot からのエクスポートのため、Snapshot が完了した段階で並行処理で DB クラスタの削除処理を実行している
- DB インスタンスが立ち上がっている時間を極力減らしたい、処理時間を長くはしたくないということで並行して実行するようにしました。これが後述するコストにもある程度効いていそうです。
- DB のコピー、Snapshot の取得、Glue crawler の実行など、ある程度時間がかかる処理は Step Functions で処理の完了を監視するような分岐を実装しました。
これらを盛り込んだ Step Functions の全体像はこのようになっています。またこれらのリソースはすべてSAMでコード化し、GitHub上で管理しています。
置き換えの効果
実行速度、安定稼働
約8時間 → 約1時間半
以前は実行時間が実質8時間以上(DB のコピーが午前1時開始、その後の Embulk の処理が2時開始のため)かかっていました。また、週に1回はエラーが出てしまう状態でした。

置き換え後は2時間かかることはほぼなく、エラーも置き換え直後の微調整以外なく安定して稼働できました。
コストの削減
コスト削減は前述の通りスコープ外だったのですが、実行時間が早くなったことにより Aurora のインスタンスが立ち上がっている時間が大幅に短くなったことや、Embulk での I/O がなくなったことなどの要因で RDS のコストが大幅に削減されました。エクスポートに関わる課金もあると思いますが、削減のほうが上回り、結果としてレポートシステムのアカウントでの全体コストも削減することができました。(9月以前の1年間の平均が$541、10月の途中に処理を置き換えたため10月は $114 とある程度削減され、完全に置き換えられた11月では 約$4 にまで下がっていました。1/100 以下になるとは驚きです。)


運用コスト削減
Step Functions と Lambda でワークフローを構築しているため、完全に運用コストがなくなったわけではありませんが、Embulk を完全に利用しなくなったことで、Embulk のバージョンアップなどを気にする必要がなくなりました。
まとめ
レポートシステムのデータ取得処理を Embulk から Aurora S3 Export に変更したことで8時間かかっていた処理を1.5時間ほどまで高速化することができました。
それにより毎朝9時の通知にデータを間に合わせることができるようになり、またエラー頻度も削減でき安定的に運用できるようになりました。
また、副次的な効果として、主に RDS のコストを $500/月 から $4/月 と、99% 削減もすることができました。
おわりに
明日のBASEアドベントカレンダーは @eijenson の記事です、お楽しみに!
また、BASE では Web アプリケーションエンジニアを積極採用しています。興味持っていただいたら、ぜひご応募ください!
採用情報 | BASE, Inc. - BASE, Inc.
※1 CSE チームについては少し古い記事ですがこちらをごらんください。