AWS 通过账单提取S3桶存储量大小
如何通过AWS的CUR账单1提取S3桶的存储量大小?
需求描述
通过CUR, 提取S3桶的存储量大小数据, 提取按天/按小时等间隔的打点数据, 用于后续图表制作
分析过程
对现有情况进行分析. 已知情况:
- S3存储计费说明统一的计算单位为:
CURRENCY x.y/GB/mo, 如: CNY 0.195 per GB - first 50 TB / month of storage used line_item_usage_type(行使用类型描述)中对于存储类型的描述为:REGION-TimedStorage-TYPE-ByteHrs, 如: CNN1-TimedStorage-ByteHrs
分析可知:
AWS对于S3桶的计费逻辑其实为
ByteHrs, 即字节/小时, 但是由于精度问题, 只能使用GB/mo作为计费维度以降低误差如果对于未清洗的CUR数据, 其每小时打点数据的计费单元为:
GBHrs即:CURRENCY x.y/GB/hrsgantt title S3桶计费图 dateFormat YYYY-MM-DD section Bucket 1st hour :a1, 2023-01-01, 1h 2nd hour :a2, after a1, 1h 3rd hour :a3, after a2, 1h 4th hour :a4, after a3, 1h many hours :a5, after a4, 30d last hour :a6, after a5, 1h参见上方示意甘特图, 假设一个bucket容量及使用类型不变的情况下, 聚合整月
line_item_usage_type数据为其总容量(GB), 那么每小时打点的line_item_usage_type值则表示该容量分散到了单位小时计费的容量(GB)
初步假设
每小时数据
如果需要采集每小时数据, 需要做一些转换,
将CUR计费规则与其每小时打点数据进行结合, 即\(¥/GB/mo\) ➡️ \(¥/GB/hrs\)
猜想1: 按720计算
\[ 1 mo(Month) = 720 hrs(Hours) = 24 * 30 (每天24小时, 每个月以30天计) \]
猜想2: 按730计算
\[ 1 mo(Month) = 730 hrs(Hours) = \frac {24 * 365} {12} (每天24小时, 一年以365天计, 一年12个月) \]
猜想3: 按自然小时数计算
该比率值按实际自然日*242计算? 可能性较低,
但不排除这种可能性
汇总
\[ GB / mo = \frac {1}{720} GB / hrs\ 或 \ GB / mo = \frac {1}{730} GB / hrs\ 或\ GB / mo = ? GB / hrs \]
即, 对于每小时打点的数据,
其line_item_usage_type值应扩大720/730倍或根据实际自然小时数扩大倍数,
则为该时间点的数据总量(GB)
每天数据
同样地, 如果需要采集每天数据, 将计费规则转换, 即\(¥/GB/mo\)➡️\(¥/GB/d\)
猜想1: 按30天计算
\[ 1 mo(Month) = 30 d(每个月以30天计) \]
猜想2: 按平均天数计算
\[ 1 mo(Month) = \frac {365} {12} = 30.4166666667 d(一年以365天计, 一年12个月) \]
由于计算后非整数, 极大概率本猜想为假
猜想3: 按自然日计算
该比率值按实际自然日3计算? 可能性较低,
但不排除这种可能性
汇总
\[ GB / mo = \frac {1}{30} GB / d 或GB/mo = ? GB/d \]
即, 对于每天打点的数据,
其line_item_usage_type求和值应扩大30倍或根据实际自然日扩大倍数,
则为该时间点的数据总量(GB)
以字节计算
由于存储桶大小规则不一致,
可以考虑使用Byte(字节)作为数据单位格式, 依据不同大小,
分配合适的单位, 如TB/GB/MB等,
满足: \[
1 Gigabyte(GB) = 1024 Megabyte(MB) = 1024^2 Kilobyte(KB) = 1024^3
byte(B)
\] 因此对于line_item_usage_type计算后结果,
应扩大10243倍用于计算其字节数
验证
获取验证数据, 以某一个账号, 某个仅使用标准存储的资源为例.
获取测试数据
登录CloudWatch Management Console, 进入指标页面
在
全部指标页面, 依次点击S3➡️存储指标➡️☑️测试存储桶, 指标名称应为BucketSizeBytes➕NumberOfObjects, 参考以下图示
为避免混淆, 选择单一类型存储为佳, 满足:
总文件计数🟰桶内文件数量调整时间周期, 提取指定周期内数据
可以看到, 测试通数据量一直处于稳定态, 记录该存储桶总字节数:
4,378,330,892,612使用
Athena查询并聚合2023-03-08当天数据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15SELECT SUM(line_item_usage_amount) AS "usage"
/* 依据实际情况修改库名和表名 */
FROM "athenacurcfn_daily_report"."dailyreport"
WHERE line_item_product_code = 'AmazonS3'
AND line_item_line_item_type = 'Usage'
AND line_item_operation = 'StandardStorage'
AND line_item_resource_id = '测试存储桶名称'
AND line_item_usage_start_date BETWEEN
CAST('2023-03-08 00:00:00' AS TIMESTAMP)
AND
/* AWS 对于时间最多支持到毫秒级别, 无法使用纳秒级别 */
CAST('2023-03-08 23:59:59.999' AS TIMESTAMP)
/* 这里使用纳秒级别可以将时间扩大至次日零时零分零秒 */
AND line_item_usage_end_date <= CAST('2023-03-08 23:59:59.999999' AS TIMESTAMP)
;
记录查询后结果:
131.5367225621
汇总数据
测试结果一览表
| 项目 | 值 | 备注 |
|---|---|---|
| CloudWatch监控指标-桶字节数 | 4378330892612 |
该数据平稳无波动, 即实际该存储桶容量 |
CUR账单-桶line_item_usage_amount求和结果 |
131.5367225621 |
该数据表示在2023-03-08当天该桶总计费单元 |
验证猜想
验证猜想1
按照上文猜想1对每天数据的猜测,
对于现有数据进行计算, 满足: \[
131.5367225621 GB/hrs = 131.5367225621 * 30 GB/mo = 3946.1016768630
GB/mo
\] 按照上文中的初步猜测,
对于GB➡️B的换算4,
对现有数据进行分析, 满足: \[
3946.1016768630 GB = 3946.1016768630 * 1024^3 B
= 4237094412204.3400000000 B
\] 结果误差为: \(4378330892612 -
4237094412204.3400000000 = 141236480407.6640000000\)
由于误差非常大(达到千亿级别),
因此本猜想结论为假
验证猜想2
按照上文猜想2对每天数据的猜测,
对于现有数据进行计算, 满足: \[
131.5367225621 GB/hrs = 131.5367225621 * 30.4166666667 GB/mo =
4000.9086446016 GB/mo
\] 按照上文中的初步猜测,
对于GB➡️B的换算5,
对现有数据进行分析, 满足: \[
4000.9086446016 GB = 4000.9086446016 * 1024^3 B
= 4295942945711.8800000000 B
\] 结果误差为: \(4378330892612 -
4295942945711.8800000000 = 82387946900.1177000000\)
由于误差非常大(达到百亿级别), 不过比猜想1误差有所降低,
因此本猜想结论为假
验证猜想3
按照上文猜想3对每天数据的猜测,
对于现有数据进行计算, 满足: \[
131.5367225621 GB/hrs = 131.5367225621 * 31 GB/mo = 4077.6383994251
GB/mo
\] 按照上文中的初步猜测,
对于GB➡️B的换算6,
对现有数据进行分析, 满足: \[
4077.6383994251 GB = 4077.6383994251 * 1024^3 B
= 4378330892611.1500000000 B
\] 结果误差为: \(4378330892612 -
4378330892611.1500000000 = 0.8520507813\)
误差竟然<1B!
因此本猜想结论为真
结果表
结论
按小时打点
如果需要按小时打点数据,
则需要对数据集的line_item_usage_amount列乘以当月实际自然日再乘以24计算
\[
Bucket\_Size\ (GB) = line\_item\_usage\_amount * 24 * days
\]
按天打点
如果需要按天打点数据,
则需要对数据集的line_item_usage_amount列乘以当月实际自然日计算
\[
Bucket\_Size\ (GB) = line\_item\_usage\_amount * days
\]
建议
无论何种打点规则,
建议数据存储以字节作为单位以最大限度降低误差 \[
Bucket\_Size\ (B) = Bucket\_Size\ (GB) * 1024^3
\]
如果需要严格计算, 一般来说, CloudWatch结果会比计算结果多1B,
对计算结果向下取整➕1即可 \[
Bucket\_Size\ (B) = \lfloor Bucket\_Size\ (B) \rfloor + 1
\]