本ブログは 「Retiring inspected count limits: technical explainer」の抄訳となります。

これまで数年間、New Relic のユーザー体験は、クエリのコストを計算するための内部的な測定単位である検査カウント(IC)に関連付けられてきました。ユーザーによる NRQL クエリの実行や、UI 読み込み時のアクションは、データを返すために New Relic データベース(NRDB)内の一定数のデータポイントを検査します。2017年に、15分間ごとの検査カウント数に一定の上限を設ける、IC 制限を導入した経緯があります。

先日、New Relic のすべての顧客に対して、これらの制限を削除したことを発表しました。これによって、IC 制限によりクエリが削除されたり、制限がリセットされるまでの待機時間を考慮する必要はなくなりました。また、今後は新しい上限に達した場合でも、クエリが拒否されることはなくなります。同時に、1つのクエリで検査可能なデータポイント数の上限も大きく引き上げられています。

このようなアップデートを実現できた背景として、過去数年間で NRDB の内部にどのような変化があったのかを簡単にご紹介いたします。

変わらないもの

変更点に触れる前に、一貫して変わっていない NRDB の重要な性質について説明します。

1 つ目は、通常の NRDB クエリと、極端に大規模なクエリの間には大きな違いがあるということです。通常のクエリ(中央値)は最大数百万のデータポイントを参照し、実行にかかる時間は概ね 100 ミリ秒未満です。一方、99.99 パーセンタイルにあたる大規模なクエリでは、数百億ものデータポイントを参照し、実行には数十秒かかります。このような極端な外れ値について考えても仕方ないと思われるかもしれませんが、NRDB は大規模なマルチテナントシステムですので、実際にそのようなクエリが 10,000 件に 1 件の割合で絶えず発生しています。

また、もう 1 つの変更されていない点として、ディスクにデータを保存する方法も、本トピックの文脈において重要な側面です。顧客から受け取ったデータは、アーカイブファイルと呼ばれるファイルに書き込まれます。1 つのアーカイブファイルには、1 人の顧客の 1 種類のデータが保存され、ファイルサイズとそれに含まれるデータの時間範囲の両方に制約があります。クエリが実行されると、基本的にはアーカイブファイルが最小の作業単位となります。異なるアーカイブ ファイルを異なるノードに分散して並列にクエリできますが、1 つのアーカイブ ファイルは 1 つのノードで完全に処理される必要があります。

2017年のNRDB

2017 年、NRDB は大量のハードウェアと比較的静的な設定による、従来のデータセンターアーキテクチャーを採用しました。当社の「クエリワーカー」コンピューティングノードは、数千におよぶ Java プロセスを、単一の大規模な共有クラスタに結合し、極めて標準的な一貫性のあるハッシュリングを編成しました。

このアプローチは概念的にも操作的にも比較的簡単で、経済性にも優れていました。通常のクエリではクラスタのリソースのほんの一部しか必要としませんでしたが、時折発生する大規模なクエリではより大きなリソースプールを利用する可能性があり、そのような場合にはテナントごとに厳密に CPU を割り当てる構成と比較すると、はるかに高速に実行できたのです。

これは 1 回限りの大規模なクエリにはうまく機能しますが、テナント間の公平性という重大な問題が発生する可能性がありました。通常、1 人のユーザーが非常に大規模なクエリを 1 つ実行した程度であれば、他のユーザーに目立った影響はありません。しかしガードレールが設けられていない場合、そのようなクエリが同時に多数実行すると、他のユーザーに大きな影響を及ぼす可能性が出てきます。これを考慮して、先述の検査カウント上限を導入しました。IC 制限により、他のユーザーのエクスペリエンスの低下を引き起こしているテナントを特定し、(クエリの一部を拒否することで)クエリ速度を少し遅くして、公平なリソース使用率を確保しました。

2024年のNRDB

この間に、多くのことが変わりました。最も根本的な変化は、NRDB をパブリッククラウドとセルベースのアーキテクチャに移行したことです。1 つの大規模な共有クラスタではなく、ワークロードを迅速かつ動的に再分散できる機能を備えた、数十の独立したクラスタでクエリ処理を実行するようになりました。この新しいアーキテクチャと連動できるように、ほぼリアルタイムのフィードバック機構も実装し、個々のユーザーのクエリ実行状況を把握できるようになりました。

その結果、単一テナントが他のユーザーのコンピューティングリソースを枯渇させるようなことは起こらなくなりました。1 人のユーザーの使用量が異常に急増し、1 つのクラスタが飽和する可能性が生じたとしても、それを検出し、他のユーザーのワークロードを他のクラスタにルーティングすることで、パフォーマンスを低下させることなく実行を継続できます。その間も、最初のユーザーの大規模なクエリは実行され続けますが、割り当てられたキャパシティの上限を超えている場合は、通常よりも少し遅くなる可能性があります。

こうした改善により、2 つの洞察が得られました。1 つ目は、クエリの可用性とパフォーマンスのサービスレベル目標 (SLO) が 2 桁改善されたことです。もう 1 つは、既存の IC 制限が発動したタイミングが、システム全体の健全性と相関関係を持たなくなったということです。言い換えれば、どのユーザーにも IC 制限を課すことなく、より優れたエクスペリエンスを提供できるようになったということです。

NRDB クエリに一切の制限がなくなったことを意味しますか?と問われれば、厳密にはそうではありません。ただし、現時点の制限は従来よりもはるかに焦点が絞られ、微妙な影響度合い、かつ応答性が高いものになっているため、ほとんどのユーザーはそれに気付かないことが想定されます。