Databricks 把有状态流的分区数从 checkpoint 里解锁;Kinesis 给只涨不落的容量补上下降方向;Snowflake 用出向隧道接进私有数据源;Redpanda 把压缩推进对象存储
本期聚焦四条同在 9 月 14 日前后落地的进展:Databricks 让 Spark 有状态流可以在保留 checkpoint 的前提下原地改分区数,Kinesis 让 on-demand 流的容量第一次可以主动往下降,Snowflake 用出向 TLS 隧道替代入向防火墙开口子接进私有源,Redpanda 让分层存储把压缩与墓碑清理推进对象存储。
这四条进展分属流计算的 state 布局、托管流的容量调节、数据集成的网络路径与日志段的压缩,指向同一件事:原本只能在创建那一刻定下来、之后想改就得推倒重来的东西,现在可以在原地调整。Databricks 把有状态流的分区数从 checkpoint 里解锁,改一次只需要停机、改配置、重启。Kinesis 给 on-demand 流只涨不落的容量补上了下降方向,用「过去一小时峰值」兜住下限。Snowflake 把「云侧探进内网」的入向连接反转成「内网主动出云」的出向隧道,防火墙上不再需要新增一条入向规则。Redpanda 让压缩从本地数据推进对象存储,重复 key 与墓碑不再永久堆积在便宜却清不掉的那层里。代价没有消失,只是换了位置:每一次调整都要付一次可度量的停顿或一道护栏——一次 repartition、一个一小时峰值下限、一份必须能随时吊销的证书、一个只能在建 topic 时选定的存储实现。
Databricks 按需状态重分区:state 分区数不再是「开流时定终身」
事件概述
Databricks 于 9 月 14 日宣布,Spark Structured Streaming 的按需状态重分区(on-demand state repartitioning)进入公开预览,运行在 Databricks Runtime 18 及以上版本。功能要解决的是一个几乎所有长期运行的有状态流都会撞上的问题:分区数在创建 checkpoint 时被写死,之后无论怎么改 spark.sql.shuffle.partitions,查询都会静默忽略。
典型场景是这样的。开流时数据量不大,接受了默认的 200 个 shuffle 分区。半年后流量涨了三倍,state store 膨胀,部分分区倾斜变热,每个 microbatch 都比应有的更慢。这时候把 spark.sql.shuffle.partitions 调大再重启,什么都不会发生。过去唯一的办法是丢弃现有 checkpoint 重来,而对一个跟踪数百万账户的欺诈模型、或者持有数天窗口的会话化作业来说,重来等于丢掉全部累积状态。
新能力允许在保留 checkpoint 与全部 state 的前提下,把分区数改到新值。它适用于聚合、流-流 join、去重、会话化与 transformWithState 等各类有状态查询。早期使用者 Coveo 给出了一组对照数字:其大规模有状态流的 Amazon S3 API 成本下降 40%;在此之前每次扩容只能二选一,要么过度配置,要么从新 checkpoint 重建,而存储 API 成本一度涨到与计算成本相当。
技术解析
- 为什么原来锁死:有状态查询的 state 按 key 哈希到分区,每个分区的数据存放在 checkpoint 里各自独立的 RocksDB 实例中,分区数决定了整个 state store 在磁盘上的布局。如果两次重启之间直接改分区数,哈希就不再对得上——原本落在 47 号分区的 key 现在会被算到 12 号,而它累积的 state 还躺在原分区的文件里,查询等于丢失了自己的记忆。为了避免这种静默损坏,Structured Streaming 选择在 checkpoint 创建时锁死分区数。
- 新配置与优先级:改动走的是专用的
spark.sql.streaming.stateStore.partitions,而不是spark.sql.shuffle.partitions。对有状态查询,前者优先级高于后者,这正是这次改动能「生效」、而老办法不能的原因。前置条件只有两条:DBR 18 及以上,以及 RocksDB state store provider——DBR 17.3 起 RocksDB 已是默认,该版本之后新建的查询除非显式改过,否则已在用。 - 重启时发生了什么:重启后的查询不会立刻恢复处理。它先跑完最后一个已计划的 microbatch,接着执行一次一次性的 repartition——按新分区数把 state 数据物理重分布、把 key 重新哈希到正确位置,全部搬完才恢复常规处理。放大和缩小走的是同一条路径,官方给出的示例是用同一个查询定义从 200 降到 100,再反向从 100 升回去。
- 可观测性:重分区的耗时随 state 体量增长,Structured Streaming 把它挂进了标准进度上报。下一个 microbatch 完成之后,
StreamingQueryProgress的durationMs里会出现controlBatch.REPARTITION字段,单位毫秒,官方示例值为 4820。文档预期多数 workload 只需几秒,大作业值得把这个指标采下来。 - 适用边界:官方把它定位为调优与扩缩容工具,不是日常操作。每次改动都要一次停机、改配置、重启,并伴随一次重分区停顿,应当按一次有计划的维护动作来安排窗口。Spark Declarative Pipelines 也走同一套机制。
行业影响
这条改动的价值不在性能,而在于把一个「开始时的决定」变成了「可反复重做的决定」。有状态流过去最难的不是性能调优,而是调优的代价被绑死在重建成本上:想试 400 个分区会不会降低 microbatch 延迟,就得重建 state 并重放数据,试错成本高到没人愿意试。现在可以拿线上 checkpoint 直接试,用 controlBatch.REPARTITION 和 microbatch 耗时做判断,把经验决策换成测量决策。
值得留意的是它把代价挪到了哪里:不再需要丢弃状态,但每次调整都要一次真实的数据搬移和一段处理停顿,这段停顿与 state 体量成正比。对一个持有数 TB state 的作业,这意味着扩容本身变成了一次需要排期、需要观测、需要回滚预案的操作。Coveo 那条 40% 的降幅也说明,此前被分摊进日常运维的存储 API 开销有多大——按官方表述,它一度接近计算成本本身。
相关链接
- Announcing On-Demand State Repartitioning for Apache Spark Structured Streaming on Databricks
- On-demand state repartitioning for stateful streaming queries(产品文档)
Kinesis on-demand 容量可以往下降了:给只涨不落的 shard 数补上回落方向
事件概述
AWS 于 9 月 14 日在 Big Data Blog 发文,介绍 Kinesis Data Streams on-demand 流新增的容量下调能力。此前 on-demand 模式会自动分裂 shard 应对流量上涨,但峰值过去之后,抬高的容量会长期留在那里。官方举的例子是:一条稳定跑在 100 MB/s 写入的流需要约 100 个 shard,一次额外 50 MB/s 的突发把流推到 150 个 shard,突发几分钟内就结束了,可这 150 个 shard 留了下来。
多出来的容量不向 Kinesis 侧收费——on-demand Advantage 不按抬高的容量计费——但账单转到了下游。若 Lambda 消费者的并行度因子是 2,并发调用就从 200 涨到 300,多了 50%,这些额外的调用消耗计算资源、占用并发执行配额,还因为每批数据变小而拉低处理效率。用 KCL 的消费者代价更直接:每个 shard 在 DynamoDB 里对应一个 lease,多 50 个 shard 意味着每个心跳周期要多扫描、续租与 checkpoint 50 个 lease。
新能力允许在开启 on-demand Advantage(ODA)的流上设置一个不高于当前值的 warm throughput,触发容量回收。这项能力对所有已开启 ODA 的 on-demand 流免费提供。
技术解析
- 双向调节:warm throughput 原本只能向上——预判到流量事件就调高,让容量提前就位。现在补上了向下:突发把流推到远超稳态需求时,调低 warm throughput 即可触发缩容。
- 护栏是「过去一小时峰值」:设置之后,最终容量取两个值的较大者——你请求的 warm throughput,以及支撑过去一小时内峰值写入量所需的容量。这条护栏保证不会因为一次误判把容量压到当前负载之下。缩容完成后如果流量重新上涨,on-demand 的响应式扩容依然会接住,避免限流。
- 操作方式:先确认流处于 on-demand 模式且已开启 ODA,然后执行
aws kinesis update-stream-mode --stream-arn <arn> --warm-throughput-in-mb 50。需要的 IAM 权限是kinesis:UpdateStreamMode。 - 监控要看什么:
IncomingBytes用 Sum 统计看总吞吐,IncomingRecords看流量模式与突发频次,WriteProvisionedThroughputExceeded是被限流丢弃的记录数——缩容之后这个值非零,就说明压得太低了。OpenShardCount不是 CloudWatch 指标,要通过DescribeStreamSummary或控制台拿,也可以写个 Lambda 定期轮询做成自定义指标。 - 官方给出的做法:缩容前至少回看 24 小时的
IncomingBytes与IncomingRecords,确认基线。因为 on-demand 流会保留到近期观测峰值的两倍,目标 warm throughput 应当设在典型峰值之上,而不是均值之上。缩容后数小时盯紧WriteProvisionedThroughputExceeded,出现限流就调回去。最适用的场景是能确认突发是临时性的——计划内的批量迁移、营销活动、定时回补;流量走势不明或仍在增长时不要动。不确定目标值的话,可以直接设一个偏低的值,让一小时峰值护栏兜底。
行业影响
这件事的意义在于,它承认了「弹性」在很长一段时间里只有一半。自动扩容做得再顺滑,只要缩容需要人工介入或者切回预置模式,长期运行的流就会缓慢地累积一层用不上的容量,而这一层的成本不在流的账单上,藏在消费者侧的计算、并发配额与 lease 管理开销里。把一个隐性成本显性化,再提供一个显性的回收开关,这个组合比单纯降价更有价值。
更有意思的是护栏的设计。AWS 没有给用户一个「立即降到 N」的硬性开关,而是把下限锚定在最近一小时的峰值写入上。这意味着缩容是一次可以被系统否决的请求,用户拿到的不是绝对控制权,而是在一个安全区间内的调节权。对平台方来说,这是把「误操作导致限流」这类工单前置消化的标准手法;对用户来说,代价是缩容的效果要等一小时窗口滑过去才能完全兑现。
相关链接
- Scale down Kinesis Data Streams on-demand capacity with ODA warm throughput
- Amazon Kinesis Data Streams on-demand capacity mode(开发者指南)
Snowflake Data Connectivity Proxy:把入向开口子换成出向隧道
事件概述
Snowflake 于 9 月 14 日宣布 Data Connectivity Proxy(DCP)正式可用,作为 Openflow 的组成部分,用于接入此前够不着的私有数据源。Openflow 是 Snowflake 托管的集成服务;DCP 补的是它最难的一环——那些位于企业内网、私有 VPC 或者与 Snowflake 账户不在同一朵云上的源。
这篇博客把问题的性质讲得很直接。对金融、医疗、制造业而言,「默认拒绝一切入向」往往是合规要求而不是偏好。当一家托管管道厂商说「配一条私有网络连接」,实际要牵动的是网络工程团队、防火墙变更与变更顾问委员会的审批。DCP 的做法是把方向掉过来:agent 只发起出向的 443 端口 TLS 连接,防火墙上不再有任何入向规则需要开、需要改、需要审批。
DCP 已于 AWS、Azure、GCP 三家云上对 Standard、Enterprise、Business-Critical 三个版本正式可用。覆盖的源包括防火墙后的本地数据库(Oracle、SQL Server、PostgreSQL、MySQL)、私有 VPC 或数据中心里的 Kafka broker,以及跨云场景——例如数据留在 AWS 而 Snowflake 账户开在 Azure。
技术解析
- 身份与加密:在 Snowflake 侧铸造一次性的 bootstrap JWT,放到 agent 主机上。agent 拿这个 token 向 DCP 控制面出示一次,换回一张绑定到该 DCP client 的 mTLS 证书;此后的隧道、心跳与路由更新全部走 mTLS,双方每次连接都互相验证书。证书由 Snowflake 在后台轮换,token 在下一次轮换之前不再使用。官方示例里 bootstrap token 的有效期设为 7 天。
- agent 是 TCP 透传:它转发流量,不检查、不解析、不存储穿过隧道的字节。源端凭据留在 Snowflake,不会落到 agent 上。
- 目标地址在云端做白名单:一条 network rule 指定私有主机与端口,一个 external access integration 允许这条 rule,再把该 integration 绑到 DCP 对象上;可选地再挂一条 network policy,限制哪些源 IP 能与 DCP 控制面通信。禁用或删除该对象,agent 的证书立即失效——即使证书本身尚未过期。
- 部署形态:agent 以 Docker 镜像分发,跑在任意带 Docker 或其他 OCI 兼容运行时的 Linux 主机上,不要求 Kubernetes。隧道断掉会自动重连,证书轮换在后台进行,不拆断活跃连接。
- 已知限制:agent 主机需要能直连 Snowflake 的 443 端口;把 agent 自身的出向流量走企业托管的正向代理(
HTTPS_PROXY或基于 CONNECT 的转发),目前不支持。 - 与既有方案的定位差:云厂商原生私有连接(AWS PrivateLink、Azure Private Endpoint、Google Private Service Connect)适合同云内的私有路径,不面向本地源;VPN、ExpressRoute、VPC peering 能用,但每一个都是需要跨团队协调、审批与长期维护的数周工程;第三方连接 agent 解决技术问题,代价是多一个厂商、一份合同和一套要运维的系统。
行业影响
把连接方向反转,本质上是在绕开企业网络治理里最贵的那一步。开通一条入向规则的真实成本不是配置本身,而是它触发的审批链与随之而来的长期审计义务;出向连接在很多组织里属于默认允许的类别,于是一个原本以季度计的项目,压缩成了一次容器部署。
代价同样清晰地挪了位置。过去风险集中在防火墙上——一处配置错误可能被外部触达;现在风险集中在凭证与对象生命周期上——谁能铸造 bootstrap token、谁能在 Snowflake 侧改白名单、删除 DCP 对象这一动作是否真的被纳入了离职与轮换流程。官方特意写明「删掉对象证书即刻失效」,说明他们清楚这里才是新的控制点。那条「不支持企业正向代理」的限制也值得留意:在出网必须过代理的组织里,这一条会直接卡住落地。
相关链接
- Introducing Data Connectivity Proxy: Bring Snowflake Openflow to Private Data
- Data Connectivity Proxy overview(产品文档)
- Data Connectivity Proxy security model
Redpanda 分层存储 v2:让压缩与墓碑清理进入对象存储
事件概述
Redpanda Cloud 在 2026 年 9 月的更新中上线了 Tiered Storage v2(beta)。分层存储负责把 topic 数据从 broker 卸载到对象存储,Redpanda Cloud 默认开启。从 v26.2 起它分为两个版本,v1 是原有实现并保持默认,v2 是新增实现,补上的能力是对象存储层上的完整压缩支持,包括墓碑清理。Redpanda 文档按月份归档更新,未给出该项的具体上线日,只能确定落在 9 月。
这项改动针对的是一个长期存在的、容易被忽略的浪费。对设置了 compact 清理策略的 topic,v1 的压缩只在本地数据上进行,已经上传到对象存储的部分不参与压缩,重复 key 可能无限期留在那里;压缩窗口也有限,只有落在同一窗口内的重复 key 会被去掉;墓碑记录则完全不被清理。结果是,一层本该因为便宜而放心扩容的存储,悄悄堆积了一批删不掉的冗余数据。
技术解析
- 两版的差异:压缩范围上,v1 只压本地、已上传对象存储的数据不压,v2 在对象存储中的数据上执行压缩,整个分区都被覆盖。压缩窗口上,v1 限于一个较小的窗口,v2 是全量压缩,最终每个 key 只保留最新值。墓碑处理上,v1 不支持移除,v2 支持,并在
delete.retention.ms配置的保留期之后移除墓碑记录。 - 怎么选版本:两版的启用方式相同,都是把 topic 的
redpanda.storage.mode设为tiered,且两个版本下该属性都显示为tiered。真正的版本由集群属性default_redpanda_storage_mode_tiered_impl决定,默认为tiered_v1。执行rpk cluster config set default_redpanda_storage_mode_tiered_impl=tiered_v2即可让之后新建的 tiered topic 走 v2,这个改动不需要重启集群。 - 逐 topic 指定:建 topic 时一并设置两个属性即可覆盖集群默认值——
rpk topic create <topic_name> -c redpanda.storage.mode=tiered -c redpanda.storage.mode.impl=tiered_v2。两个值必须一致。要确认某个已有 topic 用的是哪一版,跑rpk topic describe <topic_name>,只读属性redpanda.storage.mode.impl会报出tiered_v1或tiered_v2。 - 限制:v2 需要 BYOC 或 Dedicated 集群且 Redpanda 版本在 26.2 及以上,Serverless 集群使用 v1。升级集群不会改变已有 topic 的版本,调整集群默认值只影响之后创建的 topic。
redpanda.storage.mode.impl是只读属性,只能在建 topic 时设置,一个 topic 无法在 v1 与 v2 之间转换。 - 成熟度:官方标注为 beta,写明不用于生产部署,并在 Redpanda Cloud 上渐进式推出。文档给出的选型建议很具体——为「不允许在对象存储中累积过期值或墓碑」的新的压缩型 topic 选择 v2。
行业影响
压缩语义在分层存储里长期是个缺口。本地层压得很干净,便宜的那一层反而成了冗余数据的沉积池,这在成本模型上是错配的:越是往对象存储里放,越需要它只留有效数据,而 v1 恰恰做不到。v2 把压缩推进去,等于让「便宜的层」第一次真正具备 log compaction 的完整语义。
真正的分界线在「不能转换」这一条上。v1 与 v2 之间无法互转,意味着存量 topic 想享受新语义只能重建——这与本期其余三条恰好构成一组对照:Databricks、Kinesis、Snowflake 都在把不可逆的决定改成可反复调整的操作,而 Redpanda 在这里仍然要求你在建 topic 那一刻选对。加上它仍是 beta 且官方明确不建议上生产,现阶段的现实做法大概率是:新 topic 按语义要求选 v2,存量 topic 等成熟度上来再说。选择权给出来了,迁移路径还没给。
相关链接
编者评
把这四条放在一起看,主线不是「性能变好了」,而是「可撤销性正在被当作一项功能来卖」。分区数、流容量、网络入口方向、压缩范围,这四个参数过去有一个共同点:它们都在对象创建的那一刻被固化,事后要改,代价是一次足以让人放弃的重建——丢掉 state、切回预置模式、开一条防火墙规则、或者重建整个 topic。现在每一件都补上了一条原地修改的路径。
四条路径各自配了一道护栏,而护栏的形态很能说明平台方在担心什么。Databricks 要求一次停机与一次与 state 体量成正比的数据搬移,并把它显式暴露成 controlBatch.REPARTITION 这个指标。Kinesis 不接受你直接指定容量,只接受一个会被「过去一小时峰值」否决的请求。Snowflake 把风险从防火墙挪到了凭证生命周期,于是把吊销动作设计成「删对象即失效」这样一个足够简单的操作。Redpanda 干脆不给迁移路径,用「只能在建 topic 时选」把不确定性挡在门外。护栏的位置,就是各家认为最可能出事的地方。
对使用者来说,这里有一笔需要自己算的账。可逆性不是免费的,它把「一次性的重建成本」换成了「每次调整都要付的小额成本加一道约束」。当调整变得便宜,调整的次数就会变多,而每一次调整仍然需要一个窗口、一份观测和一套回滚预案。真正的收益不在于省下了那次重建,而在于试错从「不值得做」变成了「可以做」——分区数可以拿线上 checkpoint 试,容量可以按小时回收,连接不必再等一个季度的审批。这种变化通常不会立刻体现在某项指标上,它会体现在半年后系统的形态上:那些因为改不动而被将就着留下的设计,会一个一个被改掉。
本期中文源没有可回源的技术发布。阿里云、火山引擎的更新日志与文档在本期内无新增条目,FutureX 数据库行业简报最新一期仍为 9 月 12 日的第 35 期(已在 Vol.65 覆盖)。唯一落在 9 月 15 日的中文相关消息是 Singdata 宣布其 Lakehouse SaaS 在 8 朵云与 3 种 CPU 架构上全量可用,属新闻稿、未附可验证的技术细节,按「优先技术内容」的原则未展开,仅在此记一笔。