Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

社内向けのデータ基盤から集計結果をReverse ETLしてサービスに組み込んだ話

こんにちは、データエンジニアの滑川(@tomoyanamekawa)です。
Classiでは2022年5月に学校内のユーザー利用状況を集計し可視化したダッシュボード機能をリリースしました。
この機能のデータ集計は既存の社内用データ基盤からのReverse ETLで実現しました。
そのアーキテクチャの説明と「社内用データ基盤」から「ユーザー影響あるシステムの一部」になったことによる変化について紹介します。

ダッシュボード機能とは

  • 概要
    • 先生のみが利用可能な機能
    • 先生と学年・クラスごとの生徒の利用状況を可視化したダッシュボードを提供する機能
  • 要件・制約
    • アプリケーションはAWS上で動かす
    • 前日までの利用状況がアプリケーション上で朝8時までに閲覧可能になっていること
    • 学校/学年/クラスごとで集計する
    • 学校を横断した集計はしない

既存の社内用データ基盤とは

社内でのデータ分析を主な用途としているBigQueryを中心にした基盤のことです。
この記事の範囲では「AWS上で動いているアプリケーションのデータを日次でBigQueryに集約し、集計している」ということがわかれば十分です。
もし詳しく知りたい場合はこちらの記事で紹介しています。

Reverse ETLとは

各アプリケーション等からデータ基盤に集約・集計(ETL処理)したデータを、アプリケーションで二次利用するためにアプリケーション側の何らかのデータベースに書き戻す処理のことです。

もっと適切な定義があるかもしれませんが、当記事ではこの認識で進めます。
もしReverse ETLについて知りたい場合はこのあたりの記事がいいと思います。

この記事で話さないこと

  • アプリケーションの実装などのReverse ETLより後段のシステムについて
  • ダッシュボード機能のUIや集計内容含めた詳細
  • 既存のデータ基盤の詳細

Reverse ETLのアーキテクチャ

データ基盤のアーキテクチャ図

処理の説明

上記のアーキテクチャで日次のバッチ処理でデータを連携しています。
赤枠部分がReverse ETLに関連する部分です。

全体のワークフローはCloud Composerで管理しています。
DataLake側からDAGをトリガーして、下記の処理を順番に行うようになっています。

  • BigQuery上でqueryを実行しテーブルを作成
  • 集計結果のvalidation
  • AWS Step Functionsの実行をトリガーする

トリガーされたAWS Step Functionsが集計結果の書き込みを担っていて下記のような処理をしています。

  • 書き込み先の新しいテーブルをRDSに作成
  • 学校ごとにLambda jobを作成し、各LambdaがBigQueryからのデータ取得・RDSへの書き込みを行う
  • 全学校分の処理が正常に終わった場合にアプリケーションから参照するテーブルを新しいテーブルに切り替える

このアーキテクチャになるまでの背景

なぜアプリケーション上で直接集計せずに既存のデータ基盤を経由する選択をしたのか?

  • 複数のDBをまたぐ必要があり、1つのアプリケーションから横断的にアクセスするには既存の全体インフラ構成から変更が必要だった
  • 今後ログデータも集計に使う可能性があり、集約場所・データ量の観点からBigQueryが必要になりそうだった
  • 既存のデータ基盤でデータ集約や管理体制などがすでにある程度整っていて流用可能そうだった

データ基盤からのReverse ETL以外で検討した(が選ばなかった)選択肢

  • SaaSのBIツールを用いてデータ基盤上のデータから直接ダッシュボードを作成して、アプリケーションにembeddedする

    • そもそもアプリケーション側での可視化の実装がいらなくなり、ユーザー側で任意の集計が可能になるなどのメリットがあったが費用面から断念した
  • アプリケーションから直接BigQueryに接続する

    • BigQueryからのレスポンスが遅く、アプリケーションとして許容できなかった
    • BigQuery上での計算時間に関してはBI Engineやアプリケーション側でのキャッシュ等での高速化は可能だが下記の観点で不十分だった
      • この方法では初回の計算時間がかかってしまうことは避けられず、機能の特性上「1日1回見る」というユースケースが想定されるため、ユーザーの初回アクセス時に時間がかかることを許容できなかった
      • そもそもBigQuery上での計算時間以外の接続等でも時間がかかっていて、高速化の限界があった

Reverse ETLする上で他に検討した(が選ばなかった)選択肢

  • 書き戻し先をRDB以外にする

    • 集計の軸やデータの集計期間から今後のデータ量を考えるともRDBMS(postgreSQL)で対応できそうだった
    • 一般的なRDBMSで対応できそうであればその他のデータベースを優先する大きな理由がなかった
  • 書き戻し先をCloud SQLにする

    • Cloud SQLも選択肢に入ったが下記の理由からRDSを選択した
      • BigQueryからのwriteは1回/日なのに対してアプリケーションからのreadはもっと多いので、RDBはBigQueryよりアプリケーションに近い位置にあるほうが良かった
      • 社内的にCloud SQLよりRDSのほうが運用ノウハウがあった

社内用データ基盤からユーザー影響のあるシステムになったことによる変化

当たり前ですが、障害が起きた場合にユーザーにご迷惑をおかけしてしまうのでシステムを安定稼働させることの重要性が上がりました。
そのため社内用データ基盤であった時に設けていた基準よりも一段厳しくする必要がありました。
その対応内容を下記に示しますが、振り返ってみると新規の大きな問題は発生しておらず、元々それなりのレベルでデータ基盤を運用できていたという自画自賛をチームでしました。

気にしたこと・対応したこと

  • 社内用の分析のための処理とユーザー影響のある処理の分離

    • Google Cloudのリソースの観点では元々datalake用のprojectと社内ユーザーが利用するprojectは分けていたため問題なかった
    • Cloud Composer上のワークフロー(DAG)では処理が混ざっていたので、DAGの分離とコード整理をして気軽にデプロイしていい範囲とそうでない範囲をコードベースで分けた
  • データ基盤のSLO計測

    • もともと取り組んでいたので、計測・可視化自体は問題なかった
    • ダッシュボード機能の要件を元に基準にしている時刻・稼働率を引き上げるのみで済んだ
  • alert基準・通知の見直し

    • 何らかの想定外があった時は後続の処理でalertが飛べばいいという前提でalertを仕込めていなかった部分があったが、各処理ごとにalertが飛ぶようにした
    • errorは起きていないが、処理が遅れている時に気づくために遅延通知を導入した
  • デプロイフローの強化

    • CIでのチェックの強化
    • devからprodに上げる際の運用の明文化

残課題

  • 処理時間が長いため、障害時の復旧に時間がかかる
    • 現状では数時間かかる処理が含まれており、大幅短縮するためにはアーキテクチャレベルでの変更が必要だが着手できていない
  • このデータ基盤での障害発生時に対応できる人が少ない
    • 普段からデータ基盤を触っているデータエンジニアは障害から復旧させられるが、他のエンジニアでは権限や前提知識など様々な理由で状況を把握することができない
    • 以前はデータエンジニア内だけで十分であったが、データエンジニアも人数が少ないので安定稼働の観点では心許ない
  • データ品質の担保
    • データマネジメント文脈で「データ品質」と言うと様々な観点が出てくるのでここだけでは書ききれませんが、ユーザー影響のあるシステムになったことでデータ品質の要素の網羅性や各要素で求める基準が上がったがまだ改善途中という点で課題が残っている
    • 例えば有効性の観点では、集計後の一番最後の段階でユニーク性や値の範囲を確認して一定の担保はしているが、データが変換される各フェーズごとでチェックするほうが望ましい

データ基盤としての今後

このリリースによってデータの価値をユーザーに直接届けられるようになりました。
以前は社内の意思決定など間接的な形でしかユーザーに価値を届けることが出来なかったので、これはデータ基盤にとって大きな一歩です。
今後も機械学習などを含めた様々な形でデータからユーザーに価値提供することを考えています。

データ基盤に閉じた範囲では、肥大化したデータ基盤をデータメッシュをベースにした形でのリアーキテクチャを検討しています。
現状のデータ基盤はdatalakeにデータを集約して1つのデータパイプラインに載せるというモノリシックな構成になっています。
また、各層でデータを実体化させて保持しており、データの二重持ちによる無駄が発生してしまっています。
この状態では、今後データの入力・出力ともに増えたきた時に不要な依存関係や権限の管理コストが大きくなってしまうことが想定されるので、この問題に向き合います。

上記のようにまだまだやることがあるので、一緒に進めてくれる方を募集しています!
興味を持った方はこちらからどうぞ!

© 2020 Classi Corp.