算出磁盘何时写满并定下下单截止日
目标
在 120 天的磁盘使用量表中剥离只发生一次的阶跃,求出自然增长率,计算到阈值的剩余天数和下单截止日,然后把同样的计算做成能对任意表格运行的脚本。
为什么重要
“磁盘百分之几”这个问题,由监控画面来回答。基础设施工程师要回答的是“扩容最晚什么时候之前必须下单”,而答案来自增长速度、阈值、交付周期这三个数字。如果把迁移这样只发生一次的增长混进趋势,就会过量订购;如果忽略增长,就会缺货。本实验并排求出两个斜率(整体的和阶跃之后的),让人亲眼看到这个差别。
材料在 /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=(相对于容量,保留一位小数)。 - 把 120 天整体的最小二乘斜率以
slope_gb_per_day=(保留两位小数)写到/root/cap/02-naive.txt。 - 把比前一天增长最多的那一天及其增长量,以
step_date=、step_gb=写到/root/cap/03-step.txt。 - 把阶跃之后那天起的斜率以
slope_gb_per_day=写到/root/cap/04-organic.txt。 - 用自然增长斜率,把
days_to_threshold=、threshold_date=、days_to_full=写到/root/cap/05-runway.txt(天数向上取整)。 - 在
/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"}。
参考
- 最小二乘斜率:
Σ(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 中写三行:date=<표의 마지막 날짜>、used_gb=<그날 사용량>、used_pct=<policy.env 의 CAPACITY_GB 대비 백분율, 소수 첫째 자리>(占位符依次为表中的最后日期、当天使用量、相对于 policy.env 中 CAPACITY_GB 的百分比并保留一位小数)。
用 tail -1 看最后一行。百分比是 used ÷ capacity × 100,四舍五入到一位小数。
整个时间段的斜率
用 120 天整体求出最小二乘斜率(GB/天),以 slope_gb_per_day=<값, 소수 둘째 자리>(占位符为保留两位小数的值)写到 /root/cap/02-naive.txt。x 是从第一天起的天数。
斜率 = Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²。把日期字符串用 date.fromisoformat 转换,取与第一天的差(.days)作为 x。
找到阶跃
找出使用量比前一天增长最多的那一天,把 step_date=<그날> 和 step_gb=<그날의 증가량, 정수>(占位符依次为那一天、当天的增长量取整数)写到 /root/cap/03-step.txt。
求出相邻两行的所有差值,选出最大的。它是平时每天增长量的几十倍,很显眼。
自然增长斜率
只用阶跃发生那天的下一天起到最后一天的数据,重新求最小二乘斜率,以 slope_gb_per_day=<값, 소수 둘째 자리>(占位符为保留两位小数的值)写到 /root/cap/04-organic.txt。
把与第 3 步相同的公式只应用在 step_date 之后的行上。如果它与整体斜率相差很大,那个差值就是阶跃混进斜率的部分。
剩余天数
用自然增长斜率计算,在 /root/cap/05-runway.txt 中写三行: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 까지의 날수>(占位符分别为 threshold_date 减去 LEAD_DAYS、从最后日期到 order_by 的天数)。
LEAD_DAYS 在 policy.env 中。如果 days_left 是个位数,它就应该成为这份报告的第一句。
能对任意表格运行的预测脚本
创建 /root/cap/forecast.py。以 python3 forecast.py <csv> <용량GB> <임계%>(占位符依次为 CSV 文件、容量 GB、阈值百分比)调用时,必须在标准输出中输出一行 JSON {"step_date": "YYYY-MM-DD", "organic_slope": <숫자>, "days_to_threshold": <정수>}(占位符依次为数字、整数)。计算规则与第 4–6 步相同。评分器会把这个脚本在 holdout.csv 以及每次评分时新生成的表格上运行。
把第 4–6 步的计算封装成函数,用 sys.argv 接收文件和两个数字。输出只需一次 json.dumps。请先用 python3 forecast.py holdout.csv 1000 80 运行一下。