ワークロード分離とリソースガバナー・アドミッション制御
高負荷で全クエリが共倒れする崩壊を防げます。アドミッション制御・リソースプール・キューイングがメモリと同時実行をどう束ね、過負荷でスループットが落ちない原理を解説します。
- 1.過負荷時のスループット崩壊は、各クエリがメモリ確保前に同時入場することで起き、アドミッション制御は入場数を絞って崩壊を防ぐ機構である。
- 2.リソースプールはワークロードを分類してメモリ/CPU/同時実行の上限を割り当て、重い分析が軽い処理を巻き込む干渉を分離する。
- 3.キューイングは超過分を待たせて実行中のクエリを完走させる戦略で、待ち時間と引き換えに有効スループットを維持する。
なぜ負荷を上げると逆に遅くなるのか
同時実行数を増やすほどスループットは上がる、と期待したくなります。しかし実際のデータベースでは、ある同時実行数を超えると総処理量が増えるどころか急落します。各クエリがソートや結合のために大きな作業メモリを要求し、全員が同時に入場すると、メモリが枯渇してディスクへのスピルが多発し、誰も完走できなくなるからです。本稿は、この崩壊を防ぐアドミッション制御・リソースプール・キューイングの原理を内部から追います。
スループット崩壊のメカニズム
崩壊は「全員を入れてから足りなくなる」順序で起きます。一定量の作業メモリを使うクエリが N 本同時に走るとき、各本の取り分はメモリ総量を N で割った値に近づきます。取り分が外部ソートやハッシュ結合のしきい値を下回ると、データはディスクへスピルし(→ 集約とソートの外部アルゴリズム)、I/O が爆発します。
同時実行が臨界点を超えると、CPU はコンテキストスイッチとロック待ち、メモリはスピルの読み書きに費やされ、実際の計算が進みません。これをスラッシングと呼びます。グラフにすると、スループットは同時実行に対し山なりで、頂点を過ぎると右肩下がりになります。重要なのは、頂点の右側では「もっと入れる」ほど全員が遅くなる点です。
スループット曲線が山なりになる理由は、ユニバーサルスケーラビリティ則(USL)で整理できます。同時実行を増やすと、まず直列化(ロックやラッチの競合)が線形に効いて伸びを鈍らせ、さらにクロストーク(資源を奪い合う相互干渉、コヒーレンシ)が同時実行数の二乗で効きます。この二乗の項が、ある点で並列化の利得を食い潰し、曲線を頂点の先で右肩下がりに反転させます。アドミッション制御の狙いは、この頂点付近に入場数を固定し、頂点の右側へ踏み込ませないことに尽きます。
アドミッション制御:入場を絞る
アドミッション制御は、クエリを実行開始させる前に「いま入れてよいか」を判定するゲートです。判定軸は主に二つあります。一つはメモリ予約で、クエリの見積もりメモリ(オプティマイザの推定行数とソート/結合サイズから算出)を実行前に確保し、確保できなければ入場させません。もう一つは同時実行スロットで、同時に走れる本数の上限を設けます。
クエリ到着
→ 見積もりメモリ M を要求
→ 空きメモリ >= M かつ 実行中本数 < 上限 か?
yes: メモリ予約・スロット取得 → 実行
no : キューへ(タイムアウト付きで待機)
→ 実行終了でメモリ解放・スロット返却 → 待ち行列の先頭を起こす
要点は、メモリを実行中ずっと予約しっぱなしにすることです。途中で足りなくなって初めて気づくのでは遅く、入場時に確保できた分だけを動かすからこそ、走り出したクエリはスピルせず完走できます。見積もりが過大だと無駄に入場を絞り(メモリ遊休)、過小だと予約を超えてスピルするため、推定精度がそのままゲートの精度を決めます。
アドミッション制御には、入場時に資源を確定予約する方式(SQL Server のメモリグラント、Impala のアドミッションコントローラ等)と、走らせてから足りなければ抑制する最善努力方式があります。予約方式は完走を保証しやすい反面、見積もり誤差で資源を遊ばせます。最善努力は柔軟ですが、輻輳時に全体崩壊を招きやすく、両者は予測可能性と利用率のトレードオフにあります。
リソースプール:ワークロードを分離する
単一のゲートだけでは、重い分析クエリ1本が軽いトランザクション処理を巻き込んで遅くします。リソースプール(リソースガバナー)は、まず接続やクエリを属性(ログインユーザー、アプリ名、クエリの種類など)で分類し、プールごとに上限と保証を与えて干渉を断ち切る仕組みです。
| 設定軸 | 意味 | 効果 |
|---|---|---|
| MAX(上限) | そのプールが使える資源の天井 | 暴走ワークロードが他を食い尽くすのを防ぐ |
| MIN(保証) | 他が混んでも確保される最低量 | 重要処理の最低性能を守る |
| 重み/シェア | 競合時の比例配分の比率 | 余剰資源を優先度に応じて分配する |
| 同時実行上限 | プール内で同時に走れる本数 | プール単位でスループット頂点を管理 |
たとえば「OLTP プールに CPU 70%・メモリ上限を低めに、分析プールに CPU 上限 40%・大きなメモリグラントを許可、ただし同時実行は2本まで」と設定すれば、分析側がいくら混んでも OLTP の応答性が守られます。MIN の合計は100%を超えられない(保証は実在資源の取り分なので)一方、MAX は重ね合わせて余剰を融通できる、という非対称性が設計の勘所です。
リソースプールは資源を物理的に区切るのではなく、スケジューラが調停するための会計枠です。空いていれば MAX まで使え、混めば MIN まで譲る。これにより、隔離(最悪値の保証)と利用率(平均の最大化)を同時に追えます。CPU は時間スライスの比率、メモリはグラントの総量、I/O は帯域シェアとして、それぞれ別の調停器が比率を実現します。
キューイング:超過分を待たせて完走させる
頂点を超える要求が来たとき、選択肢は「全員入れて共倒れ」か「超過分を待たせる」かです。キューイングは後者を選びます。逆説的ですが、待たせたほうが総スループットは上がります。実行中の本数を頂点付近に保てば、走っているクエリは資源を十分に得て速く完走し、空いたスロットへ待ち行列の先頭を順に通せるからです。
これはリトルの法則で裏付けられます。系内の平均クエリ数(同時実行)は、到着率(スループット)と平均滞在時間(応答)の積です。資源を薄く分け合って全員の滞在時間が伸びるより、同時実行を絞って各本の滞在時間を短く保つほうが、結果としてより高い到着率を捌けます。キューは「捨てずに順序づけて遅延させる緩衝」として働き、バースト負荷を平滑化します。
ただしキューには上限と公平性の配慮が要ります。無制限に積めば待ち時間が発散し、実質タイムアウトの山になります。実装では、キュー長の上限、待機タイムアウト、優先度付きキュー(短いクエリや重要プールを先に)を組み合わせ、待ち行列の中でヘッドオブラインブロッキング(重い1本が後続を塞ぐ)を避けます。
アドミッション制御を入れても、到着率が処理能力を恒常的に超えれば、崩壊は「実行側」から「キュー側」へ移るだけです。キューが際限なく伸び、待機中にタイムアウトしたクエリが再投入されると、実行されない仕事の処理に資源を使う輻輳崩壊に陥ります。上限付きキュー+早期拒否(負荷制限・ロードシェディング)で、捌けない要求は早く落とすのが安全側の設計です。
三層がかみ合って崩壊を防ぐ
三つの機構は役割が分かれ、連動して初めて効きます。アドミッション制御が同時実行を頂点に固定し、リソースプールがワークロード間の干渉を分離し、キューイングが超過分を順序づけて完走を待たせます。クエリの見積もりメモリはオプティマイザの推定(→ クエリオプティマイザの内部)に依存するため、推定が外れるとゲートも外れます。並列実行のワーカー割り当ても同じ資源会計の下にあり、モーセル単位のスケジューリング(→ モーセルドリブン並列実行)はプールの CPU シェアと整合して動きます。入口の接続数を絞るコネクションプーリング(→ コネクションプーリング)は、そもそもゲートへ殺到する流量を上流で平滑化する、もう一段外側の制御です。
「同時実行を増やしたのにスループットが下がるのはなぜか」と問われたら、各クエリの作業メモリ取り分がスピルのしきい値を割り、I/O とコンテキストスイッチが爆発するスラッシングが原因、と答えます。対策として、入場数を頂点に固定するアドミッション制御(メモリグラント+同時実行スロット)、ワークロードを分けるリソースプール(MAX/MIN/重み)、超過分を待たせるキューイングの三層を、予測可能性と利用率のトレードオフとして説明できると的確です。
まとめ
スループット崩壊は「全員を入れてから資源が足りなくなる」順序で起き、頂点を超えた同時実行はスラッシングを招きます。アドミッション制御は実行前にメモリと同時実行スロットを予約して入場数を頂点に固定し、走り出したクエリの完走を保証します。リソースプールはワークロードを分類して MAX/MIN/重みで会計し、重い分析が軽い処理を巻き込む干渉を分離します。キューイングは超過分を捨てずに順序づけて待たせ、リトルの法則どおり同時実行を絞ることで有効スループットを維持します。三層はいずれも予測可能性(最悪値の保証)と利用率(平均の最大化)のトレードオフ調整であり、見積もり精度と上限付きキューの設計が安定の鍵になります。
データベース Article
ワークロード分離とリソースガバナー・アドミッション制御を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
リソースガバナー
比較で見る軸
難易度: advanced / カテゴリ: データベース / タグ数: 5
導入後に効く点
リソースプールはワークロードを分類してメモリ/CPU/同時実行の上限を割り当て、重い分析が軽い処理を巻き込む干渉を分離する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- データベース
- タグ数
- 5
判断チェックリスト
- 自社の用途が「リソースガバナー / アドミッション制御」に近いか確認する。
- 強みである「過負荷時のスループット崩壊は、各クエリがメモリ確保前に同時入場することで起き、アドミッション制御は入場数を絞って崩壊を防ぐ機構である。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。