本記事は、Thrive Learningのデータエンジニアリングチームによって執筆されました。記載されている見解や経験は同チーム独自のものです。
Snowflakeの導入前、Thriveのレガシーアナリティクスは、スケジュールされたバッチジョブと、スケジュールに従ってリフレッシュをトリガーするMongoDB変更ストリームを組み合わせて実行されていました。同チームがSnowflakeに移行した際、遅延のあるバッチ処理ではなく、変更が到着するたびにプラットフォームデータを継続的に同期および変換するという中核的な要件に基づき、当初からダイナミックテーブル上に構築しました。
このデータの鮮度は、バックオフィスの単なる利便性ではなく、プロダクトの一部です。ThriveのAnalyseスイート(お客様がすべての学習データを探索できる機能)は、Thriveプラットフォームが提供する中核的な要素です。また、パフォーマンスとデータ鮮度の向上が、お客様の満足度や営業活動における競争力に直結することも分かっています。お客様はアナリティクスを単独の項目として購入するわけではありませんが、その品質はThriveがビジネスを獲得し維持できるかどうかに直接影響します。最近では、この同じデータとダイナミックテーブルの基盤が、Thrive初の有料アドオンプロダクトである「Analyse with AI」を支えています。これは、既存のデータパイプラインの上にAIを重ね合わせたものです。
本記事では、新しいカスタム増分更新機能を使用して、ダイナミックテーブルのコストパフォーマンスをどのように改善したかをご紹介します。ThriveのシニアデータエンジニアであるRob Howe氏が、この取り組みを主導しました。同氏は、カスタム増分更新が直面していた課題に最適であると判断し、このソリューションを考案してテストを行い、数週間で本番環境にデプロイしました。
Thrive Learningの概要
Thriveは、製造、航空、小売をはじめとする多様な業界において500社以上のB2Bテナントにサービスを提供する、英国発のエンタープライズ向け学習プラットフォーム(LMS/LXP)です。Thriveのデータ&AIエンジニアリングチームは、アナリティクスおよびAIプロダクトの基盤スタックをSnowflake上で稼働させており、Dynamic Tables(ダイナミックテーブル)を全面的に活用して生の運用データを分析・予測モデルへと変換しています。これらのモデルは、顧客向けレポート機能やThriveのAIアシスタントの基盤として活用されています。
重複排除の複雑さによるコストの増加
社内でRecordStoreと呼ばれるThriveのコアパイプラインの1つは、まさにダイナミックテーブルの用途に最適なものとして始まりました。つまり、シンプルで自動的にリフレッシュされる、実質的な追加コストのない増分ダイナミックテーブルです。
問題は、チームが追加のキーでデータを強化する必要が生じたときに始まりました。特定のIDがアップストリームに確実に配置されていなかったため、それらを解決するには複数のソース(最大5つ、後に3つに最適化)をまたいで結合する必要がありました。これらの結合によって重複が発生したため、重複排除を追加する必要がありました。この複合的な複雑さにより、Snowflakeはテーブルを増分的にリフレッシュできなくなりました。その結果、フルリフレッシュにフォールバックしました。
変換コストを削減するため、チームはデータを2つのレーンに分割しました。6時間ごとにリフレッシュされる最近のデータの「ファーストレーン」と、毎週リフレッシュされる古いデータの「スローレーン」です。これにより変換コストは削減されましたが、2つのレーンの最終的なUNIONにより、自動クラスタリングコストが急増しました。チームは、あるコストを別のコストと引き換えている状態になりました。最悪の場合、このパイプラインは自動クラスタリングコストと変換コストを合わせて、1日あたり数百クレジットを消費していました。
すべての緩和策は対症療法にすぎませんでした。真の根本原因はアップストリームの信頼性の低いコンテンツIDであり、それが修正されるまでチームは行き詰まっていました。
ダイナミックテーブルへのカスタム増分更新の追加
チームが検討していたパターンは、Snowflakeのストリームとタスクでした。つまり、実際に変更された行のみを処理し、マージロジックで適用するというものです。ストリームとタスクのパイプラインは複雑さの急増にうまく対処できたはずですが、Thriveのエンジニアが指摘したように、鮮度をさらに高めようとした場合、全体的なリフレッシュラグの制御が困難になるという問題もありました。
ダイナミックテーブルのカスタム増分更新(REFRESH_MODE = CUSTOM_INCREMENTAL)は、そのトレードオフを解消しました。チームは、CHANGES()に対してMERGE INTO SELFを使用した明示的なREFRESH USINGロジックを記述し、このパイプラインにおける「増分」の意味を正確に定義しました。つまり、差分のみを処理してマージし、それ以外はそのままにするということです。チームは望んでいたストリームとタスクの実行モデルを手に入れましたが、スケジューリング、再試行、トランザクションの保証、およびラグの管理は引き続きSnowflakeが行います。
その結果、次の2つのことが起こりました。
- 変換による全データの再処理が停止:結合や重複排除の複雑さに対処するためのフルリフレッシュではなく、各リフレッシュで変更された行のみが処理されるようになりました。
- 自動クラスタリングの頻繁な再編成が停止:完全な再構築がなくなり、ファースト/スローのUNIONを維持する必要もなくなったため、クラスタリングはほぼゼロに落ち着きました。
“カスタムでの差分更新(インクリメンタル処理)を実装したことで、スケジューリングやリトライ処理、ラグ(遅延)の制御はSnowflake側に任せたまま、私たちが求めていた実行モデルを実現できました。さらに、ロジックがdbtのDAG(有向非巡回グラフ)内にそのまま残るため、別途オーケストレーション層を保守・管理する必要もなく、パイプラインはデータリネージにおける位置関係をしっかりと維持できています。”
Alex Tasioulis
変換コストと自動クラスタリングコストの両方を削減
| コスト要因 | 移行前 | 移行後 | 削減率 |
|---|---|---|---|
| 自動クラスタリング | 〜約150クレジット/日 | 〜約2クレジット/日 | 〜約99% |
| 変換コンピュート | 〜約150クレジット/日 | 〜約5クレジット/日 | 〜約97% |
注:結果はThriveの社内本番環境での測定に基づいています。
各実行では実際に変更されたソースのみが検査されるため、パイプラインのリフレッシュレイテンシーも数時間から数秒に短縮されました。現在、パイプラインはデータの合計サイズではなく、データの変更率に応じてスケールしています。
カスタム増分更新により、Thriveは変換コストとクラスタリングコストのトレードオフを解消し、リフレッシュの動作を直接解決できるようになりました。同時に、手動で構築したストリームとタスクのパイプラインでは犠牲になっていたであろうラグ制御も維持しています。これは、変換を増分SELECTとしてクリーンに表現できないあらゆる場面で、チームが再利用を予定しているパターンです。
dbtで維持されるリネージ
Thriveにとって、カスタム増分更新がストリームとタスクという代替案よりも優れていた2つ目の理由は、ガバナンスです。Thriveはdbtで変換を管理しています。どのモデルがどのモデルにデータを供給しているかを正確に把握することは、チームがプラットフォームの構成を理解し、テストし、文書化する上で中心的な役割を果たします。
ストリームとタスクはdbtの外部に存在します。このロジックを手動で構築したストリームとタスクのパイプラインに移行すると、これらのオブジェクトがdbt DAGから完全に切り離されてリネージが損なわれ、チームはそれらを独立した別のシステムとして管理および監視する必要に迫られていたでしょう。
カスタム増分ダイナミックテーブルは、依然としてダイナミックテーブルです。カスタム増分更新に対するネイティブなdbtサポートはまだありませんが、チームはそれらをカスタムdbtマテリアライゼーションでラップし、dbtプロジェクト内の主要なノードとして維持できるようにしました。パイプラインはリネージグラフ内の位置を維持し、他のすべての要素と同じワークフロー、テスト、ドキュメントで管理されるため、個別のオーケストレーションレイヤーを維持する必要がありません。
今後のエージェント型AIユースケースに向けた、より安価で鮮度の高いデータ
チームは現在、同様の結合や重複排除の複雑さに直面している他のパイプラインにも同じパターンを適用しており、Thriveのアナリティクス環境全体で、コスト削減とデータの鮮度向上という同等の成果を期待しています。直接的なコスト削減にとどまらず、Thriveではすでにエージェント型AIがこのデータを消費しています。データをより安価に、かつニアリアルタイムで提供できるようになることで、同じデータでさらに多くのエージェント型AIユースケースをサポートできるようになり、ThriveプラットフォームはAI機能をさらに拡張するための強力な基盤を築くことができます。


