リアルタイム不正分析パイプラインの構築
アーキテクチャの解説:毎秒5万件のイベントを取り込み、smart signalsで拡充し、当社のストリーミングエンジンで10ms未満にリスクをスコアリングする方法。
毎秒5万件のフィンガープリントイベントを処理し、それぞれをsmart signalsで拡充し、10ミリ秒未満にリスクスコアを返すには、入念に設計されたストリーミングアーキテクチャが必要です。本稿では、取り込みから判断まで当社のパイプラインを順に解説します。
取り込み層
イベントは、訪問者のブラウザで動作する当社のJavaScriptエージェントからのHTTPS POSTリクエストとして到着します。各イベントには暗号化されたシグナルのペイロード——通常は8〜12KBの圧縮データで、130+のブラウザシグナルを網羅——が含まれます。当社のエッジサーバーはTLSを終端し、リクエスト署名を検証し、ペイロードを処理パイプラインに転送します。
当社は、エッジサーバーを顧客のCDNノードと同じ場所に配置するマルチリージョンのデプロイを採用しています。これにより、世界中のリクエストの95%でネットワークのラウンドトリップが20ms未満に保たれます。エッジサーバーはロードバランサーの背後で動作するステートレスなGoサービスで、リクエスト量に応じて水平にスケールします。
シグナル抽出
最初の処理ステージは、シグナルのペイロードを復号し解析します。各シグナルは抽出され、検証され、型付けされます。canvasのハッシュは既知の不可能な値(canvasのブロックや偽装を示す)と照合されます。WebGLのパラメータは整合性のために相互検証されます。Navigatorのプロパティは既知の有効な組み合わせと照合されます。
このステージはシグナルの正規化も行います。ユーザーエージェント文字列は構造化された構成要素(ブラウザ、バージョン、OS、デバイス)に解析されます。画面の寸法はDPIスケーリングを考慮して正規化されます。タイムゾーンのオフセットはIPの位置情報データと照合して検証されます。
Smart Signalsによる拡充
抽出されたシグナルは、当社のサーバーサイドのインテリジェンス層であるSmart Signals分析で拡充されます。これには、シークレット検出(シグナルパターンを既知のプライベートブラウジングのシグネチャと比較)、VPN検出(IPデータをタイムゾーンやロケールのシグナルと相互参照)、ブラウザ改ざん検出(シグナル偽装を示す不整合を特定)、仮想マシン検出(VMware、VirtualBox、クラウドVMに関連するハードウェアプロファイルを認識)が含まれます。
各smart signalは独立に計算され、真偽値の結果と信頼度スコアの両方を生成します。拡充ステージは各イベントに24の追加シグナルを加え、クライアント側の収集だけでは達成できない包括的な脅威評価を提供します。
リスクスコアリングエンジン
拡充されたイベントは、当社のリスクスコアリングエンジン——数百万件のラベル付きイベントで訓練された勾配ブースティング決定木モデル——に渡されます。モデルは130+のすべての生シグナル、24のsmart signals、そしていくつかの派生特徴量を考慮します。すなわち、速度メトリクス(このデバイスからのイベントが直近5分、1時間、24時間で何件あったか)、過去の行動パターン、ネットワークレピュテーションのスコアです。
モデルは0〜100のリスクスコアを、主要な寄与要因とともに出力します。たとえばスコア85には、「VPN検出」「シークレットモード」「高速度——5分で47件」といった要因が添えられるかもしれません。この説明可能性は、特定のイベントがなぜフラグされたのかを理解する必要のある不正アナリストにとって決定的に重要です。
保存とクエリ層
すべてのイベントはClickHouse——大規模データセットに対する分析クエリに最適化されたカラム型データベース——に永続化されます。ClickHouseは当社の書き込み量(毎秒5万件)を難なくさばき、そのカラム型ストレージは数十億行に対するサブ秒の分析クエリを可能にします。
当社は多層の保存戦略を用います。ホットデータ(直近7日)はサブ100msのクエリ応答のためにNVMe SSDに保存されます。ウォームデータ(7〜90日)は標準SSDにあります。コールドデータ(90日以上)は圧縮されオブジェクトストレージに移され、クエリ可能ですがレイテンシは高くなります。
バックボーンとしてのKafka
Apache Kafkaがパイプラインを結び付けます。すべてのステージがKafkaのトピックから読み、そこへ書きます。取り込み層は生イベントを書きます。シグナル抽出ステージは生イベントを読み、抽出済みイベントを書きます。Smart Signalsの拡充ステージは抽出済みイベントを読み、拡充済みイベントを書きます。リスクスコアリングエンジンは拡充済みイベントを読み、スコア付きイベントを書きます。
このアーキテクチャはいくつかの利点をもたらします。各ステージは独立にスケールでき、あるステージの障害が他に影響せず、デバッグや再処理のためにどのステージにもイベントを再生できます。Kafkaのコンシューマーグループは各ステージ内での並列処理を可能にし、その厳密に一度だけの(exactly-once)セマンティクスは、いかなるイベントも二度処理されたり失われたりしないことを保証します。
レイテンシバジェット
当社のエンドツーエンドのレイテンシ目標は、拡充されたシグナルのペイロードが処理パイプラインに到着した瞬間から、リスクスコアが返される瞬間までで10msです。バジェットの内訳は次のとおりです。シグナル抽出が1〜2ms、Smart Signalsの拡充が3〜4ms、リスクスコアリングが2〜3ms、シリアライズと応答が1〜2ms。ステージ間のKafkaのホップは、同じ場所に配置した当社のデプロイでは1ms未満を加えます。
このバジェットを毎秒5万件で一貫して満たすには、あらゆるステージでの入念な最適化が必要です。当社は事前割り当てのメモリプール、ゼロコピーのシリアライズ、バッチ化したClickHouseの書き込みを用います。リスクスコアリングモデルはONNX Runtimeを使ってネイティブコードにコンパイルされ、Pythonインタープリタのオーバーヘッドを排除します。
Markは、当社の分散ルックアップ層にボトルネックを見つけるまで2週間パイプラインをプロファイリングしました——単一のミューテックスが、すべてのゴルーチンにわたるルックアップを直列化していたのです。シャード化したロック設計に切り替えた後、p99は48msから9msに低下しました。見つけてしまえば、修正は拍子抜けするほど単純なこともあるのです。