「チェーンの強さは、最も弱いリンクの強さによって決まる」という言葉を聞いたことはありますか?
データベースにおいては、「アプリケーションの速度は、最も遅いトランザクションによって決まる」というのがそれに相当します。
ほとんどのデータベース操作は、いくつかのサブ操作で構成されています。そのため、たった1つの操作でも遅れが生じると、アプリケーション全体が機能不全に陥る可能性があります。
多くの場合、これらの中断を予測し、リアルタイム操作のためのデータベース全体の速度を最適化するために、キャッシュデータレイヤーをスタックに統合するという選択肢があります。キャッシュは非常に便利なツールですが、データベース全体の速度とパフォーマンスを最適化するための特効薬ではありません。
では、なぜ「ミリ秒単位のレイテンシー」が重要になるのでしょうか。
たとえば、アプリケーションのしきい値が200ミリ秒だとします。一見すると、これは自動的にミリ秒以下のパフォーマンスの必要性を排除するように思えます。
しかし、これは危険な考え方です。200 msのしきい値では、「ここやあそこで数ミリ秒は重要ではない」と考えがちです。しかし、すべての操作でレイテンシーが発生すると、それらは積み重なります。
そして、ユーザーは気付くのです。それが、たとえ応答時間がそれほど重要ではないように思えるアプリケーションであったとしても。
キャッシュの活用方法
まず、キャッシュには最も頻繁に使用されるデータをメモリに保持する必要があります。確かにそれはパフォーマンスを向上させますが、そのコストはどれくらいでしょうか。
メモリ自体のコストだけでなく、必要な追加サーバー、さらには追加サーバーを管理するための追加スタッフも必要です。
キャッシュのユースケース
キャッシュがデータベースに取り付けて超音速を達成するジェットブースターのように機能しないのであれば、どのような役割を果たすのでしょうか。
キャッシュレイヤーをスタックに統合することが不可欠だと考えられるのはどのような場合でしょうか?
より一般的な用途には以下のようなものがあります。
コンテンツキャッシュ
メディアやサムネイルの基本的なコンテンツキャッシュを実装することで、ストレージへのリクエストを減らすことができます。
よく利用されるデータをキャッシュから取得することで、従来のデータアーキテクチャを乱すことなく、パフォーマンスを向上させることができます。
ユーザーセッションストア
ユーザープロファイルやウェブ履歴データは、ショッピングカート、リーダーボードでのパーソナライズ、リアルタイムのおすすめエンジンなどで利用できます。
バックエンドのデータストアへのアクセスを高速化
レガシーのメインフレーム、データウェアハウス、リレーショナルシステムは、クラウドスケールで効率的に機能するように作られていません。使用量が増えると、リクエストの膨大な量がこれらのシステムを圧倒する可能性があります。
しかし、現代の運用ユースケースに役立つデータセットが含まれている可能性があります。そこで、そのデータを抽出してキャッシュやインメモリデータベースに入れることで、バックエンドシステムに負担をかけることなく、そのデータを有効活用できるのです。
キャッシングの応答時間を可視化
キャッシングは、アプリケーションが必要とするデータがキャッシュに存在する場合にのみ有効です。キャッシュにヒットしないデータベース操作は、レイテンシーが大幅に長くなります。これがページの読み込み速度や銀行口座の更新速度を制限する要因となります。
例えば、ECストアを考えてみましょう。1つの商品ページを読み込むために、次のようなサブ操作を実行する必要があります。
- 包括的な商品説明の取得
- 商品の画像や動画の読み込み
- 顧客からのフィードバックの収集
- 関連商品の推奨
- よく一緒に購入される商品のリストの作成
- ユーザーアカウント情報の表示
- ショッピングカートの商品のまとめ
- 最近見た商品の表示
- 現在の割引オファーの紹介
これらのタスクの多くはデータベースクエリを必要とします。各サブ操作に必要なデータを提供するためにデータベースが要する時間をグラフ化すると、次のようなパターンになるでしょう。
ページの読み込み時間は、最も長いサブ操作の期間を超えてはいけません。この場合はサブ操作5がそれに当たります。パフォーマンス効率を高めるために、データベースの前にキャッシュを配置するのが一般的な方法です。この方法により、応答時間は次のように変化します。
ここで何が起きているのでしょうか?
特定の操作では、キャッシュを利用してデータを素早く取得することができ、それによって操作の期間が大幅に短縮されます。一方、他の操作では、直接データベースにアクセスする必要があり、以前と同じ高いレイテンシーを維持しています。
ページの読み込み速度全体は、最も遅いタスクによって決定されるため、キャッシュを実装しても、ページの読み込み時間全体にはわずかな影響しかありません。
キャッシュヒット率
キャッシュヒット率は、サーバーではなくキャッシュによって満たされるデータリクエストの割合を表します。
サブ操作全体でキャッシュヒット率を拡張する
次のことを考えてみてください。
キャッシュヒット率が50%(実際にはかなり良い値)で、タスクの中で2つの操作を満たすとします。両方がキャッシュに存在する可能性は、50%×50%=25%です。
ページ上に4つのタスクがある場合、その確率は約6%まで下がります。言い換えれば、データベースの前にキャッシュを配置したり、ディスクの前に大量のメモリを追加したりすることの利点は、せいぜい最小限です。
これを視点に入れると、キャッシュヒット率を75%に改善しても、4つの操作すべてがキャッシュに存在する可能性は3分の1未満です。
キャッシュサイズを大幅に維持することで99%という印象的なキャッシュヒット率を達成したとしても、5つのサブ操作を含むページの読み込みがキャッシュのみから提供される可能性は95%を超えないことを強調することが重要です(99%の5乗として計算)。
95%の効率は称賛に値しますが、ほとんどの企業は、ユーザーリクエストの99%で最適なパフォーマンスを確保することを目指しており、このようなキャッシュアプローチでは、望ましい結果と実際の結果の間に矛盾があることを強調しています。
そもそも、5つの操作しか必要としないページがどのくらいの頻度であるでしょうか?だからこそ、サブミリ秒のレイテンシーが重要なのです。必要ないと思っているアプリケーションでも、です。
一部のアプリケーションではミリ秒のレイテンシーが必要不可欠
不正防止、人工知能、カスタマー360などの高負荷なアプリケーションの中には、リアルタイムの応答がなければ規模に応じて機能しないものがあります。
ユースケース:金融サービス
PayPalの事例を見てみましょう。
同社は、1日に4,100万件の支払いを発行し、年間の取引高は3,230億ドルに上ります。取引を承認するか拒否するかを決定するのに、人間の思考の速度である500ミリ秒しかありません。
そして、その500ミリ秒の間に、意思決定の助けとなる最大40件のリファレンスをチェックする必要があるかもしれません。90%のキャッシュヒット率でも、大きな違いは生まれません。
500ミリ秒が経過すると、不正検知ソフトウェアは決定を下さなければなりません。取引が不正かどうか判断できない場合は、リスクを受け入れて取引を通すことになります。通常、これは全取引の約1.5%に相当し、年間47億ドルのリスクを生み出していました。
幸いなことに、これらの取引のほとんどは問題ありませんでした。しかし、サブミリ秒の精度を持つデータベースに切り替えたことで、その割合は1.5%から0.05%に減少し、露出リスクが30分の1に減少しました。
その結果、PayPalの不正利用率は業界平均の10分の1になっています。
ユースケース:eコマース
あるいは、年間売上高140億ドル、アクティブ顧客3,100万人、商品1,400万点、年間注文数6,100万件のオンライン家具販売会社を考えてみてください。
多くのeコマース企業と同様に、同社の死活問題は、購入履歴、閲覧カテゴリ、お気に入り商品などのデータから計算する商品のレコメンドと広告の配置にかかっています。
これらすべてのデータとサブミリ秒のレイテンシーにより、同社は関連商品の広告を表示しています。関心を示した商品のセールについてアプリ通知をユーザーに送信するなど、ユーザーの行動に基づいてアクションを自動化しています。
その結果、よりよいレコメンドが実現し、顧客のカートのサイズが6%増加し、カートの放棄率が30%減少しました。
キャッシュすべきか、否か
複雑なトランザクションや運用のユースケースでは、キャッシュが期待通りに機能しない可能性があることを理解することが重要です。上で説明したように、キャッシュサーバーに大量のメモリを搭載しても、一様に低レイテンシーの応答が得られるとは限りません。
非常に高いキャッシュヒット率(99%以上)を確保できる制御された環境では、シンプルなキャッシングレイヤーで望んだ結果が得られるかもしれません。
しかし、複雑なクエリが一般的な動的な環境では、データをリアルタイムまたはインメモリデータベースレイヤーに抽出する方が、より良くかつより予測可能な結果が得られることが経験上わかっています。
サブミリ秒のレイテンシー:組織にとってのミッションクリティカル
アプリケーションが一貫した予測可能な低レイテンシーに依存している場合、1つの異常なクエリやデータベース操作によって、データベースアプリケーション全体のパフォーマンスが低下する可能性があり、キャッシュソリューションではそのようなタイプの負荷を吸収できない可能性があります。
キャッシュには特定の機能があり、多くのユースケースで重要な問題を解決しますが、サブミリ秒のデータベースパフォーマンスを保証するものではありません。それは実際にはデータベース自体に依存します。
不正検知、AI、カスタマー360などの高負荷のユースケースで許容できるアプリケーションパフォーマンスを得るためには、サブミリ秒のレイテンシーは単にあった方が良いというだけでなく、不可欠なのです。