1. 稼働率(Availability)とは

稼働率 \(A\) は、システムがある時間範囲のうち「正常に動いている時間の割合」を表す指標です。0 と 1 の間(または 0% と 100% の間)の値を取り、1 に近いほど可用性が高いことを意味します。

\[ A \;=\; \dfrac{\text{稼働時間}}{\text{稼働時間} + \text{停止時間}} \]

可用性設計では、後述の MTBF(平均故障間隔)MTTR(平均修復時間) から \(A\) を算出し、複数の構成要素を組み合わせて システム全体の稼働率を求めます。

「ナイン」表記: \(A = 0.999\)(スリーナイン)は年間約 8.76 時間の停止、 \(A = 0.99999\)(ファイブナイン)は年間約 5.26 分の停止に相当します。

2. MTBF と MTTR、故障率 λ・修復率 μ

稼働率は、機器の故障と修復の周期から導けます。

\[ A \;=\; \dfrac{\mathrm{MTBF}}{\mathrm{MTBF} + \mathrm{MTTR}} \]

故障率 λ・修復率 μ との関係

MTBF と MTTR は、それぞれ 故障率 \(\lambda\)修復率 \(\mu\) の逆数です。

\[ \lambda \;=\; \dfrac{1}{\mathrm{MTBF}}, \qquad \mu \;=\; \dfrac{1}{\mathrm{MTTR}} \]

これらを使うと稼働率は次のように書けます。

\[ A \;=\; \dfrac{\mu}{\lambda + \mu} \]

計算例

MTBF = 1000 時間、MTTR = 10 時間 のコンポーネントの稼働率は、

\[ A \;=\; \dfrac{1000}{1000 + 10} \;=\; \dfrac{1000}{1010} \;\approx\; 0.9901 \]

3. 直列構成の稼働率

直列構成 は、構成要素のいずれか 1 つでも故障するとシステム全体が停止する構成です。Web サーバ → App サーバ → DB のような依存関係が典型例です。

A, B, C が直列に接続された信頼性ブロック図
A, B, C が直列に接続された構成

各要素が独立に故障すると仮定すると、システム稼働率は各要素の稼働率の積になります。

\[ A_\text{system} \;=\; \prod_{i=1}^{n} A_i \;=\; A_1 \cdot A_2 \cdots A_n \]
直感: 直列構成は要素を増やすほど稼働率が下がります。 0.99 を 3 つ直列にすると \(0.99^3 \approx 0.9703\) となり、 いずれか 1 つが落ちる確率が積み上がるためです。

計算例

\(A_1 = 0.99\), \(A_2 = 0.99\), \(A_3 = 0.999\) のとき:

\[ A_\text{system} \;=\; 0.99 \times 0.99 \times 0.999 \;\approx\; 0.9791 \]

4. 並列構成の稼働率(1 out of n)

並列構成 は、構成要素のうち 少なくとも 1 つ が動いていればシステムが稼働する構成です。DB の二重化、ロードバランサ配下の冗長 Web サーバなどが該当します。

A と B が並列に接続された信頼性ブロック図
A と B が並列に接続された構成

「全要素が同時に故障する確率」を求めて、それを 1 から引きます。各要素の 不稼働率 は \(1 - A_i\) です。

\[ A_\text{system} \;=\; 1 \;-\; \prod_{i=1}^{n} (1 - A_i) \]
直感: 並列化は冗長化によって稼働率を引き上げます。 稼働率 0.9 のコンポーネントを 2 つ並列にすると \(1 - (1 - 0.9)^2 = 1 - 0.01 = 0.99\) となり、 1 つだけのときの 0.9 から大きく改善します。

計算例

\(A_1 = 0.99\), \(A_2 = 0.99\) のとき:

\[ A_\text{system} \;=\; 1 - (1 - 0.99)(1 - 0.99) \;=\; 1 - 0.0001 \;=\; 0.9999 \]

5. k out of n 構成の稼働率

k out of n 構成(k-out-of-n)は、\(n\) 個のブランチのうち 少なくとも \(k\) 個 が稼働していればシステムが稼働すると判定する構成です。

A, B, C の 3 ブランチからなる 2 out of 3 構成
3 つのうち 2 つ以上が稼働で OK(バッジは k/n を示す)

同一稼働率の場合(簡単な式)

すべての要素が同じ稼働率 \(A\) を持つときは、二項分布で表せます。 ちょうど \(j\) 個稼働する確率を合計します。

\[ A_\text{system} \;=\; \sum_{j=k}^{n} \binom{n}{j} A^{j} (1 - A)^{n - j} \]

異種混合の場合(一般式)

各ブランチの稼働率が異なる場合は、 ポアソン二項分布 (Poisson binomial distribution)に従います。各ブランチが稼働 / 故障する全ての組み合わせ(部分集合)を列挙し、 稼働数が \(k\) 以上のケースの確率を足します。

\[ A_\text{system} \;=\; \sum_{\substack{S \subseteq \{1,\dots,n\} \\ |S| \ge k}} \left( \prod_{i \in S} A_i \right) \left( \prod_{i \notin S} (1 - A_i) \right) \]

この式は意味が明確ですが、部分集合の数が \(2^n\) 個あるため、\(n\) が大きくなると 指数的に計算量が増えます。例えば \(n = 30\) なら約 10 億通りを列挙することになり、現実的ではありません。

動的計画法(DP)による効率化

そこで本ツールでは 動的計画法(Dynamic Programming) を用い、 \(O(2^n)\) の問題を \(O(n^2)\) に落としています。次のように「\(i\) 番目までを見たとき、ちょうど \(j\) 個が稼働している確率」を \(p_j^{(i)}\) と定義します。

\[ p_j^{(i)} \;=\; \Pr\!\bigl(\text{ブランチ 1〜}i\text{ のうち、ちょうど } j\text{ 個が稼働}\bigr) \]

初期条件

1 個も見ていない時点 (\(i = 0\)) では、稼働 0 個の確率が 1、それ以外は 0 です。

\[ p_0^{(0)} \;=\; 1, \qquad p_j^{(0)} \;=\; 0 \quad (j \ge 1) \]

漸化式

\(i\) 番目のブランチを追加で見るとき、「\(i\) 番目が故障する場合」と 「\(i\) 番目が稼働する場合」の確率を足し合わせます。

\[ p_j^{(i)} \;=\; \underbrace{p_j^{(i-1)} \cdot (1 - A_i)}_{i\text{ 番目が故障し、前段で }j\text{ 個稼働}} \;+\; \underbrace{p_{j-1}^{(i-1)} \cdot A_i}_{i\text{ 番目が稼働し、前段で }j-1\text{ 個稼働}} \]

全ブランチを見終わった後 (\(i = n\))、稼働数が \(k\) 以上である確率を合計したものが システム稼働率です。

\[ A_\text{system} \;=\; \sum_{j=k}^{n} p_j^{(n)} \]

各 \(i\) について長さ \(n + 1\) のテーブルを 1 回更新するため、 全体の計算量は \(O(n^2)\) となり、\(2^n\) の素朴な列挙と比べて大幅に高速です。

計算例:2 out of 3

\(A_1 = A_2 = A_3 = 0.9\) のとき、ちょうど 2 個・3 個稼働の場合を足します。

\[ \begin{aligned} A_\text{system} &= \binom{3}{2}\, 0.9^{2}\, 0.1^{1} \;+\; \binom{3}{3}\, 0.9^{3} \\ &= 3 \times 0.81 \times 0.1 \;+\; 1 \times 0.729 \\ &= 0.243 \;+\; 0.729 \;=\; 0.972 \end{aligned} \]

部分集合の列挙で計算

異種混合の場合(\(A_1 = 0.9, A_2 = 0.8, A_3 = 0.7\))は、

\[ \begin{aligned} A_\text{system} &= A_1 A_2 (1 - A_3) + A_1 (1 - A_2) A_3 + (1 - A_1) A_2 A_3 + A_1 A_2 A_3 \\ &= 0.9 \times 0.8 \times 0.3 + 0.9 \times 0.2 \times 0.7 + 0.1 \times 0.8 \times 0.7 + 0.9 \times 0.8 \times 0.7 \\ &= 0.216 + 0.126 + 0.056 + 0.504 \;=\; 0.902 \end{aligned} \]

同じ値を動的計画法で求める

上の漸化式に従って \(p_j^{(i)}\) のテーブルを順次更新すると、 各行は次のように変化します。 色付きの行が最終結果です。

\(i\) 追加するブランチ \(A_i\) \(p_0^{(i)}\) \(p_1^{(i)}\) \(p_2^{(i)}\) \(p_3^{(i)}\)
0 —(初期状態) 1 0 0 0
1 \(A_1 = 0.9\) 0.1 0.9 0 0
2 \(A_2 = 0.8\) 0.02 0.26 0.72 0
3 \(A_3 = 0.7\) 0.006 0.092 0.398 0.504

例えば \(i = 2\) 行目の \(p_1^{(2)} = 0.26\) は、 「\(A_2\) が故障し前段で 1 個稼働 (\(0.9 \times 0.2 = 0.18\))」 と 「\(A_2\) が稼働し前段で 0 個稼働 (\(0.1 \times 0.8 = 0.08\))」 の和です。

最終行 (\(i = n = 3\)) から、稼働数 \(k = 2\) 以上の確率を合計します。

\[ A_\text{system} \;=\; p_2^{(3)} + p_3^{(3)} \;=\; 0.398 + 0.504 \;=\; 0.902 \]

上の部分集合列挙と 同じ 0.902 が得られ、 ブランチ数が増えても DP なら \(O(n^2)\) で済むことが確認できます。

6. 年間・月間ダウンタイムの算出

システム稼働率 \(A\) が決まれば、停止時間は次のように求められます。

\[ \text{年間ダウンタイム[時間]} \;=\; (1 - A) \times 8760 \]
\[ \text{月間ダウンタイム[時間]} \;=\; (1 - A) \times \dfrac{8760}{12} \;=\; (1 - A) \times 730 \]

稼働率と年間ダウンタイムの対応表

稼働率 \(A\) 俗称 年間ダウンタイム(目安)
0.99 ツーナイン 約 87 時間 36 分
0.999 スリーナイン 約 8 時間 46 分
0.9999 フォーナイン 約 52 分 34 秒
0.99999 ファイブナイン 約 5 分 15 秒
0.999999 シックスナイン 約 31 秒

7. 総合例:Web + App + DB 二重化

直列と並列を組み合わせた典型的な 3 層構成を計算してみます。

Web → App → (DB#1 と DB#2 の並列) の直列構成
Web → App → (DB#1 と DB#2 の並列) の直列構成

各要素の稼働率を以下とします。

まず DB の並列部分を計算します。

\[ A_\text{DB} \;=\; 1 - (1 - 0.99)(1 - 0.99) \;=\; 1 - 0.0001 \;=\; 0.9999 \]

次に Web → App → DB の直列として全体稼働率を求めます。

\[ A_\text{system} \;=\; A_W \cdot A_A \cdot A_\text{DB} \;=\; 0.999 \times 0.999 \times 0.9999 \;\approx\; 0.99780 \]

年間ダウンタイムは:

\[ (1 - 0.99780) \times 8760 \;\approx\; 19.27 \text{ 時間/年} \]
DB を二重化しないと? DB が 1 台だけ(\(A_\text{DB} = 0.99\))の場合、全体は \(0.999 \times 0.999 \times 0.99 \approx 0.98802\) で、 年間ダウンタイムは約 105 時間/年 に増えます。 並列化の効果が定量的に確認できます。