- 設計
可用性設計と稼働率の計算|直列・並列の計算式と停止時間の早見表
可用性設計とは、システムを「使いたいときに使える」状態に保つために、目標の稼働率を決め、それを満たす構成と復旧の段取りを決めることです。 稼働率は「動いていた時間 ÷ 動いているべき時間」で表し、直列の構成では掛け算、並列の構成では「止まる確率どうしの掛け算を1から引く」計算で求めます。
この記事では、99%〜99.999% を年・月・週・日の停止時間に直した早見表と、MTBF・MTTR から稼働率を出す式、直列・並列・k-out-of-n(n 台中 k 台稼働)の計算式をまとめます。Web・AP・DB の3層を題材に、構成ごとの稼働率を同じ Python の関数で計算して比べ、目標値から台数や MTTR を逆算する例まで載せました。
確認環境:Ubuntu 24.04、Python 3.11(標準ライブラリのみ)。掲載した数値はすべて記事中のコードで計算した出力です。構成図は Mermaid 12.1.0 で描画できることを確認しています。機器1台あたりの稼働率や MTBF は、計算の手順を示すための例の値です。
稼働率と停止時間の早見表(99%〜99.999%)
1年を365日、1か月を30日として計算した、許される停止時間の上限です。
| 稼働率 | 年(365日) | 月(30日) | 週 | 日 |
|---|---|---|---|---|
| 99% | 3.65日 | 7.20時間 | 1.68時間 | 14.40分 |
| 99.5% | 1.83日 | 3.60時間 | 50.40分 | 7.20分 |
| 99.9% | 8.76時間 | 43.20分 | 10.08分 | 1.44分 |
| 99.95% | 4.38時間 | 21.60分 | 5.04分 | 43.20秒 |
| 99.99% | 52.56分 | 4.32分 | 1.01分 | 8.64秒 |
| 99.995% | 26.28分 | 2.16分 | 30.24秒 | 4.32秒 |
| 99.999% | 5.26分 | 25.92秒 | 6.05秒 | 0.86秒 |
| 計算したいもの | 式 | 例 |
|---|---|---|
| 稼働率(時間から) | 動いていた時間 ÷ 動いているべき時間 | 719.5 ÷ 720 = 99.931% |
| 稼働率(MTBF・MTTR から) | MTBF ÷(MTBF + MTTR) | 2000 ÷ 2002 = 99.9001% |
| 直列(すべて必要) | A × B × C | 0.999 × 0.995 × 0.999 = 99.3011% |
| 並列(どれか1つでよい) | 1 -(1 - A)×(1 - B) | 1 - 0.001 × 0.001 = 99.9999% |
| n 台中 k 台以上(k-out-of-n) | i = k〜n について C(n, i) × A^i ×(1 - A)^(n - i) を合計 | 3台中2台、各 99% → 99.9702% |
| 許される停止時間 | 期間 ×(1 - 稼働率) | 8760時間 × 0.001 = 8.76時間 |
「9が1つ増えると、許される停止時間は10分の1になる」と覚えておくと、表がなくても見積もれます。99.9% は年に約8.76時間、99.99% は約52.56分、99.999% は約5.26分です。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「可用性設計と稼働率の計算|直列・並列の計算式と停止時間の早見表」
早見表を出したコード
上の表は次のコードで出しました。月を31日にしたいときや、別の稼働率を足したいときは、数値を書き換えて使えます。
# 稼働率から、年・月・週・日あたりの許容停止時間を求める
PERIODS = {"年(365日)": 365 * 24 * 3600, "月(30日)": 30 * 24 * 3600,
"週": 7 * 24 * 3600, "日": 24 * 3600}
def fmt(sec: float) -> str:
"""秒を読みやすい単位に直す"""
if sec >= 86400:
return f"{sec / 86400:.2f}日"
if sec >= 3600:
return f"{sec / 3600:.2f}時間"
if sec >= 60:
return f"{sec / 60:.2f}分"
return f"{sec:.2f}秒"
print("稼働率\t" + "\t".join(PERIODS))
for a in ["99", "99.5", "99.9", "99.95", "99.99", "99.995", "99.999"]:
down = 1 - float(a) / 100
print(f"{a}%\t" + "\t".join(fmt(p * down) for p in PERIODS.values()))
稼働率 年(365日) 月(30日) 週 日
99% 3.65日 7.20時間 1.68時間 14.40分
99.5% 1.83日 3.60時間 50.40分 7.20分
99.9% 8.76時間 43.20分 10.08分 1.44分
99.95% 4.38時間 21.60分 5.04分 43.20秒
99.99% 52.56分 4.32分 1.01分 8.64秒
99.995% 26.28分 2.16分 30.24秒 4.32秒
99.999% 5.26分 25.92秒 6.05秒 0.86秒
MTBF・MTTRから稼働率を求める
| 用語 | 意味 | 伸ばす・縮める手段の例 |
|---|---|---|
| MTBF(平均故障間隔) | 復旧してから次に止まるまでの平均時間。長いほどよい | 部品の品質、設定変更の手順化、リリース前の確認 |
| MTTR(平均復旧時間) | 止まってから復旧するまでの平均時間。短いほどよい | 監視での早い検知、自動切り替え、復旧手順書、予備機 |
| 稼働率 | MTBF ÷(MTBF + MTTR) | MTBF を伸ばすか、MTTR を縮める |
稼働率は MTBF と MTTR の比で決まります。MTBF が2倍になるのと、MTTR が半分になるのは、稼働率への効果がほぼ同じです。機器の故障間隔を倍にするのは難しくても、検知と復旧を速くして MTTR を半分にすることは設計で狙えます。
直列・並列・k-out-of-n の計算式
直列:すべてが動いて初めて使える
Web → AP → DB のように、1つでも止まると全体が使えなくなるつながりです。稼働率を掛け算するので、全体は必ずいちばん低い要素より低くなります。
並列:どれか1つが動いていれば使える
同じ役割の機器を複数並べた構成です。「全部が同時に止まる確率」を1から引きます。99% の機器を2台並べると、同時に止まる確率は 0.01 × 0.01 = 0.0001 なので、99.99% になります。
k-out-of-n:n 台のうち k 台以上が必要
「3台あるが、処理量をさばくには2台必要」という構成です。並列は「n 台中1台」、直列は「n 台中 n 台」にあたるので、k-out-of-n の式1つで直列も並列も表せます。
flowchart TB
subgraph S[直列:掛け算]
direction LR
s1[A 99.9%] --> s2[B 99.9%]
end
subgraph P[並列:止まる確率を掛けて1から引く]
direction LR
p0(( )) --> p1[A 99.9%] --> p3(( ))
p0 --> p2[B 99.9%] --> p3
end
稼働率を計算する Python の関数
以降の計算は、すべて次の avail.py の関数を使います。
# 稼働率の計算に使う関数(Python 3.8 以降。標準ライブラリのみ)
from math import comb, prod
def from_mtbf(mtbf: float, mttr: float) -> float:
"""MTBF と MTTR(同じ単位)から稼働率を求める"""
return mtbf / (mtbf + mttr)
def series(*a: float) -> float:
"""直列:すべてが動いているときだけ全体が動く"""
return prod(a)
def parallel(*a: float) -> float:
"""並列:どれか1つでも動いていれば全体が動く"""
return 1 - prod(1 - x for x in a)
def k_out_of_n(k: int, n: int, a: float) -> float:
"""同じ稼働率 a の n 台のうち、k 台以上が動いている確率"""
return sum(comb(n, i) * a**i * (1 - a) ** (n - i) for i in range(k, n + 1))
def pct(a: float) -> str:
return f"{a * 100:.4f}%"
def down_per_year(a: float) -> str:
h = (1 - a) * 365 * 24
return f"{h:.2f}時間" if h >= 1 else f"{h * 60:.2f}分"
if __name__ == "__main__":
print("== MTBF・MTTR から稼働率 ==")
for mtbf, mttr in [(1000, 1), (2000, 2), (2000, 4), (4380, 4), (8760, 4), (8760, 0.5)]:
a = from_mtbf(mtbf, mttr)
print(f"MTBF {mtbf}h, MTTR {mttr}h -> {pct(a)}(年 {down_per_year(a)})")
print("== 直列・並列の基本 ==")
print("直列 0.999 x 0.999 ->", pct(series(0.999, 0.999)))
print("並列 0.999 と 0.999 ->", pct(parallel(0.999, 0.999)))
print("並列 0.99 と 0.99 ->", pct(parallel(0.99, 0.99)))
print("2 out of 3(各 0.99) ->", pct(k_out_of_n(2, 3, 0.99)))
print("1 out of 2 は並列と同じ ->", pct(k_out_of_n(1, 2, 0.99)))
print("3 out of 3 は直列と同じ ->", pct(k_out_of_n(3, 3, 0.99)), pct(series(0.99, 0.99, 0.99)))
WEB, AP, DB = 0.999, 0.995, 0.999 # 1台あたりの稼働率(例)
print("== Web・AP・DB の3層 ==")
cases = {
"A 単一構成(各1台)": series(WEB, AP, DB),
"B Web・APだけ二重化": series(parallel(WEB, WEB), parallel(AP, AP), DB),
"C 各層を二重化": series(parallel(WEB, WEB), parallel(AP, AP), parallel(DB, DB)),
"D APを3台中2台稼働": series(parallel(WEB, WEB), k_out_of_n(2, 3, AP), parallel(DB, DB)),
"E APを3台中1台稼働": series(parallel(WEB, WEB), k_out_of_n(1, 3, AP), parallel(DB, DB)),
}
for name, a in cases.items():
print(f"{name}\t{pct(a)}\t年 {down_per_year(a)}")
実行結果です。
== MTBF・MTTR から稼働率 ==
MTBF 1000h, MTTR 1h -> 99.9001%(年 8.75時間)
MTBF 2000h, MTTR 2h -> 99.9001%(年 8.75時間)
MTBF 2000h, MTTR 4h -> 99.8004%(年 17.49時間)
MTBF 4380h, MTTR 4h -> 99.9088%(年 7.99時間)
MTBF 8760h, MTTR 4h -> 99.9544%(年 4.00時間)
MTBF 8760h, MTTR 0.5h -> 99.9943%(年 30.00分)
== 直列・並列の基本 ==
直列 0.999 x 0.999 -> 99.8001%
並列 0.999 と 0.999 -> 99.9999%
並列 0.99 と 0.99 -> 99.9900%
2 out of 3(各 0.99) -> 99.9702%
1 out of 2 は並列と同じ -> 99.9900%
3 out of 3 は直列と同じ -> 97.0299% 97.0299%
== Web・AP・DB の3層 ==
A 単一構成(各1台) 99.3011% 年 61.22時間
B Web・APだけ二重化 99.8974% 年 8.99時間
C 各層を二重化 99.9973% 年 14.19分
D APを3台中2台稼働 99.9923% 年 40.34分
E APを3台中1台稼働 99.9998% 年 1.12分
読み取れることを整理します。
| 確かめたこと | 結果 |
|---|---|
| MTBF 1000時間・MTTR 1時間と、MTBF 2000時間・MTTR 2時間 | どちらも 99.9001%。比が同じなら稼働率も同じ |
| MTBF 8760時間で、MTTR を4時間から30分に縮める | 99.9544% → 99.9943%。年の停止は4時間から30分に |
| 99.9% を2つ直列 | 99.8001%。つなぐほど下がる |
| 99% を2台並列 | 99.99%。9が2つ増える |
| 99% の3台中2台 | 99.9702%。2台並列(99.99%)より低い |
3台あっても「2台必要」なら、2台並列より稼働率は低くなります。 台数が多いことと、余裕が大きいことは別だとわかります。余裕は「止まってもよい台数」で決まります。
Web・AP・DBの3層で構成を比べる
1台あたりの稼働率を Web 99.9%、AP 99.5%、DB 99.9% と置いた例です。
flowchart LR
U([利用者]) --> W1[Web 1台<br/>99.9%] --> A1[AP 1台<br/>99.5%] --> D1[(DB 1台<br/>99.9%)]
flowchart LR
U([利用者]) --> LB{{負荷分散}}
subgraph WEB[Web層 1 out of 2]
W1[Web 1]
W2[Web 2]
end
subgraph AP[AP層 2 out of 3]
A1[AP 1]
A2[AP 2]
A3[AP 3]
end
subgraph DB[DB層 1 out of 2]
D1[(DB 主)]
D2[(DB 待機)]
end
LB --> W1 & W2
W1 & W2 --> A1 & A2 & A3
A1 & A2 & A3 --> D1
D1 -. 複製 .-> D2
| 構成 | 計算 | 稼働率 | 年間の停止時間 |
|---|---|---|---|
| A 単一構成(各1台) | 0.999 × 0.995 × 0.999 | 99.3011% | 61.22時間 |
| B Web・AP だけ二重化(DB は1台) | 並列(Web) × 並列(AP) × 0.999 | 99.8974% | 8.99時間 |
| C 各層を二重化 | 並列(Web) × 並列(AP) × 並列(DB) | 99.9973% | 14.19分 |
| D AP を3台中2台稼働(2枚目の図) | 並列(Web) × 2-out-of-3(AP) × 並列(DB) | 99.9923% | 40.34分 |
| E AP を3台中1台稼働 | 並列(Web) × 1-out-of-3(AP) × 並列(DB) | 99.9998% | 1.12分 |
この表から、設計で使える見方が3つ得られます。
- 単一構成は、いちばん低い AP(99.5%)よりさらに低い 99.3011% になる。 直列は掛け算なので、層が増えるほど下がります。
- 1台だけ残った層が全体の上限を決める。 B は Web と AP を二重化しても、DB が1台のままなので 99.9%(DB 単体)を超えません。こうした箇所を単一障害点(SPOF)と呼びます。二重化は、残っている単一の箇所から順に進めると効果が大きくなります。
- 同じ3台でも「何台必要か」で結果が変わる。 AP を3台にして2台必要(D)なら年40分、1台で足りる(E)なら年1分です。性能の見積もり(1台で何件さばけるか)と可用性の計算は、セットで行います。
目標の稼働率から逆算する
目標が先に決まっているときは、式を逆向きに使います。
# 目標の稼働率から、台数・MTTR・層ごとの目標を逆算する
from math import log, ceil
from avail import k_out_of_n
def units_needed(target: float, a: float) -> int:
"""稼働率 a の機器を並列に何台並べれば target に届くか"""
return ceil(log(1 - target) / log(1 - a) - 1e-12)
def n_for_k(target: float, k: int, a: float, limit: int = 20) -> int:
"""k 台が必要なとき、全部で何台あれば target に届くか"""
for n in range(k, limit + 1):
if k_out_of_n(k, n, a) >= target:
return n
raise ValueError("limit 台では届きません")
def mttr_allowed(target: float, mtbf: float) -> float:
"""MTBF が決まっているとき、target を満たす MTTR の上限"""
return mtbf * (1 - target) / target
def per_tier(target: float, tiers: int) -> float:
"""直列 tiers 層の全体で target にするための、1層あたりの稼働率"""
return target ** (1 / tiers)
print("== 並列に必要な台数 ==")
for a in (0.99, 0.995, 0.999):
for t in (0.999, 0.9999, 0.99999):
print(f"1台 {a*100:g}% で目標 {t*100:g}% -> {units_needed(t, a)}台")
print("== 2台分の処理能力が必要なときの台数 ==")
for t in (0.999, 0.9999, 0.99999):
n = n_for_k(t, 2, 0.995)
print(f"目標 {t*100:g}% -> {n}台({k_out_of_n(2, n, 0.995)*100:.5f}%)")
print("== 許される MTTR(MTBF 2000時間)==")
for t in (0.99, 0.999, 0.9995, 0.9999):
m = mttr_allowed(t, 2000)
print(f"目標 {t*100:g}% -> MTTR {m:.2f}時間({m*60:.0f}分)")
print("== 3層直列で全体の目標を満たす1層あたりの稼働率 ==")
for t in (0.999, 0.9995, 0.9999):
print(f"全体 {t*100:g}% -> 1層あたり {per_tier(t, 3)*100:.5f}%")
== 並列に必要な台数 ==
1台 99% で目標 99.9% -> 2台
1台 99% で目標 99.99% -> 2台
1台 99% で目標 99.999% -> 3台
1台 99.5% で目標 99.9% -> 2台
1台 99.5% で目標 99.99% -> 2台
1台 99.5% で目標 99.999% -> 3台
1台 99.9% で目標 99.9% -> 1台
1台 99.9% で目標 99.99% -> 2台
1台 99.9% で目標 99.999% -> 2台
== 2台分の処理能力が必要なときの台数 ==
目標 99.9% -> 3台(99.99253%)
目標 99.99% -> 3台(99.99253%)
目標 99.999% -> 4台(99.99995%)
== 許される MTTR(MTBF 2000時間)==
目標 99% -> MTTR 20.20時間(1212分)
目標 99.9% -> MTTR 2.00時間(120分)
目標 99.95% -> MTTR 1.00時間(60分)
目標 99.99% -> MTTR 0.20時間(12分)
== 3層直列で全体の目標を満たす1層あたりの稼働率 ==
全体 99.9% -> 1層あたり 99.96666%
全体 99.95% -> 1層あたり 99.98333%
全体 99.99% -> 1層あたり 99.99667%
| 逆算したいこと | 式 | 例の結果 |
|---|---|---|
| 並列に必要な台数 | log(1 - 目標) ÷ log(1 - 1台の稼働率) を切り上げ | 1台 99% で目標 99.999% → 3台 |
| k 台必要なときの総台数 | n を1台ずつ増やして k-out-of-n が目標を超える最小の n | 2台必要・1台 99.5%・目標 99.999% → 4台 |
| 許される MTTR | MTBF ×(1 - 目標)÷ 目標 | MTBF 2000時間・目標 99.95% → 60分 |
| 直列の1層あたりの目標 | 目標の(1 ÷ 層の数)乗 | 3層で全体 99.9% → 1層 99.96666% |
最後の行が示すとおり、全体で 99.9% を目指すなら、各層には 99.9% より高い値が必要です。3層なら1層あたり約 99.967% で、層ごとの目標を 99.9% にそろえると全体は 99.7% になります。目標を層に割り振るときは、全体の値から逆算します。
MTTR の逆算は、復旧手順の設計に直結します。MTBF 2000時間の機器で 99.95% を目指すなら、検知から復旧までを60分以内に収める必要があります。「検知5分、判断10分、切り替え15分、確認10分」のように内訳を置くと、どこを自動化すべきかが見えてきます。
切り替え時間を入れて計算する
並列の式は「片方が止まった瞬間に、もう片方が引き継ぐ」ことを前提にしています。切り替えに時間がかかる構成では、その時間も停止に数えます。MTBF 2000時間・MTTR 2時間の機器を2台並べた例で確かめます。
# 切り替え時間を入れた二重化の稼働率(1台ずつの障害と、2台同時の障害を分けて数える)
YEAR_H = 365 * 24
def duplex_with_failover(mtbf_h, mttr_h, failover_sec):
a = mtbf_h / (mtbf_h + mttr_h)
both_down_h = (1 - a) ** 2 * YEAR_H # 2台とも止まっている時間
failures = 2 * YEAR_H / (mtbf_h + mttr_h) # 年間の障害回数(2台分)
switch_h = failures * failover_sec / 3600 # 切り替え中の停止
down_h = both_down_h + switch_h
return 1 - down_h / YEAR_H, both_down_h * 60, switch_h * 60, failures
for sec in (0, 30, 60, 300):
a, both, sw, n = duplex_with_failover(2000, 2, sec)
print(f"切り替え {sec:>3}秒: 稼働率 {a*100:.5f}% 同時障害 {both:.2f}分/年 + 切り替え {sw:.2f}分/年(障害 {n:.2f}回/年)")
切り替え 0秒: 稼働率 99.99990% 同時障害 0.52分/年 + 切り替え 0.00分/年(障害 8.75回/年)
切り替え 30秒: 稼働率 99.99907% 同時障害 0.52分/年 + 切り替え 4.38分/年(障害 8.75回/年)
切り替え 60秒: 稼働率 99.99824% 同時障害 0.52分/年 + 切り替え 8.75分/年(障害 8.75回/年)
切り替え 300秒: 稼働率 99.99158% 同時障害 0.52分/年 + 切り替え 43.76分/年(障害 8.75回/年)
切り替えが60秒かかると、停止時間の大半は「2台同時の障害」ではなく「切り替え中」になります。 並列の式で 99.9999% と出ても、切り替えに5分かかる構成では 99.99% 台です。二重化を設計するときは、台数に加えて次の3点を決めます。
| 決めること | 内容 | 稼働率への影響 |
|---|---|---|
| 検知の時間 | 何秒おきに、何回続けて応答がなければ切り替えるか | 切り替え時間に加算される |
| 切り替えの方式 | 自動か、人が判断するか | 人が判断する場合は連絡と判断の時間が加わる |
| 切り替えの訓練 | 定期的に切り替えを試すか | 待機側が動かない状態に気づける |
計画停止を含める場合と含めない場合
稼働率は、分母(動いているべき時間)に何を入れるかで値が変わります。定期メンテナンスなどの計画停止の扱いを、目標を決める前にそろえておきます。
# 計画停止を含める場合と含めない場合の稼働率
def availability(total_h, planned_h, unplanned_h, include_planned):
if include_planned: # 計画停止も停止として数える
return (total_h - planned_h - unplanned_h) / total_h
service_h = total_h - planned_h # 計画停止を除いた時間を分母にする
return (service_h - unplanned_h) / service_h
MONTH = 30 * 24 # 720時間
print("計画停止\t障害停止\t含めない\t含める")
for planned, unplanned in [(0, 0.5), (2, 0.5), (4, 0.5), (4, 0), (8, 1)]:
ex = availability(MONTH, planned, unplanned, False)
inc = availability(MONTH, planned, unplanned, True)
print(f"{planned}時間\t{unplanned}時間\t{ex*100:.3f}%\t{inc*100:.3f}%")
# サービス時間が平日 9〜18 時(月 20 日)の場合
biz = 20 * 9
print("サービス時間 180時間/月 で障害 0.5時間 ->", f"{(biz - 0.5) / biz * 100:.3f}%")
print("サービス時間 720時間/月 で障害 0.5時間 ->", f"{(MONTH - 0.5) / MONTH * 100:.3f}%")
計画停止 障害停止 含めない 含める
0時間 0.5時間 99.931% 99.931%
2時間 0.5時間 99.930% 99.653%
4時間 0.5時間 99.930% 99.375%
4時間 0時間 100.000% 99.444%
8時間 1時間 99.860% 98.750%
サービス時間 180時間/月 で障害 0.5時間 -> 99.722%
サービス時間 720時間/月 で障害 0.5時間 -> 99.931%
| 月の計画停止 | 月の障害停止 | 計画停止を含めない稼働率 | 計画停止を含める稼働率 |
|---|---|---|---|
| 0時間 | 0.5時間 | 99.931% | 99.931% |
| 2時間 | 0.5時間 | 99.930% | 99.653% |
| 4時間 | 0.5時間 | 99.930% | 99.375% |
| 4時間 | 0時間 | 100.000% | 99.444% |
| 8時間 | 1時間 | 99.860% | 98.750% |
月に4時間の計画停止があると、障害が1回もなくても「含める」計算では 99.444% です。99.9%(月43.2分)を計画停止込みで目指すなら、止めずにメンテナンスできる構成(1台ずつ順番に更新するなど)が前提になります。
サービス時間の決め方でも値は変わります。同じ30分の障害でも、24時間365日が対象なら 99.931%、平日9〜18時の月180時間が対象なら 99.722% です。目標を書くときは、次の項目をセットで書きます。
| 項目 | 記入例 |
|---|---|
| サービス時間 | 24時間365日 / 平日 9:00〜18:00 |
| 計画停止の扱い | 稼働率の計算から除く(事前に通知したものに限る) |
| 計画停止の上限 | 月1回、深夜2時間まで |
| 目標稼働率 | 月間 99.9%(障害停止 43.2分以内) |
| 集計の単位 | 月ごと |
| 停止の定義 | 主要な機能(ログイン、検索、登録)のいずれかが使えない状態 |
| 計測の方法 | 外部からの監視で1分おきに確認し、連続2回の応答なしを停止とする |
計算の前提と、数字に表れにくい要因
ここまでの式は、それぞれの機器が互いに関係なく止まることを前提にしています。同じ原因で同時に止まる要因があると、計算より低くなります。
| 同時に止まる要因 | 例 | 設計での対応 |
|---|---|---|
| 共有している設備 | 同じ電源、同じラック、同じネットワーク機器 | 系統や設置場所を分ける |
| 同じ変更 | 全台に同時に入れた設定変更やリリース | 1台ずつ順番に反映し、様子を見てから広げる |
| 同じデータ | 誤った更新が待機側にも複製される | バックアップからの復元手順を別に用意する |
| 負荷の集中 | 1台が止まり、残りに負荷が集まって連鎖する | 1台減った状態で処理できる台数にする |
| 共通の依存先 | 認証、名前解決、外部のサービス | 依存先も直列の要素として計算に入れる |
計算式は、構成どうしを同じ物差しで比べるための道具です。実際の値は、運用を始めてから計測した停止時間で確かめ、計算の前提を見直していきます。
可用性設計の進め方(7つの手順)
- サービス時間と停止の定義を決める。「何が使えないと停止か」を先に決めます。
- 目標の稼働率を決める。 早見表で停止時間に直し、利用者にとって受け入れられるかを確かめます。
- 構成を直列の要素に分ける。 利用者の操作が通る経路を、入口から順に書き出します。依存する外部のサービスも入れます。
- 各要素の稼働率を置く。 提供元が示す値や、過去の停止記録から求めます。
- 全体を計算し、目標と比べる。 届かないときは、いちばん低い単一の箇所から二重化を検討します。
- 切り替え時間と MTTR を決める。 逆算した MTTR を、検知・判断・切り替え・確認に割り振ります。
- 計画停止の扱いを決め、目標の書き方をそろえる。
よくある質問
Q. 稼働率 99.9% と 99.99% は、どのくらい違いますか? A. 許される停止時間が10倍違います。99.9% は年に約8.76時間(月43.2分)、99.99% は年に約52.56分(月4.32分)です。月4分に収めるには、人の判断を待たない自動の切り替えが前提になります。
Q. 二重化すれば稼働率は必ず上がりますか? A. 式の上では上がりますが、切り替え時間と、同時に止まる要因の分だけ目減りします。記事中の例では、切り替えに5分かかると 99.9999% の計算値が 99.99% 台になりました。
Q. 直列と並列が混ざった構成はどう計算しますか?
A. 内側から順に計算します。まず各層の並列(または k-out-of-n)を1つの値にまとめ、次にそれらを直列として掛け合わせます。記事の series(parallel(...), k_out_of_n(...), parallel(...)) がその形です。
Q. MTBF がわからないときはどうしますか? A. 過去の記録があれば「動いていた時間の合計 ÷ 停止の回数」で求められます。記録がない段階では、目標の稼働率と見込める MTTR から、必要な MTBF を逆算して目安にします(MTBF = MTTR × 目標 ÷(1 - 目標))。
まとめ
- 稼働率は「動いていた時間 ÷ 動いているべき時間」。MTBF ÷(MTBF + MTTR)でも求められる。
- 9が1つ増えると停止時間は10分の1。99.9% は年8.76時間、99.99% は年52.56分、99.999% は年5.26分。
- 直列は掛け算、並列は「1 - 止まる確率の積」。k-out-of-n の式1つで両方を表せる。
- 3層の例では、単一構成 99.3011% → 各層二重化 99.9973%。1台だけ残した層が全体の上限になる。
- 「何台必要か」で結果が変わる。3台中2台必要なら 99.9923%、1台で足りるなら 99.9998%。
- 目標からの逆算で、台数・MTTR・層ごとの目標が出せる。3層で全体 99.9% なら1層あたり約 99.967%。
- 切り替え時間と計画停止の扱いを先に決める。式の値と、目標の書き方の両方に効く。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「可用性設計と稼働率の計算|直列・並列の計算式と停止時間の早見表」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。