3. Kinesis Data Streams核心机制
Kinesis Data Streams(KDS)是 AWS 上承载实时数据摄取的基础服务,它的行为几乎全部由“分片”这一概念决定。理解分片、分区键、序列号、保留周期、扩缩容模式与吞吐量计算,是后续设计生产级实时分析系统的前提。本节围绕这些核心机制展开,并给出可复用的吞吐量估算方法。
分片:KDS 的并行与容量单元
一个 Kinesis 数据流由一个或多个分片(Shard)组成。分片是 KDS 的容量与并行单元:每个分片提供固定的写入与读取能力,数据在分片内按到达顺序追加,消费者按分片并行读取。因此,流的整体吞吐量约等于“分片数 × 单分片能力”。
每个分片的典型能力如下(以预置模式为准):
- 写入:1 MB/s 或 1000 条记录/s,二者取先达到者;单条记录上限 1 MB(含分区键)。
- 读取(共享吞吐,经典 KCL/GetRecords):2 MB/s。
- 读取(增强扇出,Enhanced Fan-Out):每个消费者 2 MB/s 独占带宽。
需要特别注意:写入限制是“1 MB/s 或 1000 条/s”,不是两者同时满足。若记录很小(例如 200 字节),1000 条/s 会先触发上限;若记录很大(例如 100 KB),1 MB/s 会先触发上限。这直接决定了分片数量的估算方式。
分区键:决定记录进入哪个分片
生产者写入记录时必须提供分区键(Partition Key)。KDS 对分区键做 MD5 哈希,再映射到某个分片。因此:
- 相同分区键的记录总是进入同一分片,从而保证该键内的顺序。
- 不同分区键可能落到同一分片,也可能分散到不同分片。
- 分区键分布不均会导致“热分片”,即某个分片先达到 1 MB/s 或 1000 条/s 而被限流,而其他分片空闲。
分区键的选择原则是高基数且分布均匀。例如用设备 ID、用户 ID、订单 ID 作为分区键通常较均匀;若用固定字符串、日期或状态值作为分区键,则极易造成热点。若业务不要求键内顺序,可使用随机后缀(如 UUID)打散,但会牺牲同一逻辑实体的顺序性。
序列号:分片内的唯一位置标识
每条写入成功的记录都会获得一个序列号(Sequence Number),它是该记录在分片内的唯一标识,由 KDS 分配,长度约 50 位以上数字字符串。序列号的主要用途:
- 作为消费者检查点(Checkpoint)的游标,记录“已处理到哪一条”。
- 用于 GetShardIterator 的 AT_SEQUENCE_NUMBER / AFTER_SEQUENCE_NUMBER 定位。
- 在排查重复或丢失时,用于比对生产与消费的边界。
序列号在分片内单调递增,但跨分片不保证有序。因此“全局有序”在 KDS 中并不成立,只有“同一分区键(同一分片)内有序”。
保留周期:数据可重读的时间窗口
保留周期(Retention Period)决定记录写入后可供读取的时长。默认 24 小时,可延长至最多 365 天(按延长部分额外计费)。保留周期直接影响:
- 消费者故障后能否从旧检查点恢复;
- 是否支持“重放”历史数据做回溯分析;
- 成本,延长保留会增加存储费用。
若下游需要重放或补数,应把保留周期设置为大于最大可接受故障恢复时间。例如要求 7 天内可重放,则保留周期至少设为 168 小时。
扩缩容模式:预置与按需
KDS 提供两种容量模式:
- 预置模式(Provisioned):手动指定分片数,可按需 SplitShard(增加)或 MergeShards(减少)。扩容通常几分钟内生效,缩容需合并相邻分片。适合流量可预测、成本敏感的场景。
- 按需模式(On-Demand):无需管理分片数,KDS 根据流量自动伸缩,默认支持最高约 200 MB/s 写入与 200 MB/s 读取(可申请提高)。适合流量波动大或难以预估的场景,但单位成本通常高于预置模式。
选择依据:若峰值/均值比小于约 2 且可预测,预置模式更经济;若波动剧烈或上线初期不确定,按需模式更省心。两种模式都支持增强扇出,但按需模式下的分片数对用户不可见。
吞吐量计算:从需求到分片数
分片数估算的核心是分别计算“写入所需分片”和“读取所需分片”,取较大值。公式如下:
写入分片数 = max( 平均写入MB/s / 1 , 平均写入记录数/s / 1000 )
读取分片数 = 平均读取MB/s / 2 (共享吞吐)
= 平均读取MB/s / 2 (增强扇出,按每个消费者单独计算)
最终分片数 = max(写入分片数, 读取分片数) × 安全系数(1.2~1.5)
示例(合理假设):某系统平均写入 8 MB/s、每秒 6000 条记录,单条平均约 1.3 KB;下游两个消费者各需读取 8 MB/s。
- 写入分片数 = max(8/1, 6000/1000) = max(8, 6) = 8。
- 共享吞吐读取分片数 = 8/2 = 4;两个消费者共享,总读取需求 16 MB/s,则 16/2 = 8。
- 若使用增强扇出,每个消费者独占 2 MB/s,则每个消费者需 8/2 = 4 个分片,两个消费者共 8 个分片。
- 取 max(8, 8) = 8,再乘安全系数 1.3,约需 11 个分片。
注意:以上为估算,实际还需考虑分区键分布、记录大小波动、消费者处理延迟与重试。若分区键分布不均,即使总分片数足够,仍可能因热分片被限流。
实践中的关键判断
在真实系统中,分片数不是一次算完就固定不变的。建议按以下顺序排查与调整:
- 先看指标:WriteProvisionedThroughputExceeded 与 ReadProvisionedThroughputExceeded 是否持续大于 0。
- 若写入被限流,先检查分区键分布,再考虑扩容;若读取被限流,先评估是否启用增强扇出,再考虑扩容。
- 扩容后观察 5~10 分钟,确认限流指标回落且消费者延迟(MillisBehindLatest)下降。
- 若流量长期低于估算值,可合并分片以降低成本,但合并会短暂影响可用性,建议在低峰期执行。