容量計画と変更管理 — いつ満杯になるかを計算し、止める時刻を先に書く
ディスクがいつ満杯になるかを計算し、発注期限を決める
目標
120日分のディスク使用量の表から、1回限りの階段状の増加を取り除いてオーガニックな増加率を求め、しきい値までの残り日数と発注締切日を計算したうえで、同じ計算をどの表にも実行できるスクリプトにします。
なぜ重要なのか
「ディスクは何%か」という質問には、モニタリング画面が答えます。インフラエンジニアが答えるべきなのは「増設をいつまでに発注しなければならないか」であり、その答えは増加の速さ・しきい値・リードタイムの3つの数字から出ます。移行のような1回限りの増加をトレンドに混ぜると過剰発注に、成長を無視すると欠品になります。このラボでは、2つの傾き(全体と階段状の増加より後)を並べて求め、その差を目で確かめます。
材料は/opt/lab/capacity/forecast/にあり、採点ツールは期待値を元の材料から計算します。最後のステップのスクリプトは、採点のたびに新しく作った表にも実行して確かめます。
ステップ
/opt/lab/capacity/forecast/のdisk_usage.csv、holdout.csv、policy.envを/root/cap/へコピーしてください。/root/cap/01-now.txtにdate=、used_gb=、used_pct=(容量に対する割合、小数第1位)を書いてください。- 120日全体の最小二乗の傾きを、
/root/cap/02-naive.txtにslope_gb_per_day=(小数第2位)で書いてください。 - 前日より最も大きく増えた日とその増加量を、
/root/cap/03-step.txtにstep_date=、step_gb=で書いてください。 - 階段状の増加の翌日からの傾きを、
/root/cap/04-organic.txtにslope_gb_per_day=で書いてください。 - オーガニックな傾きを使って、
/root/cap/05-runway.txtにdays_to_threshold=、threshold_date=、days_to_full=を書いてください(日数は切り上げ)。 /root/cap/06-order.txtにorder_by=(しきい値到達日 − LEAD_DAYS)とdays_left=を書いてください。/root/cap/forecast.py <csv> <용량GB> <임계%>(プレースホルダーはCSVファイル、容量GB、しきい値%です)が、JSON{"step_date", "organic_slope", "days_to_threshold"}を1行で出力するようにしてください。
参考
- 最小二乗の傾き:
Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²。xは初日からの日数です。 - 日付:
date.fromisoformat、timedelta(days=n)。切り上げ:math.ceil。 - よくある間違い1: 階段状の増加を取り除いていない傾きで残り日数を求めてしまうことです。過度に悲観的な予測になります。
- よくある間違い2: スクリプトにこの表の日付や数字を直接書き込んでしまうことです。採点ツールが新しく作った表で失敗します。
材料のコピー
/opt/lab/capacity/forecast/のファイル一式(disk_usage.csv、holdout.csv、policy.env)を/root/cap/へコピーしてください。内容は変更しません。
cpでディレクトリの内容をコピーします。材料を変更すると、採点ツールが元のものと変わっていると知らせます。
現在の状態を書く
/root/cap/01-now.txtに3行を書いてください: date=<표의 마지막 날짜>、used_gb=<그날 사용량>、used_pct=<policy.env 의 CAPACITY_GB 대비 백분율, 소수 첫째 자리>(プレースホルダーは、表の最後の日付、その日の使用量、policy.envのCAPACITY_GBに対する百分率(小数第1位)です)。
tail -1で最後の行を確認します。百分率はused ÷ capacity × 100を小数第1位に四捨五入して求めます。
全期間の傾き
120日全体で最小二乗の傾き(GB/日)を求め、/root/cap/02-naive.txtにslope_gb_per_day=<값, 소수 둘째 자리>(プレースホルダーは値(小数第2位)です)で書いてください。xは初日からの日数です。
傾きは、Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²で求めます。日付文字列をdate.fromisoformatで変換し、初日との差(.days)をxに使います。
階段状の増加を見つける
前日より使用量が最も大きく増えた日を見つけ、/root/cap/03-step.txtにstep_date=<그날>とstep_gb=<그날의 증가량, 정수>を書いてください(プレースホルダーはその日付と、その日の増加量(整数)です)。
隣り合う2行の差をすべて求め、最大のものを選びます。普段の1日の増加量の数十倍なので目立ちます。
オーガニックな傾き
階段状の増加があった日の翌日から最終日までだけで、最小二乗の傾きを引き直し、/root/cap/04-organic.txtにslope_gb_per_day=<값, 소수 둘째 자리>(プレースホルダーは値(小数第2位)です)で書いてください。
ステップ3と同じ式を、step_dateより後の行だけに適用します。全期間の傾きと大きく違うなら、その差は階段状の増加が傾きに混ざっていた分です。
残り日数
オーガニックな傾きで計算し、/root/cap/05-runway.txtに3行を書いてください: days_to_threshold=<THRESHOLD_PCT 까지 남은 날수, 올림>、threshold_date=<마지막 날짜 + 그 날수>、days_to_full=<100% 까지 남은 날수, 올림>(プレースホルダーは、THRESHOLD_PCTまでの残り日数(切り上げ)、最終日の日付にその日数を足した日付、100%までの残り日数(切り上げ)です)。
残り日数は、切り上げ((容量 × 割合 − 現在の使用量) ÷ 傾き)で求めます。math.ceilを使い、日付はtimedelta(days=…)で足します。
発注締切日
/root/cap/06-order.txtにorder_by=<threshold_date − LEAD_DAYS>とdays_left=<마지막 날짜부터 order_by 까지의 날수>を書いてください(プレースホルダーは、最終日の日付からorder_byまでの日数です)。
LEAD_DAYSはpolicy.envにあります。days_leftが1桁なら、このレポートの最初の文にする必要があります。
どの表でも動く予測スクリプト
/root/cap/forecast.pyを作成してください。python3 forecast.py <csv> <용량GB> <임계%>(プレースホルダーは、CSVファイル、容量GB、しきい値%です)で呼び出すと、標準出力にJSONを1行、{"step_date": "YYYY-MM-DD", "organic_slope": <숫자>, "days_to_threshold": <정수>}(プレースホルダーは数値と整数です)の形で出力する必要があります。計算規則はステップ4–6と同じです。採点ツールはholdout.csvと、採点のたびに新しく作った表に、このスクリプトを実行します。
ステップ4–6の計算を関数にまとめ、sys.argvでファイルと2つの数字を受け取ります。出力はjson.dumpsを1回呼べば済みます。まずpython3 forecast.py holdout.csv 1000 80で実行してみてください。