LESSON 40分

ストーリー

佐藤CTO
SLI/SLOの設計は内部の話だ。次は外部との契約 — SLAについて学ぼう
あなた
SLAはSLOと何が違うのですか?
佐藤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マルチAZ99.99%< 99.99%: 10%クレジット、< 99.0%: 30%
AWS S3Standard99.9%< 99.9%: 10%、< 99.0%: 25%
Google CloudCompute99.99%< 99.99%: 10%〜50%段階的
AzureVMs99.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 SLOSLAは顧客との契約(SLOより保守的に設定)
財務的影響SLA違反は金銭的ペナルティ(サービスクレジット)を伴う
依存関係自社SLAは依存サービスのSLAの複合値に制約される
交渉のポイント除外条件、計測方法、ペナルティ構造を明確に合意する
ダッシュボードSLA状況をリアルタイムで可視化し、違反を予測する

チェックリスト

  • SLOとSLAの違いとバッファ設計を理解した
  • SLAクレジット(ペナルティ)構造を設計できる
  • 依存サービスのSLAの複合計算ができる
  • SLA交渉の主要なポイントを把握した
  • SLAトラッキングのPromQLクエリを理解した

次のステップへ

次は「計測とダッシュボード」を学びます。Prometheusのメトリクス収集とGrafanaダッシュボードの構築により、SLI/SLO/SLAを可視化する方法を深掘りしましょう。


推定読了時間: 40分