はじめに
こんにちは。データエンジニアとして社内横断で使われるデータ基盤 Crois の開発を担当している青木です。
2024 年 9 月に開催された AWS Innovate - Migrate. Modernize. Build. にて、「リクルートのデータ基盤 Crois - 年 3 倍成長! 1 日 40,000 コンテナの実行を支える AWS 活用とプラットフォームエンジニアリング」というタイトルで発表を行いました。
汎用的なワークフローエンジン・ジョブスケジューラとして開発された Crois は、リクルートのデータ利活用の進化に伴い急速に利用が拡大しています。 その急成長を支えている要因として、AWS の活用・プラットフォームエンジニアリングの実践という 2 つの観点に着目しお話しさせていただきました。
本記事では、その内容をご紹介します。
本記事は、データ推進室 Advent Calendar 2024 11日目の記事です
発表スライド・動画
発表に使用したスライドを公開しています。 動画 も公開されていますので、併せてご参照ください。
Crois の概要
Crois はバッチ処理に特化したワークフローエンジン・ジョブスケジューラです。
事業や案件を横断して活用可能なシステム (横断データプロダクト) として開発されており、リクルートの様々な事業領域のデータ利活用施策を支えています。
主な機能を紹介します。
ひとまとまりの処理を実装しコンテナイメージにしたものを「モジュール」と呼んでいます。 以下のように一覧画面からモジュールを選択し、ワークフローに組み込むことができます。
ワークフロー定義は YAML で記述します。 タスク間で受け渡すパラメータや入出力ファイルの設定、コンテナ実行環境のスペック指定も可能です。 ワークフローはスケジュール実行、アドホックなオンデマンド実行が可能です。
実行されたワークフローを「ジョブ」と呼んでいます。 以下のように、ログやメトリクスを閲覧することも可能です。
こうした機能を備え、スケーラビリティ・セキュリティを確保した基盤を Crois が提供することで、事業領域データ組織のデータサイエンティスト、データエンジニア、機械学習エンジニアがより創造性の高いタスクに注力できる状態を実現しています。
Crois の規模と利用の拡大
Crois は現在、1日あたり 17,000 ジョブ、40,000 コンテナ 1 を実行する基盤になっています。 ピーク時間帯には計 30,000 vcpus の処理が並列で実行されています。
2019 年のリリースから約 5 年、重複する機能を持つ社内基盤の統合・移行や、各事業領域でのデータ利活用の拡大を経験しながら、平均年 3 倍のペースで指数的に利用量が増加し続けています。
Crois はプラットフォームとしてなぜこの 5 年間スケールし続けることができたのでしょうか?
「技術的にスケールできない」「運用がパンクする」「ユーザに使われなくなる」といった落とし穴がある中で、Crois が広く使われ続ける要因は、「スケーラブルな AWS マネージドサービスの活用」「プラットフォームエンジニアリングの実践」 という2つの軸にあると考えています。 それぞれ、以下で詳しくご紹介します。
スケーラブルな AWS マネージドサービスの活用
Crois は、その運用開始当初から社内横断で使われることを意識して設計が行われています。 横断的な利用に堪える高いスケーラビリティを、1 つのチームで担える低い運用負荷で実現させるため、 AWS のマネージドサービスを中心に採用しています。
ワークフロー
Crois のワークフローは AWS Step Functions のステートマシンに変換され、実行や制御を全て委譲しています。 例えば図左下のようなワークフローは、Crois が右のようなステートマシンに変換しています。
コンテナ実行基盤
Crois のコンテナ実行基盤には AWS Batch (on Amazon ECS, Amazon EC2) と Amazon ECS on AWS Fargate を利用しています。
インスタンスのプロビジョニングやスケーリング、コンテナの実行環境の管理を AWS に委譲することで、低い運用負荷と高いスケーラビリティを実現しています。
ジョブ・タスク状態管理
ジョブ・タスクの状態管理には、イベント駆動のアーキテクチャを採用しています。
以下のように、ジョブやタスクの状態変化のイベントが発生すると EventBridge を経由して Lambda が実行され、DynamoDB に状態を反映する仕組みをとっています。 イベント駆動アーキテクチャは障害に強く、またスケールも容易に行えるという運用上のメリットがあります。
例えば 1 つのコンポーネントに一時的に障害が発生してもアプリケーション全体が停止することはありませんし、回復時に自然に処理を再開できます。
マネージドサービスを中心に採用したことで、 高いスケーラビリティを実現しつつ、運用負荷を低く抑える ことができています。
プラットフォームエンジニアリングの実践
近年、 プラットフォームエンジニアリング という言葉が注目されています2。 社内のプロダクトチームに属する開発者を「ユーザ」として捉え、複雑なインフラを抽象化したプラットフォームをセルフサービス型プロダクトとして提供することで組織の生産性向上を図る取り組みです。 Crois は、現在プラットフォームエンジニアリングと呼ばれる取り組みをその運用開始当初から行ってきました。
チームトポロジーの視点
Crois は、チームトポロジーの用語では「プラットフォームチーム」と位置付けられます3。 「ストリームアラインドチーム」である各事業領域のプロダクトチームに対し、XaaS モード でのインタラクションを基本として、安定した能力・サービスを提供することが主な責務となります。
XaaS モードでは、プラットフォームチームとストリームアラインドチームの間に明確な境界、インタフェース4が置かれ、チーム間で共有するコンテキストが少ない状態を保ちます。 これによって、ストリームアラインドチームは独立して高速なデリバリーを行うことが可能になります。
XaaS モードでの典型的なコミュニケーションは、ストリームアラインドチームからは機能要望や問い合わせ、プラットフォームチームからはドキュメント、広報、SLO の提示といったものになります。 以下はその一例です。
プラットフォームとして XaaS モードを中心とした能力提供を行ってきた中で、 Crois が特に意識してきたことは 「セルフサービスな開発体験の徹底」 と 「動的に変化するインタラクションモード」 です。 それぞれ以下で詳しくご紹介します。
セルフサービスな開発体験の徹底
プラットフォームもしくは社内基盤とその利用者の関係で陥りがちなアンチパターンとして、プラットフォームを利用するために毎度プラットフォームチームに設定変更を依頼しなくてはならない、という状態が考えられます。
しかし、この状況では利用の増加に比例して運用コストが高まり、プラットフォームとしてスケールしません。 さらに、ストリームアラインドチームはプラットフォームチームの対応待ちで開発速度が阻害されますし、プラットフォーム側も自身の改善に時間が使えず、持続的な価値提供ができなくなってしまいます。
こうした課題への対処として、Crois ではライトユーザからコアユーザまで、それぞれの利用者のニーズに合ったセルフサービス機能を提供しています。
サービスへのインタフェース
多くのユーザが使用する基本機能の Web UI をはじめ、以下のような Web API や、ワークフローの設定等をコードで管理したいユーザ向けの IaC ツールを提供しています。
モジュール
先述の通り、 Crois ワークフローの一つひとつの処理ではモジュールと呼ばれるコンテナイメージを使用します。 よく使われる処理は公式モジュールとして提供することで、ユーザはすぐに Crois を使い始めることができます。 より高度な処理を行いたい場合は、ユーザ自身で独自にモジュールを作成することも可能です。
オブザーバビリティ
コンテナのログやメトリクスは Amazon CloudWatch と連携してユーザに提示しており、ユーザの開発・運用を容易にしています。 インフラコストも利用領域ごとに可視化しており、ユーザ自らコスト最適化に取り組むことができます。
ここまで見てきたようなセルフサービス重視な開発体験の徹底によって、運用コストの増加を抑え、持続的な価値提供を実現しています。
ただし、 Crois も最初から全てをセルフサービスにできていたわけではありませんし、何がユーザに求められているかが不明瞭な時点ではその必要はないと考えています。 ユーザのニーズや、プラットフォームチームの運用負荷の変化を常に注視し、提供の仕方を都度見直すことが重要です5。
動的に変化するインタラクションモード
基本的なインタラクションモードである XaaS モードの責任境界は、お互いの認知負荷を下げるために重要です。 しかし、XaaS モードでのインタラクションを続けていると、ユーザとの距離が離れすぎてしまい、「ユーザのことを知らない」「使われない機能を作ってしまう」といった課題が生じがちです。 こうなってしまうと、ストリームアラインドチームや組織全体の開発生産性に貢献できず、プラットフォームはだんだん使われなくなっていきます。
Crois では、以下のような 「個別最適と全体最適のループ」 によって上述の課題に立ち向かっています。
個別最適フェーズ
個別最適フェーズは、コラボレーションモード (= 2つのチームが責任を共有し素早く問題解決にあたるインタラクションモード) によってニーズのキャッチアップを行うフェーズです。
不確実性が高い案件フェーズ (例:他の社内基盤の Crois への移行) では、特に密接なコラボレーションを行い要望に対する理解を深めます。 チーム間で定期的なミーティングを行ったり、人材の兼務を行ったりするほか、プラットフォーム側からプロトタイプの実装を提供し早期にフィードバックをもらうなどといったケースもあります。
全体最適フェーズ
全体最適フェーズでは、個別最適フェーズでキャッチアップしたニーズを汎用化してプラットフォームに実装します。
個別最適フェーズで得られたユーザの要望自体は具体的な使用ケースが想定されたものですが、ここではその要望を汎用的な機能として実現し、全ユーザにとって利益がある方法での能力提供を行います。 このフェーズでは、改めて XaaS モードの考え方に立ち、チーム間の責任境界を明確にすることが求められます。
以下は、個別最適フェーズで得られたユーザの要望を汎用化して提供した例です。
こうした取り組みによって、 Crois は 「使われなくなるプラットフォーム」に陥ることを回避し、ユーザのニーズに合致した機能を継続的に提供できています。
なお、場合によっては「ストリームアラインドチーム側に要件の一部分を実装する」「プラットフォームを採用すべきでない」ことをプラットフォームチームから提案することもあります。 プラットフォームチームのミッションは事業領域の生産性を最大化することにあり、プラットフォームを使ってもらうこと自体ではないからです。
おわりに
ここまで、リクルートのデータ基盤 Crois がリクルートの大規模なデータ利活用を支える基盤としてスケールし続けることができた要因を「スケーラブルな AWS マネージドサービスの活用」「プラットフォームエンジニアリングの実践」という 2 つの観点に着目してご紹介しました。
リクルートのデータ利活用を支えるプラットフォームとして今後も継続的に価値提供を行うため、AWS Innovate での発表以降も、新たに以下のような取り組みを行っています。
- ユーザ自ら正確なコストシミュレーションが行えるツール提供
- 現状のコスト可視化と組み合わせて、セルフサービスでのコスト最適化がより容易に
- より高いカスタマイズ性を持つ実行環境の提供
- ユーザごとに多様化している要件に対応するため、AWS Batch の代わりに ECS on EC2 を直接使用した実行環境を開発中
- 個別に細かくチューニングが可能な実行環境を提供することで、コスト削減・パフォーマンス向上を目指す
最後までお読みいただき、ありがとうございました。 本記事が、皆様のプラットフォームエンジニアリングの取り組みに少しでもお役に立てれば幸いです。
-
本発表では AWS に着目していますが、Crois では GCP 上でのコンテナ実行もサポートしています。GCP 上の実行を含めると、1 日あたり 70,000 コンテナになります。 ↩︎
-
データ推進室のプラットフォームエンジニアリング事例として、Crois と密接に関連するプロダクトである Knile の取り組みについて紹介されている リクルートにおける Platform Engineering / SRE の事例共有 もご参照ください。 ↩︎
-
チームトポロジーについては、 「チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計」 等をご参照ください。 ↩︎
-
ここで言うインタフェースは Crois を操作するための API も含んでいますが、より広義にチーム間の情報のやり取りの境界を指す言葉です。 ↩︎
-
例えば Crois では、近年ユーザにおけるデータエンジニアの割合が増え、求められるサービスの抽象度もより低レベルな方向へ変化してきています。それに合わせて API や IaC ツールのような低レベルインタフェースの改善に力を入れています。 ↩︎
データエンジニア。社内横断で使われるデータ基盤 Crois の開発を担当
青木 悠
休日はバイクに乗ってお出かけ派