TL

リース・ハートビートと故障検出器の理論

二重リーダーやフェイルオーバーの誤判定を防ぎたい人へ。時間境界つきリースと accrual 故障検出器の数理を押さえれば、安全な権限委譲と確率的な疑い判定を設計できます。

応用分散システム故障検出リースハートビート可用性リーダー選出最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.リースは時間境界つきのロック。リーダー権限に期限を付け、期限内は他者が奪えないと保証することで、ネットワーク分断中でも二重リーダー(スプリットブレイン)を構造的に防ぐ。
  • 2.ハートビート+固定タイムアウトの素朴な故障検出は、検出時間と誤検出率がトレードオフで二者択一になりやすい。
  • 3.accrual 故障検出器(φ)は到着間隔の分布から「どれだけ疑わしいか」を連続値で出力し、判定しきい値をアプリ側に委ねることで検出速度と精度を両立する。

なぜ「故障を検出する」のは難しいのか

分散システムで「あのノードは死んだ」と断言するのは、原理的に不可能です。完全非同期モデル——メッセージ遅延に上限がない世界——では、遅いノードと死んだノードを区別できないことが証明されています(FLP 不可能性の核にある事実)。応答が来ないのは、相手がクラッシュしたからかもしれないし、単に GC で 5 秒止まっただけかもしれない。

だから現実の故障検出器 (failure detector) は、確実な判定ではなく疑い (suspicion) を出力する確率的な装置として設計されます。狙いは2つの相反する目標のバランスです。

  • 完全性 (completeness): 本当に死んだノードは、いつかは疑われる。
  • 正確性 (accuracy): 生きているノードは、できるだけ疑われない(誤検出を減らす)。

非同期モデルでは両方を完璧には満たせないため、タイムアウトという「ある程度の同期」を仮定して妥協します。問題は、その妥協をいつ、どれだけの確信度で下すかです。

リース:時間境界つきのリーダー権限

故障検出の最も危険な失敗は、生きているリーダーを死んだと誤判定し、新リーダーを立ててしまうことです。これがスプリットブレイン(二重リーダー)を生みます。これを防ぐ道具が リース (lease) です。

リースとは、有効期限つきのロックです。リーダーは「時刻 T + L まで自分がリーダーである」という保証を取得し、その期間 L(リース長)の間は、他のノードが絶対に新リーダーになれないと約束されます。期限が切れる前にリーダーが更新 (renew) し続ければ権限は継続し、更新が途絶えれば期限切れとともに権限は自動的に失効します。

リースのライフサイクル
  grant   : リーダーが時刻 t に有効期限 t+L のリースを獲得
  renew   : t+L より前に再取得(心拍が届く限り継続)
  expire  : 更新が途絶え t+L を過ぎると自動失効
            → ここで初めて他ノードが新リースを獲得可能

リースが 分散合意(Paxos / Raft) の単なるタイムアウトより強いのは、安全性が時間境界そのものに根拠を持つ点です。新リーダーは「旧リースの期限が確実に過ぎた」と判断できるまで待ってから昇格します。期限内は旧リーダーが(たとえネットワークから孤立していても)唯一の書き込み窓口であり続けるので、二者が同時に書き込むことが起こりません。

クロックスキューがリースの命綱を握る

リースの安全性は「期限を過ぎたか」の時刻比較に依存します。ところがリーダーと検証側の物理クロックがずれていると、片方がまだ有効と思っている期限を、もう片方が過ぎたと誤認しかねません。そこで実装ではクロックスキューの上限 ε を見込み、新リーダーは旧リースの公称期限よりさらに ε(場合により安全係数も)待ってから昇格します。リース長 L はこの待ち時間と、フェイルオーバーの速さのトレードオフで決めます。L を短くすると失効が速く可用性回復は早いが、更新の往復が頻発します。

リースを使う側で見落とされがちなのが、読み取りの扱いです。リーダーが「自分はまだリーダーだ」と思って強整合な読み取りを返す場合、その読み取り時点でリースが生きていることを保証しなければなりません。多くの実装が「リースが切れる安全マージン手前まで」しか lease-based read を許さないのはこのためです。

ハートビートと素朴なタイムアウト検出

リースの更新や生存確認の土台になるのが ハートビート (heartbeat) です。各ノードが一定間隔 Δ で「生きている」信号を送り、受信側は最後に受け取ってからの経過時間を監視します。最も単純な故障検出は、固定タイムアウト T_to を置く方式です。

素朴な固定タイムアウト検出
  last_recv         : 最後に心拍を受けた時刻
  now - last_recv > T_to  → そのノードを「故障」と疑う

この方式の弱点は、T_to の選び方が検出時間と誤検出率の二者択一になることです。

T_to の設定検出の速さ誤検出 (false positive)向く環境
短い速い(すぐ疑う)多い(一時的な遅延で誤判定)遅延が安定した同一データセンター内
長い遅い(疑うまで待つ)少ない遅延が揺らぐ WAN・クラウド越し
固定値環境変化に追従しないネットワークが荒れると急増負荷が一定の限定用途

短くすれば一瞬のジッタ(GC 停止、瞬間的な輻輳)で生きたノードを殺し、長くすれば本当の故障の検出が遅れてフェイルオーバーが間に合いません。固定値である限り、この相反を同時に良くすることはできません

accrual 故障検出器:疑いを連続値で測る

この二者択一を崩すのが accrual(累積)故障検出器 です。発想の転換は、出力を「故障 / 正常」の真偽値ではなく、「どれだけ疑わしいか」の連続的な疑い度にすることです。判定のしきい値設定をアプリケーション側へ委ねるので、同じ検出器を厳しい用途にも緩い用途にも使い回せます。

代表が φ(ファイ)accrual 故障検出器 です。中核のアイデアは、過去のハートビート到着間隔の分布を測り、「今この瞬間まで次の心拍が来ていない」という事象の起こりにくさを確率で評価することにあります。

φ の定義(直感)
  P_later(t) = 「最後の心拍から t 経過した今も、まだ次が来ない」確率
  φ(t) = -log10( P_later(t) )

  φ が大きい  = その遅れは統計的に起こりにくい = 故障の可能性が高い
  しきい値 Φ を決め、 φ(t) > Φ になったら疑う

φ は対数スケールなので直感的に扱えます。**φ = 1 はおよそ「誤検出確率 10%」、φ = 2 は「1%」、φ = 3 は「0.1%」**に対応します。アプリは「誤検出を 1% 以下に抑えたい」なら Φ = 2 を、「とにかく速く疑いたい」なら Φ = 1 を選べばよく、同じ検出器でトレードオフ点だけを動かせるわけです。

到着間隔を正規分布で近似する

φ の実装(Cassandra や Akka が採用)は、直近 N 個の到着間隔の標本平均 μ と分散 σ² をスライディングウィンドウで保持し、次の心拍までの間隔が正規分布 N(μ, σ²) に従うと仮定します。最後の受信からの経過 t に対し P_later(t) を正規分布の上側確率で求め、その負の常用対数が φ です。ネットワークが荒れて間隔のばらつき σ が大きくなれば、検出器は自動的に寛容になり(同じ遅れでも φ が上がりにくい)、安定すれば敏感になります。固定タイムアウトに無い「環境への自己適応」がここから生まれます。

固定タイムアウトと accrual の違いを整理します。

観点固定タイムアウトaccrual(φ)
出力故障 / 正常の真偽値疑い度 φ(連続値)
しきい値検出器に固定で埋め込みアプリが Φ を選び後から変更可
環境適応なし(手で再調整)到着間隔の分布で自動追従
速さと精度二者択一Φ の選択で連続的に調整
代表実装多くの心拍監視Cassandra, Akka の φ 検出器

リース・心拍・検出器をどう組み合わせるか

実システムではこの3者が層をなします。ハートビートが生の信号を運び、accrual 検出器がその信号から疑い度を導きリースが疑いを安全な権限委譲へ翻訳します。

たとえばリーダーフェイルオーバーなら、心拍途絶を φ がしきい値超えとして検出し、それでもなお旧リースの期限(+クロックスキュー余裕)が過ぎるまで新リーダーは待ってから昇格します。検出器が「疑え」と言っても、リースが「まだ奪うな」と言う間は委譲を保留する——この二段構えが、検出の速さ(活性)と二重リーダー回避(安全性)を両立させます。

検出器とリースの役割分担

試験・面接では「故障検出器が誤検出したらスプリットブレインになるのか」がよく問われます。答えはノーです。誤検出は新リーダー選出の起動を早めるだけで、安全性を守るのはリースの時間境界です。検出器(活性)とリース/合意(安全性)の責務が分離されている点が要点。逆に言えば、リースを使わずタイムアウトだけでリーダーを切り替える設計は、誤検出が即スプリットブレインに直結します。

quorum を使う設計との関係も押さえておきましょう。リースの付与自体を 分散合意(Paxos / Raft)クォーラムと読み書き整合性 の上で行えば、リース台帳そのものが過半数で複製され、単一ノードのクロックや故障に依存しなくなります。レプリケーションの 同期/準同期/非同期モード を選ぶ際も、フェイルオーバー判定の速さは結局この故障検出器とリース長で決まります。

まとめ

まとめ

故障は原理的に「確実な検出」ができず、検出器は疑いを出すしかありません。ハートビートが生存信号を運び、固定タイムアウトは検出の速さと誤検出が二者択一になる弱点を抱えます。accrual 故障検出器(φ)は到着間隔の分布から疑い度を連続値で出し、しきい値 Φ をアプリに委ねて速さと精度を両立させ、ネットワークの揺らぎに自己適応します。そしてリースは時間境界つきのロックとして、誤検出があっても期限が切れるまで権限を奪わせないことで二重リーダーを防ぎます。検出器が活性を、リースが安全性を担う責務分離こそが、安全で素早いフェイルオーバーの背骨です。

データベース Article

リース・ハートビートと故障検出器の理論を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

分散システム

比較で見る軸

難易度: advanced / カテゴリ: データベース / タグ数: 6

導入後に効く点

ハートビート+固定タイムアウトの素朴な故障検出は、検出時間と誤検出率がトレードオフで二者択一になりやすい。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
データベース
タグ数
6

判断チェックリスト

  • 自社の用途が「分散システム / 故障検出」に近いか確認する。
  • 強みである「リースは時間境界つきのロック。リーダー権限に期限を付け、期限内は他者が奪えないと保証することで、ネットワーク分断中でも二重リーダー(スプリットブレイン)を構造的に防ぐ。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

分散システム故障検出リースハートビート可用性分散システム故障検出リース