ストーリー
佐
佐藤CTO
SLI/SLOの設計は内部の話だ。次は外部との契約 — SLAについて学ぼう
佐
佐藤CTO
SLOは内部目標で、SLAは顧客との契約だ。SLAを破るとお金が動く。だからSLAはSLOよりも保守的に設定する。SLOが社内のバッファで、SLAが顧客との約束ということだ
SLA vs SLO
比較
| 観点 | SLO(内部目標) | SLA(外部契約) |
|---|
| 対象 | エンジニアリングチーム | 顧客・ビジネスパートナー |
| 目的 | サービス品質の内部基準 | ビジネス上の品質保証 |
| 目標レベル | SLAより高い | SLOより低い(バッファ) |
| 違反時の影響 | エラーバジェットポリシー発動 | 金銭的補償・契約違反 |
| 変更の容易さ | 四半期レビューで変更可能 | 契約改定が必要 |
| 典型的な関係 | SLO: 99.95% | SLA: 99.9% |
SLOとSLAのバッファ設計
SLA SLO 現在の実績
│ │ │
──────────────────┼────────┼─────────┼──→ 可用性
99.9% 99.95% 99.97%
◄──────────────────┤
SLA違反 │
(ペナルティ発生) │
│
├────────┤
│ バッファ │
│ (SLO-SLA)│
│ = 0.05% │
└────────┘
SLAの財務的影響
SLAクレジット(ペナルティ)構造
interface SlaCredit {
uptimeRange: { min: number; max: number };
creditPercentage: number;
description: string;
}
const slaCreditStructure: SlaCredit[] = [
{
uptimeRange: { min: 99.9, max: 100 },
creditPercentage: 0,
description: 'SLA内 - ペナルティなし',
},
{
uptimeRange: { min: 99.0, max: 99.9 },
creditPercentage: 10,
description: '月額の10%をサービスクレジットとして付与',
},
{
uptimeRange: { min: 95.0, max: 99.0 },
creditPercentage: 25,
description: '月額の25%をサービスクレジットとして付与',
},
{
uptimeRange: { min: 0, max: 95.0 },
creditPercentage: 50,
description: '月額の50%をサービスクレジットとして付与',
},
];
function calculateSlaPenalty(
monthlyRevenue: number,
actualUptime: number,
credits: SlaCredit[]
): {
creditPercentage: number;
penaltyAmount: number;
slaStatus: string;
} {
const credit = credits.find(
c => actualUptime >= c.uptimeRange.min && actualUptime < c.uptimeRange.max
);
if (!credit) {
return { creditPercentage: 0, penaltyAmount: 0, slaStatus: 'Unknown' };
}
return {
creditPercentage: credit.creditPercentage,
penaltyAmount: monthlyRevenue * (credit.creditPercentage / 100),
slaStatus: credit.description,
};
}
// 例: 月額1,000万円のサービス、可用性99.5%
const penalty = calculateSlaPenalty(10_000_000, 99.5, slaCreditStructure);
// creditPercentage: 10%
// penaltyAmount: 1,000,000円
// slaStatus: "月額の10%をサービスクレジットとして付与"
主要クラウドプロバイダのSLA構造
| プロバイダ | サービス | SLA | ペナルティ(SLA未達時) |
|---|
| AWS EC2 | マルチAZ | 99.99% | < 99.99%: 10%クレジット、< 99.0%: 30% |
| AWS S3 | Standard | 99.9% | < 99.9%: 10%、< 99.0%: 25% |
| Google Cloud | Compute | 99.99% | < 99.99%: 10%〜50%段階的 |
| Azure | VMs | 99.99% | < 99.99%: 10%、< 99%: 25%、< 95%: 100% |
SLA交渉のテクニック
SLA設計のフレームワーク
sla_design_framework:
step_1_define_scope:
description: "SLAの対象範囲を明確にする"
considerations:
- 対象サービスの範囲
- 除外条件(メンテナンスウィンドウ、不可抗力)
- 計測方法と責任
step_2_set_targets:
description: "目標値を設定する"
guidelines:
- SLOよりも保守的に設定(バッファを持つ)
- 依存サービスのSLAを考慮
- コスト対効果を検証
example:
internal_slo: "99.95%"
external_sla: "99.9%"
buffer: "0.05% = 月間約21分"
step_3_define_penalties:
description: "ペナルティ構造を設計する"
principles:
- 段階的なクレジット構造
- 上限額の設定(通常、月額の100%以下)
- クレジットの有効期間
step_4_establish_process:
description: "SLA管理プロセスを確立する"
elements:
- SLA違反の検知と報告
- クレジット申請プロセス
- 定期的なSLAレビュー
依存サービスのSLAの複合計算
// 自社SLAは依存サービスのSLAに制約される
interface DependencyChain {
name: string;
sla: number; // 0-1の範囲
redundant: boolean;
redundancyCount?: number;
}
function calculateCompositeSla(
dependencies: DependencyChain[]
): {
compositeSla: number;
weakestLink: string;
recommendation: string;
} {
let compositeSla = 1;
let weakestLink = '';
let weakestSla = 1;
for (const dep of dependencies) {
let effectiveSla: number;
if (dep.redundant && dep.redundancyCount) {
// 冗長構成: 1 - (1 - SLA)^n
effectiveSla = 1 - Math.pow(1 - dep.sla, dep.redundancyCount);
} else {
effectiveSla = dep.sla;
}
compositeSla *= effectiveSla;
if (effectiveSla < weakestSla) {
weakestSla = effectiveSla;
weakestLink = dep.name;
}
}
const maxSla = Math.floor(compositeSla * 10000) / 10000;
return {
compositeSla: maxSla,
weakestLink,
recommendation: `自社SLAは ${(maxSla * 100).toFixed(2)}% 以下に設定すべき(最弱リンク: ${weakestLink})`,
};
}
// 例: ECプラットフォームの依存関係
const dependencies: DependencyChain[] = [
{ name: 'AWS ALB', sla: 0.9999, redundant: false },
{ name: 'AWS RDS', sla: 0.9995, redundant: true, redundancyCount: 2 },
{ name: '決済API', sla: 0.9999, redundant: false },
{ name: 'AWS ElastiCache', sla: 0.9995, redundant: true, redundancyCount: 3 },
];
const result = calculateCompositeSla(dependencies);
// compositeSla: 0.9997 (99.97%)
// recommendation: "自社SLAは99.97%以下に設定すべき"
SLA交渉でのよくある落とし穴
| 落とし穴 | 問題 | 対策 |
|---|
| 依存サービスの考慮漏れ | 依存先がダウンしてもSLA違反になる | 依存SLAの複合計算を実施 |
| 除外条件が曖昧 | 何がSLAの範囲か争いになる | メンテナンスウィンドウ、不可抗力を明記 |
| 計測方法の不一致 | 顧客とプロバイダで数値が異なる | 計測方法を合意して明記 |
| ペナルティ上限なし | 想定外の大規模障害で巨額のペナルティ | クレジット上限を設定 |
| SLAの一方的な変更 | 顧客の信頼を失う | 変更プロセスと事前通知を規定 |
SLA管理のダッシュボード
SLAトラッキング
# SLA可用性のリアルタイムトラッキング
# 30日ローリングウィンドウでの可用性
# 現在の可用性
- record: sla:availability:30d
expr: |
sum(rate(http_requests_total{status!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))
# SLAまでの余裕(分単位)
- record: sla:remaining_budget_minutes
expr: |
(sla:availability:30d - 0.999) * 30 * 24 * 60
# SLA違反予測(現在のバーンレートが続いた場合)
- record: sla:predicted_violation_days
expr: |
sla:remaining_budget_minutes / (slo:error_ratio:1h * 60 * 24)
まとめ
| ポイント | 内容 |
|---|
| SLA vs SLO | SLAは顧客との契約(SLOより保守的に設定) |
| 財務的影響 | SLA違反は金銭的ペナルティ(サービスクレジット)を伴う |
| 依存関係 | 自社SLAは依存サービスのSLAの複合値に制約される |
| 交渉のポイント | 除外条件、計測方法、ペナルティ構造を明確に合意する |
| ダッシュボード | SLA状況をリアルタイムで可視化し、違反を予測する |
チェックリスト
次のステップへ
次は「計測とダッシュボード」を学びます。Prometheusのメトリクス収集とGrafanaダッシュボードの構築により、SLI/SLO/SLAを可視化する方法を深掘りしましょう。
推定読了時間: 40分