前一期我们聊完了LSM\-Tree为什么能成为时序数据库的标配存储结构。但存储模型解决的是单节点上数据怎么落盘的问题,一旦数据量上来、节点数变多,就绕不开另一个核心问题: 数据怎么拆到不同机器上去?这就是分片(Sharding)要干的事。时序数据库的分片策略看起来选择不少,但归根结底就三种思路:按时间分、按维度分、按哈希分。每种思路的底层逻辑不同,适用的场景也不同。选错了,轻则查询变慢,重则扩缩容直接翻车。这篇从底层设计逻辑出发,把这三种分片策略理理清楚。
工业物联网、车联网、能源监测这些场景,数据写入是持续不断的。一台设备一天可能产生几万条时序点,十万台设备就是几十亿条。单机存储和写入能力总有天花板,CPU、内存、磁盘IO、网络带宽,哪个先扛不住都不好说。分片的目的就是把 写入压力、存储容量、查询负载分散到多个节点上。但时序数据有个很特殊的属性:它自带时间戳,而且写入顺序基本和时间正相关。这个特征让时序分片和电商订单、社交网络这类数据的分片思路很不一样。
传统数据库分片,核心目标是让数据均匀分布,避免热点。时序数据库分片,除了均匀,还要考虑 时间局部性和 查询模式。因为时序查询十有八九是查某段时间内某个设备的数据,如果分片策略和查询模式对不上,查询时就要跨很多节点拉数据,网络开销会拖死整个集群。所以时序分片不是怎么把数据拆开这么简单,对时序数据库而言,分片策略直接决定了:
接下来我将分别介绍下比较主流的三种分片方式:时间分片、维度分片和哈希分片。

shard_id = floor((timestamp - epoch) / shard_duration)
这些模型的共同点是: 查询模式高度时间局部化。运维查监控,通常只看最近 1 小时或某一天的曲线。

当前主流产品对比:
- InfluxDB 的 Shard Group 是典型的时间分片,默认按 7 天一个窗口,实现简单,但粒度固定,高峰期容易单分片膨胀。
- TimescaleDB 的 Hypertable Chunk 也是按时间范围切分,Chunk 大小可配置,但需要 DBA 根据业务特征手动调参。
- KaiwuDB 在这块做了自适应动态分片,系统会根据写入吞吐自动调整时间窗口大小。这个思路的好处是低峰期不会分片过细浪费元数据资源,高峰期又能自动拆分避免单点瓶颈。不过动态调整是否会增加元数据管理的复杂度,以及分片合并/拆分过程中的查询一致性如何保证,还需要在真实场景下验证。
device_id
、
region
、
tenant_id
等维度,把同一维度的数据路由到同一个分片。底层通常是基于维度值的范围或前缀来做分片映射:
shard_id = hash(tag_value) % num_shards // 或者按 tag 范围划分

当前主流产品对比:
- TDengine 的超级表(STable)+ 子表设计,本质上是一种维度分片的变体——按设备维度把数据拆到不同的子表(vnode)中。这种设计在设备查询场景下性能很好,但代价是纯时间范围查询必须带设备过滤,否则就是全 vnode 扫描。
- IoTDB 在最新版本里引入了时间分区 + 设备分区的混合策略,试图缓解纯维度分片的问题。
- KaiwuDB 的做法是时间分片为主、标签维度为辅的二级分片:先按时间窗口切分,再在时间窗口内按 Series(标签组合)做路由。这种混合思路相当于在时间查询和维度查询之间取了一个平衡,但实现复杂度也更高,二级路由的元数据开销需要关注。
shard_id = hash(timestamp, tag1, tag2, ...) % num_shards
哈希函数通常选择一致性哈希(Consistent Hashing),以最小化扩容时的数据迁移量。
对查询模式不确定的系统:无法预判用户主要按时间还是按维度查询

当前主流产品对比:
- Cassandra 和 HBase 在时序场景下常采用哈希分片,因为它们的底层存储引擎(LSM\-Tree)对顺序写友好,但对时序查询的局部性没有特殊优化。
- VictoriaMetrics 虽然主要按时间分片,但在集群模式下对 Series 做了哈希路由,属于一种折中方案。
- 纯哈希分片在时序数据库中其实越来越少见,因为时序数据的查询模式高度时间局部化,哈希的均匀恰恰破坏了这种局部性。目前主流产品要么完全放弃纯哈希(如 InfluxDB、TimescaleDB),要么只在二级路由中使用(如 KaiwuDB 在 Series 层面的哈希路由)。
聊完三种策略,再深入两个容易被忽视但对性能影响极大的参数。
分片粒度指的是 单个分片覆盖的数据量或时间跨度。

产品实现对比:
- InfluxDB 的 Shard Group 默认 7 天,对于高频写入场景(如每秒百万点)这个粒度偏粗,单分片很容易膨胀到几十 GB,查询时索引无法完全缓存进内存。
- TimescaleDB 的 Chunk 可以配置得更细(比如 1 天),但配置太细又会导致元数据膨胀,需要 DBA 在粗和细之间手动权衡。
- KaiwuDB 的自适应分片机制也是为了解决这个问题:系统持续监控每个分片的写入速率和存储大小,当检测到单分片压力接近阈值时自动拆分,低峰期又自动合并。这种自调优机制降低了运维门槛,但动态调整带来的分片生命周期管理复杂度,也是一把双刃剑。
分片边界决定了 相邻分片之间的分界规则。以时间分片为例,边界可以按固定时间窗口(如每天 00:00),也可以按滑动窗口(如每 1000 万条记录)。固定边界的问题在于 时间边界处的写入热点——所有系统在 00:00 同时切到新分片,旧分片的写入瞬间归零,新分片瞬间承压。有一种优化思路是 预创建分片 \+ 写入缓冲:在边界到来前提前创建好新分片,并让写入层在边界处做短暂缓冲,平滑过渡。
当前主流产品对比:
- 大部分时序数据库(包括 InfluxDB、OpenTSDB)在分片边界处都没有做特殊处理,切分瞬间容易出现写入抖动。
- TDengine 在 vnode 层面做了预分配,但时间分片的边界问题依然存在。
- KaiwuDB 的做法是在时间窗口结束前提前创建下一个分片,并在边界处维护一个双写缓冲期(通常几秒到几十秒),让写入流量平滑迁移。这个细节对生产环境的稳定性有一定帮助,但缓冲期内的数据一致性保障机制(如双写去重)会增加写入路径的复杂度。
---
三种策略不是互斥的,很多生产系统会采用 混合分片:先按时间做一级分片,再在时间分片内部按维度或哈希做二级分片。这里我整理了几家主流数据库厂商的分片策略。

分片策略是时序数据库架构设计的根,它影响了存储格式、查询优化器、扩容机制、甚至冷热分级方案。理解三种分片策略的底层逻辑,不是为了背概念,而是为了在选型时能够:
如果你的系统还在用随便哈希一下的方式分片,而业务查询 90% 都是时间范围查询——那大概率还有很大的优化空间。
这篇写得比较干,主要是理清楚自己的思路。如果大家对某个具体策略想深入聊,或者对 KaiwuDB 的自适应分片机制、 TDengine 的 vnode 设计、 TimescaleDB 的 Chunk 调优感兴趣,可以留言,我后面可以挑几个方向单独展开测一波。
---

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70049832/viewspace-3181137/ ,如需转载,请注明出处,否则将追究法律责任。