大規模なリアルタイム不正スコアリング
tracio.aiがストリーム処理、事前計算済みシグナルベクトル、エッジキャッシュを用いて、毎秒5万イベントを50ms未満のスコアリングで処理する方法。
大規模な不正スコアリングは、バッチ処理とは根本的に異なるアーキテクチャを必要とします。決済が承認される、あるいはアカウントが作成されるその瞬間、リスクスコアを届けるための時間は数分ではなく数ミリ秒しかありません。tracio.aiでは、中央値22msのスコアリングレイテンシで毎秒5万件超のイベントを処理しています。本記事では、これを可能にするアーキテクチャを説明します。
スコアリングパイプライン
すべての受信イベントは、シグナルエンリッチメント、ベクトル計算、リスクスコアリングという3段階のパイプラインに入ります。シグナルエンリッチメントは、デバイスインテリジェンスのデータ、すなわち訪問者のフィンガープリント、ボット検知の結果、IPインテリジェンス、過去の挙動を、生のイベントに付与します。ベクトル計算は、これらのエンリッチ済みシグナルを、当社のスコアリングモデル向けに最適化された固定長の特徴ベクトルへ変換します。リスクスコアリングは、そのベクトルを学習済みモデルに通し、0.0から1.0までのスコアを返します。
鍵となる設計上の決定は、エンリッチメントとベクトル計算をスコアリングから分離していることです。エンリッチメントのデータは事前計算されキャッシュされます。訪問者がページを読み込むと、当社はそのデバイスプロファイルを計算し、TTL 60分でRedisに保存します。スコアリング要求が到着すると(通常は決済やログインによってトリガーされます)、再計算する代わりに事前計算済みのプロファイルを取得します。これにより、スコアリングレイテンシは200ms超から30ms未満へ削減されます。
Goによるストリーム処理
当社の取り込み層はGoで書かれており、ファンアウトアーキテクチャを用いています。受信イベントはHTTP POSTで到着し、ただちに内部チャネルに載せられます。ワーカーgoroutineのプールがこのチャネルから読み取り、エンリッチメントを行い、エンリッチ済みイベントを分析用のClickHouseとリアルタイム処理用のスコアリングキューへ書き込みます。ファンアウトプールは、キューの深さに応じて動的にスケールします。
取り込み層にGoを選んだのは、その優れた並行性プリミティブと予測可能なメモリ割り当てのためです。各ワーカーgoroutineは約4KBのスタック領域を消費するため、単一ノードで数千の並行ワーカーを実行できます。ガベージコレクタのサブミリ秒の停止は、高いスループット下で一貫したレイテンシを維持するうえで不可欠です。
エッジキャッシュとシグナルベクトル
最も取扱量の多い顧客向けには、事前計算済みシグナルベクトルのキャッシュを用いてエッジでスコアリングモデルをデプロイします。デバイスが初めて確認されると、当社はその完全なシグナルベクトルを計算し、(Cloudflare Workers KV上にデプロイされた)エッジキャッシュに保存します。同じデバイスに対する以後のスコアリング要求は、キャッシュ済みのベクトルを取得し、エッジでローカルにスコアリングを実行して、10ms未満のレイテンシを達成します。
エッジのスコアリングモデルは、当社の完全なモデルを蒸留したものです。より小さく高速でありながら、同じ精度目標に最適化されています。当社はエッジモデルを毎週再学習し、キャッシュ無効化の嵐を避けるためにローリングデプロイで更新を配信します。エッジモデルの信頼度が設定可能なしきい値を下回る場合には、完全なモデルがサーバー側で実行されます。
分析用のClickHouse
すべてのエンリッチ済みイベントは、当社のカラム型分析データベースであるClickHouseに保存されます。ClickHouseの圧縮とクエリ性能により、リアルタイムの分析クエリをサポートしながら、数十億のイベントを保存できます。顧客はこれらの分析を用いて、不正のパターンを理解し、スコアリングのしきい値を調整し、個々のイベントを調査します。
当社はClickHouseのマテリアライズドビューを用いて、事前集計されたメトリクス、すなわち国別の不正率、デバイスタイプ別のスコアリング分布、しきい値別の誤検知率を維持しています。これらのマテリアライズドビューはイベントの到着に合わせてリアルタイムに更新され、高コストな集計クエリなしにダッシュボード表示に適したメトリクスを提供します。
得られた教訓
リアルタイムスコアリングシステムの構築は、いくつかの教訓を与えてくれました。第一に、事前計算が最も重要な最適化です。スコアリング要求が到着する前に行える作業はすべて、レイテンシ予算に計上されない作業です。第二に、Goの並行性モデルは高スループットのイベント処理に適していますが、GC圧を避けるためにメモリ割り当てには規律が必要です。第三に、エッジデプロイはレイテンシにとって変革的ですが、古くなった予測を避けるために慎重なモデル管理を要します。