亚马逊AWS官方博客
AWS CUR 深度分析 Amazon KVS 用量:三维拆解法
摘要:这篇博客介绍了用 AWS CUR 分析 Amazon KVS 用量的”三维拆解法”:将总用量分解为”设备数 × 推流时长 × 码率”,通过追踪各维度变化定位费用增长原因。文章涵盖了 KVS 计费模型、CUR 统计陷阱、Athena 查询示例,并通过实战案例展示了如何发现增长根因和针对性优化方向。
1. 背景与挑战
Amazon Kinesis Video Streams(Amazon KVS)是 AWS 提供的全托管视频流服务,广泛应用于 IoT 摄像头、智能门铃、车载监控等场景。当接入设备达到大规模时,如何从 AWS Cost and Usage Report(AWS CUR)中准确分析用量构成、定位增长原因并制定优化策略?本文介绍一套系统化的三维分析方法,并分享实践中的踩坑经验和优化建议。
适用读者:已有 KVS 规模化部署(数千台以上设备接入)、并已配置 AWS CUR 的工程师或 FinOps 团队。如果你已熟悉 KVS 计费模型,可跳过第 2 节直接从第 4 节 CUR Usage Type 开始阅读。
Amazon KVS 的按用量付费模式(pay-as-you-go)使其非常适合 IoT 场景的弹性需求。但与 Amazon EC2 实例或 Amazon S3 存储桶不同,KVS 没有一个集中的”资源清单”面板——你无法在控制台一目了然地看到”当前有多少设备在推流、每个设备推了多久、用了什么码率”。
这带来了几个实际挑战:
- 设备数难以准确统计:CUR 中的 resource_id 混合了 video stream 和 signaling channel,直接 count 会得到错误结果
- 增长原因难以定位:总费用明显增长,是设备多了?推流时间长了?还是码率变了?
- 优化缺乏数据支撑:不了解用量构成,就无法针对性地优化
AWS CUR 提供了最细粒度的计费数据(每小时、每个资源),是解决上述问题的最佳数据源。本文将展示如何利用 Amazon Athena 查询 CUR 数据,完成完整的 KVS 用量分析。
2. Amazon KVS 计费模型全解析
在分析 CUR 数据之前,需要先理解 Amazon KVS 的完整计费结构。KVS 的计费围绕两大功能模块展开:Video Stream(视频推流、存储与消费)和 WebRTC(实时双向通信)。此外,2025 年 11 月起 Video Stream 的存储新增了 Hot/Warm 分层定价,为长期留存场景提供更低成本选项。本节介绍的每个计费项,均与第 4 节 CUR Usage Type 存在一一对应关系。
2.1 Video Stream 计费
Video Stream 是 KVS 的核心功能,用于视频的推流、存储和消费。
| 计费项 | 单位 | 说明 |
| Ingest(推流) | $/GB | 设备向 KVS 推送视频数据 |
| Storage(存储) | $/GB-Month | 视频数据在 KVS 中的保留 |
| Consumption(消费) | $/GB | 通过 HLS/DASH/GetMedia 拉取视频 |
| Image Extraction | $/千张 | 从视频流中提取缩略图 |
2.2 WebRTC 计费
WebRTC 功能用于设备与观看者之间的实时双向通信(如实时查看门铃画面)。
| 计费项 | 单位 | 说明 |
| Signaling Channel | $/channel/月 | 当月如有设备或应用连接,即视为活跃并收费;未连接则不收费 |
| Signaling Messages | $/百万条 | 用于建立 P2P 连接的信令消息 |
| TURN Streaming Minutes | $/千分钟 | 无法直连时通过 TURN 服务器中继媒体 |
| Media Ingested via WebRTC | $/分钟 | 通过 WebRTC 推流至 KVS 的媒体(用于录制/存储场景) |
| Session Viewing with Multi-Viewer | $/viewer 分钟 | 多观看者会话(多人同时观看同一路流) |
2.3 Hot Tier vs Warm Tier
2025 年 11 月 26 日,Amazon KVS 新增了存储分层能力,将 Video Stream 的存储成本进一步拆分为两档:原有存储层重新命名为 Hot Tier,新增成本更低的 Warm Tier 供长期保留场景使用。详见 官方博客。
两者的核心区别:
- Hot Tier:实时消费延迟,无最小保留期,Ingest 按 GB 计费。适用于实时消费和短期存储场景。
- Warm Tier:接近实时的消费延迟,最小保留期 30 天(不足按 30 天计费),Ingest 按每 1000 fragments 计费。适用于 retention 超过 30 天且回看频率低的合规留存场景。
3. 前置条件:CUR 已接入 Athena
本文所有 SQL 均基于 Legacy CUR(Parquet 格式)在 Athena 中的表结构。Legacy CUR 字段在 Athena 中映射为下划线命名(如 line_item_usage_type,对应原始字段 lineItem/UsageType),映射规则详见 Running Amazon Athena queries。如使用 CUR 2.0 Data Exports,字段名格式可能不同,需相应调整。
尚未配置?参考以下资源:
- 创建 Legacy Cost and Usage Report(官方文档)
- Athena 集成 — 使用 CloudFormation 模板自动建表(官方文档)
- CUR Query Library(各服务 CUR 查询示例)
⚠️ 查询成本提醒:始终在 WHERE 子句中加上 year/month 分区过滤,避免全表扫描。示例:
4. CUR 中的 Usage Type 分类
配置好 Athena 接入后,先花几分钟了解 KVS 的 Usage Type 体系——这是后续所有 SQL 的核心过滤条件。以下列出经实测确认的主要 Usage Type(实际值会带区域前缀,如 USE1-BytesIn)。第 2.2 节提到的 Media Ingested via WebRTC 和 Multi-Viewer 的 Usage Type 本文未实测到,如你使用了这些功能,请通过下方 SELECT DISTINCT 查询确认其字段名。
| 类别 | Usage Type | 含义 | 计费单位 | 记录粒度 |
| Video Stream | BytesIn | 推流数据量(对应 Ingest) | GB | 每 stream 每小时 |
| BytesOut | 拉流数据量(对应 Consumption) | GB | 每 stream 每小时 | |
| BytesHr | 存储量(对应 Storage) | GB-Month | 每 stream 每小时 | |
| 图片 | LowRes-ImagesCount | 缩略图提取(对应 Image Extraction) | 千张 | 每 stream 每小时 |
| WebRTC | SignalingChannel | 信令通道月费(对应 Signaling Channel) | 个 | 每 channel 每月 |
| SignalingMessages | 信令消息(对应 Signaling Messages) | 条 | 每 channel 每小时 | |
| TURNMinutes | TURN 中继(对应 TURN Streaming) | 分钟 | 每 channel 每小时 | |
| 互联网传输 | DataTransfer-In-BytesDataTransfer-Out-Bytes | 互联网出入流量 | GB | 每资源每小时 |
| 跨区域传输 | {src}-{dst}-AWS-In-Bytes{src}-{dst}-AWS-Out-Bytes | 区域间传输 | GB | 每资源每小时 |
获取你账号中完整的 Usage Type 列表:
USE1-BytesIn(us-east-1)、 EUC1-BytesIn(eu-central-1)。后续 SQL 示例统一使用 USE1- 前缀,请替换为你实际使用的区域前缀。
5. 统计陷阱与规避方法
5.1 陷阱一:月初设备数翻倍
如果你按天统计 count(distinct line_item_resource_id) 且不过滤 usage type,会发现每月第一天的数字远高于其他天。
原因:SignalingChannel 按活跃月计费,每个 channel 当月首次被连接时在 CUR 中生成一条记录。由于大量设备在月初即触发首次连接(如开机心跳),月初当天会集中出现大量 SignalingChannel 记录(本例中 6 月 1 日产生约 6.6 万条,而其他天仅数百至数千条),导致不加过滤的 distinct resource_id 统计在月初出现虚高。
示例
- 某月 1 日统计:15.2 万 distinct resource_id
- 某月 2 日统计:8.6 万 distinct resource_id
- 差异 ~6.6 万 = signaling channel 月度计费记录
规避方法:统计活跃设备数时,只使用 BytesIn 类型,不做全量 resource_id 统计。
5.2 陷阱二:DataTransfer 归属不明
建议先确认数据格式,再应用过滤条件。执行以下查询,确认 DataTransfer 条目的 resource_id 实际格式:
确认格式后,再根据实际情况应用 ARN 过滤:
- Video Stream ARN 格式:
arn:aws:kinesisvideo:*:*:stream/stream-name/* - Signaling Channel ARN 格式:
arn:aws:kinesisvideo:*:*:channel/channel-name/*
在 SQL 中可通过 WHERE line_item_resource_id LIKE '%:stream/%' 过滤出仅属于 video stream 的传输费用,反之用 LIKE '%:channel/%' 过滤 signaling channel 的传输费用。
注意:DataTransfer 条目的 resource_id 字段在部分情况下可能为空或为聚合值,因此务必先执行上述确认查询,再使用过滤条件。
5.3 陷阱三:BytesHr 不代表当天推流
BytesHr 是存储计费,只要数据仍在 retention 期内就会持续产生。一个设备即使今天没有推流,只要历史数据尚未过期,就仍然会有 BytesHr 记录。因此,统计”当天活跃推流设备”应使用 BytesIn 而非 BytesHr。
例:一个设备 retention 设为 7 天,周一推了 1 小时流后停止。周二到周日该设备不会有 BytesIn 记录,但仍会持续产生 BytesHr 记录(因为周一的数据还在保留期内)。直到第 8 天数据过期,BytesHr 才会消失。
在了解了这些统计前提之后,我们可以开始进行系统化的三维拆解分析。
6. 三维分析法
Amazon KVS 的总 Ingest 用量可以分解为三个独立维度的乘积:
总日 Ingest (GB) = 活跃 Stream 数 × 平均活跃小时数/天 × 等效码率 (GB/h)
分别追踪每个维度的变化趋势,即可定量回答”增长来自哪里”。以下是每个维度的分析方法和对应 SQL。
6.1 维度一:活跃 Video Stream 数量(设备数)
通过 BytesIn 的 distinct resource_id 统计每日活跃推流 stream 数:
输出字段
| 字段 | 含义 | 用途 |
| active_streams | 当天有推流行为的 stream 数 | 最接近”活跃设备数” |
| total_ingest_gb | 当天所有设备推流总量 | 衡量整体规模 |
| avg_ingest_gb_per_stream | 每设备日均推流量 | 综合用量指标 |
为什么用 BytesIn?
- BytesIn 只对应 video stream 的推流操作,不含 signaling channel
- 有 BytesIn 记录 = 设备当天确实在推流 = 活跃设备
- 每条记录对应一个 stream 在一个整点小时内的推流量
6.2 维度二:推流时长分布
利用 CUR 按小时出行项目的特性,统计每个 stream 一天内有多少个小时有推流行为:
输出解读:结果是一个 1~24 的分布表,每行表示”活跃 N 小时的 stream 有多少个”。对各行加权平均(Σ hours_active × stream_count / Σ stream_count)即可得到当日的平均活跃小时数,用于三维公式的验证。
月级别聚合技巧:如需对比两个月的平均活跃小时数趋势,可按月聚合每设备每天的活跃小时数:
| 活跃小时数 | 设备行为特征 |
| 1-3 小时 | 事件触发型:检测到运动/声音才推流 |
| 8-12 小时 | 时段型:营业时间或白天推流 |
| 20-24 小时 | 持续型:7×24 连续录像 |
分析技巧:对比不同月份的分布,重点关注高时长段(19-24h)的设备数量是否持续增长。如果增速超过总设备数增速,说明设备正在从”事件触发”向”持续录像”迁移。
6.3 维度三:等效码率
每条 BytesIn 记录 = 一个 stream 在一个小时内的推流量。对全天所有记录取平均即为等效码率:
GB/h 转 Kbps 换算公式
码率 (Kbps) = avg_gb_per_stream_hour × 1024 × 1024 × 8 ÷ 3600
常见码率量级参考(仅供估算)
- 0.02-0.05 GB/h(~50-120 Kbps):低码率场景
- 0.1-0.2 GB/h(~230-470 Kbps):中等码率场景
- 0.4-0.5 GB/h(~930-1170 Kbps):较高码率场景
- 1.0+ GB/h(~2300+ Kbps):高码率/高分辨率场景
实际码率取决于编码器、分辨率、帧率和场景复杂度,建议以设备端实际配置为准。
趋势分析技巧:按月对比等效码率,观察变化模式:
- 阶梯式跳变:通常对应固件升级或产品配置批量变更
- 线性缓慢增长:可能是新设备型号(更高分辨率)逐步混入
- 稳定不变:码率不是增长因素,增长来自其他维度
7. 完整分析案例
注:以上数字为演示用途,均为虚构示例,不代表任何真实账户数据。
Step 1:运行 SQL-1,观察总量趋势
对 1 月和 3 月分别运行 SQL-1,得到以下月均数据:
| 指标 | 1 月均值 | 3 月均值 | 环比变化 |
| active_streams(日均) | 74,200 | 78,100 | +5.3% |
| total_ingest_gb(日均) | 39,479 GB | 45,711 GB | +15.8% |
| avg_ingest_gb_per_stream(日均) | 0.532 GB | 0.586 GB | +10.1% |
初步结论:设备数增长 5.3%,每台设备日均用量增长 10.1%,两者共同贡献了总 Ingest +15.8% 的增幅。需进一步拆解是时长变化还是码率变化驱动了单设备用量的提升。
Step 1.5(可选):业务台账校验
将 CUR 统计的活跃 stream 数(active_streams)与业务侧设备台账对比,确认统计口径一致后再继续深入分析:
- 对比对象:业务系统中的注册设备数、在线设备数
- 吻合:说明统计口径一致,分析结果可信
- CUR 数量 >> 台账:通常意味着存在未清理的历史 stream(设备已换绑或停用,但旧 stream ARN 仍在产生计费记录)
- CUR 数量 << 台账:可能有设备长期离线,或使用了其他区域的推流端点
Step 2:运行 SQL-2,对比时长分布
对比 1 月 15 日和 3 月 15 日的推流时长分布:
| 活跃小时数 | 1 月 stream 数 | 3 月 stream 数 | 变化 |
| 1-6 小时 | 18,400(24.8%) | 17,200(22.0%) | -1.2K |
| 7-18 小时 | 41,300(55.7%) | 38,600(49.4%) | -2.7K |
| 19-24 小时 | 14,500(19.5%) | 22,300(28.5%) | +7.8K |
发现:持续录像(19-24h)设备数从 14,500 台增长到 22,300 台,增加了 7,800 台(+54%)。而短时长设备(1-18h)合计减少约 3,900 台,与总活跃设备数的净增量(+3,900 台)基本吻合。这一模式高度指向存量设备推流策略发生了改变(事件触发 → 持续录像)。
对各时段加权平均,得到平均活跃小时数:1 月约 11.9h,3 月约 13.0h,环比 +9.2%。
⚠️ 注意:上述推断基于聚合层面的数量匹配,并不能完全排除”新增持续录像设备 + 短时长设备流失”的组合效应。若需精确归因,可通过追踪同一批 line_item_resource_id 跨月的时长变化来验证——若大量相同 stream 在 1 月处于短时长区间、3 月进入 19-24h 区间,则”切换”假设得到确认。
Step 3:运行 SQL-3,验证码率变化
| 月份 | avg_gb_per_stream_hour | 等效码率 |
| 1 月 | 0.0447 GB/h | ~105 Kbps |
| 3 月 | 0.0451 GB/h | ~106 Kbps |
发现:码率基本没有变化(+0.9%)。固件升级通常会改变默认编码参数(如分辨率、帧率),直接体现为等效码率的跳变;此处码率无明显变化,说明这一路径可排除。
归因结论与优化方向
1. 三维公式闭环验证
| 月份 | 活跃 Stream 数 | 平均活跃小时 | 等效码率 | 公式估算日 Ingest | SQL-1 实测日 Ingest |
| 1 月 | 74,200 | 11.9h | 0.0447 GB/h | 74,200 × 11.9 × 0.0447 = 39,479 GB | 39,479 GB ✓ |
| 3 月 | 78,100 | 13.0h | 0.0451 GB/h | 78,100 × 13.0 × 0.0451 = 45,711 GB | 45,711 GB ✓ |
三个维度的乘积与 SQL-1 实测值完全吻合,说明分解路径可信。各维度贡献:设备数 +5.3%、时长 +9.2%、码率 +0.9%,乘积增幅 = 1.053 × 1.092 × 1.009 − 1 ≈ +16.0%(受四舍五入影响,与账单增幅 15.8% 误差在 0.3% 以内,属正常偏差)。
2. 对应优化方向
- 与产品/固件团队确认:是否有版本更新改变了默认录像策略?
- 对这 7,800 台设备评估:是否需要持续录像,还是可以恢复事件触发模式?
- 如确需持续录像:retention 是否也随之延长?若是,需同步评估存储优化(参考第 8.2 节)
8. 基于分析结果的优化建议
完成三维分析后,可以针对性地采取以下优化措施:
8.1 清理未使用的 Signaling Channel
适用场景:Signaling Channel 数量远超活跃 Video Stream 数量,且确认这些多余的 channel 当月仍有设备定期连接(即在 CUR 中有对应的 SignalingChannel 计费条目)。
操作方法
- 用 SQL 对比 SignalingChannel 总数与 BytesIn 的活跃 stream 数
- 如果 channel 数 > stream 数的 1.5 倍以上,大概率有历史遗留
- 通过 ListSignalingChannels API 获取 channel 列表,结合业务侧设备注册表识别不再使用的 channel
- 删除不再需要的 channel,立即停止月费
预期收益:每清理 10 万个活跃计费的 channel,每月节省约 $3,000($0.03/channel/月,以 us-east-1 定价为参考,请以 官方定价页 为准)。
8.2 存储成本优化
适用场景:存储成本占比高,且实际回看率低。
峰值总存储量与 retention 的关系:
峰值总存储量 (GB) ≈ 活跃 Stream 数 × 平均推流时长/天 × 码率 (GB/h) × Retention 天数
这意味着即使 ingest 量不增长,修改 retention(如从 7 天改为 30 天)也会导致存储阶梯式增长。
优化策略
- 缩短 Hot Tier retention:
- 对比
BytesHr(存储)与BytesOut(消费)的 resource_id 重合度 - 如果大量 stream 有存储但从未被消费(拉流),说明 retention 设置过长
- 对事件触发型设备,设置更短的 retention(如 24-72h);保留 24-72h 已满足需求,无需延长至 30 天以上
- 对比
- 迁移长期保留需求至 Warm Tier:
- 评估现有 retention 设置中,实际保留天数 ≥ 30 天的 stream 是否可以迁移至 Warm Tier(详见 §2.3)
- Warm Tier 按 fragment 计费 ingest,配合更长的 fragment duration 可进一步降低成本
- 适合合规要求长期保留(30-90 天)但很少回看的场景
- 参考 AWS 官方博客 中的最佳实践
⚠️ Warm Tier 迁移前必算两笔账:
- 存储打平点:Warm Tier 有 30 天最低计费——实际保留 2 天也按 30 天收费。粗略估算:retention ≥ 30 天才开始省存储费,16 天约持平,7 天约贵 2 倍,2 天约贵 8 倍。建议门槛:retention ≥ 30 天再考虑迁移,与 §2.3 的最小保留期保持一致。
- 低码率设备额外注意:Warm Tier 的 Ingest 按 fragment 条数计费,与数据量无关。低码率设备(如 ≤128 Kbps 的门铃/门锁类)产生的 fragment 数量相同,但每 fragment 节省的存储费更少,综合算下来可能并不划算。建议先估算:
每月 fragment 数 × Warm Ingest 单价与每月节省的存储费(Hot - Warm 差价 × GB 数)孰大孰小,再决定是否迁移。
8.3 设备端优化方向
如果分析发现码率提升或推流时长增加是主因,以下方向可供产品/固件团队参考:
- 码率优化:H.265 编码(相比 H.264 节省 30-50% 带宽)、自适应码率(静态场景自动降码率)、合理选择分辨率
- 推流策略优化:事件触发推流(设备端 AI 检测)、时段调度、本地缓存 + 按需上传
这些优化需要设备端配合实施,CUR 分析的价值在于提供数据支撑——量化潜在收益,帮助团队做优先级决策。
8.4 WebRTC TURN 成本排查
适用场景:TURNMinutes 费用占比异常高(通常意味着 P2P 直连失败率高)。
排查方向
- 统计 TURN 依赖度:对比有 TURNMinutes 记录的 distinct channel 数与有 SignalingMessages 记录的 distinct channel 数。比值越接近 1,说明越多会话需要 TURN 中继而非 P2P 直连。
- NAT 类型问题:用户网络中对称 NAT 占比高会导致 P2P 穿透失败,TURN 成为必要路径
- 按设备/channel 维度聚合 TURNMinutes,识别是少数设备大量使用还是普遍性问题
- 优化方向:改善 ICE 配置(增加 STUN 服务器)、引导用户改善网络环境、评估是否可用 HLS 替代 WebRTC 回看
9. 总结
本文介绍了通过 AWS CUR 数据系统化分析 Amazon Kinesis Video Streams 用量的完整方法论:
- 看懂账单结构再查数:区分 Video Stream 和 WebRTC 的计费逻辑,绕开 SignalingChannel 月初噪声和 BytesHr 的误导,才能得到可信的活跃设备数
- 三维拆解定位增长根因:活跃设备数 × 推流时长 × 等效码率 = 总 Ingest,三个维度各自贡献多少,一查便知
- 数据闭环是关键:三维乘积要能还原出实测总量,分析结论才站得住;CUR stream 数要能对上业务台账,异常才有落点
- 归因驱动优化:时长问题找推流策略,码率问题找编码配置,channel 过多找清理脚本——对症下药比泛泛优化有效得多
这套方法适用于任何规模的 Amazon KVS 部署。三个核心 SQL 可以直接在 Amazon Athena 中运行,无需额外工具,即可完成从数据采集到归因分析的全流程。
快速排查指引:KVS 账单突然增长时从哪里入手?
当月 KVS 费用较上月明显增长
- 先看设备数变化(SQL-1:active_streams 月环比) → 涨了?→ 新设备接入 / 历史休眠设备重新激活
- 设备数没变?看推流时长分布(SQL-2:hours_active 分布变化) → 时长增加?→ 持续推流设备占比升高 / 运动触发阈值降低
- 时长也没变?看等效码率(SQL-3:avg_gb_per_stream_hour) → 码率跳升?→ 固件升级更改了编码参数 / 新摄像头型号分辨率更高
- 额外检查 WebRTC:SignalingChannel 月度条目数是否异常增多? → 是?→ 大量 channel 当月有连接但未被清理
➡️ 下一步行动:
相关产品:
- Amazon Athena — 使用 SQL 在 S3 中查询数据
- Amazon Kinesis — 实时流数据处理
- Amazon EC2 — 安全且可调整大小的计算容量
- Amazon S3 — 适用于 AI、分析和存档的几乎无限的安全对象存储
- Amazon CloudFormation — 基础设施即代码服务
相关文章:
- 使用 Amazon Athena 分析 Kiro 团队用量报表:动态模型列的数据建模实践
- AWS Security Agent 增加威胁建模、Kiro 能力包、Claude Code 插件及更多功能
- 使用 AWS Security Agent 构建应用安全闭环——从代码提交到漏洞修复的自动化之路
- 飞来汇借助 AWS Security Agent 构建跨境支付应用的智能安全防线
- AWS Security Agent 渗透测试实操
10.相关资源
- Amazon Kinesis Video Streams 定价
- AWS Cost and Usage Report 用户指南
- CUR Query Library(各服务 CUR 查询示例)
- Amazon KVS Tiered Storage 文档
*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。
本篇作者
AWS 架构师中心:云端创新的引领者探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用 |
![]() |

