3. 分区表设计需求分析

在动手设计分区表之前,必须先回答一个更基础的问题:这张表到底要承受什么样的负载、满足什么样的服务承诺、花多少钱、留多久、由谁来维护。分区表设计不是先选分区键再补理由,而是先把业务与工程约束量化成一张需求清单,再让分区键、分区粒度、分区数量、索引策略去匹配这些数字。本节围绕写入吞吐、查询延迟、存储成本、数据生命周期与运维复杂度五个维度,说明如何把模糊的“要快、要省、要好维护”翻译成可验证的设计约束。

一、五个维度各自约束什么

写入吞吐决定分区表能否承接逐笔行情的峰值。逐笔行情具有明显的脉冲特征:开盘集合竞价、整点、尾盘往往出现数倍于均值的写入速率。需求分析时要区分日均写入行数、峰值每秒行数(TPS 意义上的行/秒)与单批写入大小。分区表在这里的关键约束是“写入放大”:每个分区都是独立物理表,若分区过多,单条写入需要定位分区、维护更多索引与元数据,批量导入时还可能因分区切换产生额外开销。因此写入吞吐约束通常表述为“峰值 X 万行/秒持续 N 分钟,单分区日均写入不超过 Y 行”。

查询延迟决定分区裁剪是否有效。逐笔行情的典型查询有两类:按证券代码加时间范围回放,以及按时间窗口做统计聚合。前者希望分区键能同时命中代码与时间,后者希望时间分区足够细以裁剪掉无关数据。需求清单里应写明 P95/P99 延迟目标、典型查询的过滤条件组合、单次查询扫描的数据量上限。若查询以“某只股票某天全部逐笔”为主,按天分区加代码索引即可;若以“全市场某分钟快照”为主,则时间粒度要更细。

存储成本约束分区粒度与副本策略。逐笔数据体量大、增长快,成本要按“原始数据量 × 副本数 × 保留期 × 单位存储价格”估算,并考虑压缩比。分区表的价值之一是按时间分区后可以对冷分区使用更低成本的存储介质或更低压缩级别,但分区过细会产生大量小文件,反而抬高元数据与对象存储请求成本。需求分析应给出年度数据增量、可接受的单位 GB 成本、冷热分层比例。

数据生命周期约束保留与归档策略。逐笔行情通常要求热数据可查数周至数月、温数据可查一年、冷数据归档备查。分区表天然适合按时间做 TTL 或分区摘除,因此需求清单要明确“热/温/冷”的边界、各层保留时长、到期后是删除还是转储、转储格式与恢复时间目标。生命周期约束会直接决定分区是按天还是按小时,以及是否需要独立的归档表。

运维复杂度约束分区数量与自动化程度。分区数量不是越多越好:分区越多,DDL、统计信息收集、备份恢复、监控告警的复杂度越高。需求分析要给出可接受的分区总数上限、每日新增分区数、是否需要自动建分区与自动清理、故障恢复时间目标。运维复杂度往往是前四个维度冲突时的“刹车”,防止为了延迟把分区切得过细。

二、把约束写成可量化清单

下面给出一份示例需求清单,参数为教学假设,用于说明字段粒度与填写方式,不代表任何真实系统的实测值。假设某逐笔行情平台日均写入 8 亿行,峰值 40 万行/秒,热数据保留 30 天,温数据保留 365 天。

维度约束项示例目标值对分区设计的影响
写入吞吐峰值写入速率40 万行/秒,持续 10 分钟单分区不宜过小,批量写入按分区聚合
写入吞吐单分区日均行数≤ 3 亿行按天分区时单分区约 8 亿行,需评估或改按小时
查询延迟单股单日回放 P99≤ 800 ms时间分区 + 代码二级索引,确保分区裁剪
查询延迟单次扫描上限≤ 5 GB分区粒度需让典型查询只命中 1~2 个分区
存储成本年度原始增量约 120 TB(压缩前)按天分区便于冷热分层与压缩策略差异化
存储成本冷热分层比例热 10%、温 60%、冷 30%冷分区可迁至低成本介质
生命周期热/温/冷保留30 天 / 365 天 / 3 年按天分区,到期整分区摘除或转储
生命周期归档恢复时间≤ 4 小时归档分区需保留可独立加载的完整边界
运维复杂度分区总数上限≤ 2000 个按天分区一年约 365 个,留出余量
运维复杂度自动建/删分区必须支持需预建未来 7 天分区,自动清理过期分区

这张表的价值在于:每一条约束都能在后续设计中找到对应的验证方法。例如“单分区日均行数 ≤ 3 亿行”与“按天分区约 8 亿行”冲突,就提示要么改按小时分区,要么接受更大的单分区并验证写入与查询是否仍达标。需求分析阶段不急着下结论,而是把冲突显性化。

三、约束之间的冲突与取舍

五个维度很少同时最优。按小时分区能改善查询裁剪和生命周期管理,但一年产生 8760 个分区,逼近甚至超过分区总数上限,运维复杂度上升;按天分区运维简单,但单分区数据量大,冷热分层粒度粗。写入吞吐希望分区少而大,查询延迟希望分区小而多,这是一对典型矛盾。合理的做法是先确定“不可妥协项”:逐笔行情通常把查询延迟和生命周期合规视为硬约束,把存储成本和运维复杂度视为可优化项,再在硬约束内寻找分区粒度的可行区间。

另一个常见冲突是索引策略。为提升按代码查询的延迟,可能在每个分区上建代码索引,但分区越多、索引总量越大,写入放大越明显。需求清单里应把“索引带来的写入开销”计入写入吞吐约束,而不是等上线后才发现峰值写入不达标。

五维需求约束 → 分区设计决策 写入吞吐 峰值行/秒 · 单分区行数 查询延迟 P99 · 扫描量 · 裁剪率 存储成本 增量 · 压缩 · 冷热分层 数据生命周期 热/温/冷 · 归档恢复 运维复杂度 分区总数 · 自动化 分区粒度决策 按天 / 按小时 / 混合 分区键:时间 + 代码 预建未来 7 天分区 过期分区自动摘除 冷分区转储归档 验证与回看 峰值写入压测是否达标 典型查询 P99 是否达标 分区总数是否超上限 冷热分层成本是否可控 归档恢复是否满足 RTO 冲突显性化示例(教学假设) · 按天分区:单分区约 8 亿行,超过“单分区 ≤ 3 亿行”约束 · 改按小时分区:一年 8760 个分区,超过“分区总数 ≤ 2000”约束 · 折中:按天分区 + 代码二级索引,或按小时分区 + 分区滚动归档 · 结论:先锁定延迟与生命周期硬约束,再优化成本与运维

四、从需求清单到设计输入

需求清单完成后,应能直接回答四个设计问题:分区键选什么、分区粒度多粗、分区总数控制在多少、索引建在哪。以本节示例为例,若最终选择按天分区,则分区键为交易日,辅以证券代码作为二级索引;分区总数按一年 365 个加预建 7 个计算,远低于 2000 上限;热分区保留 30 天,到期后先转温存储,满 365 天再转冷归档,归档前保留完整分区边界以便独立加载。若压测发现单分区 8 亿行导致查询扫描量超过 5 GB,则把时间粒度改为按小时,同时引入分区滚动归档把在线分区数压回上限以内。

需要强调的是,需求分析阶段的数字应标注来源与假设。峰值写入速率来自历史行情回放或容量规划,查询延迟目标来自服务等级约定,存储单价来自采购合同,保留期来自合规要求。凡是假设值,都应在清单中注明“待压测确认”,避免把假设当成实测结论带入后续设计。需求清单不是一次性文档,而应在每次容量变化、业务规则调整后回看更新,让分区表设计始终有据可依。

把五个维度写成“约束项 + 目标值 + 验证方法”三列,比只写目标值更有用。验证方法可以是压测脚本、查询样本集、成本估算表或分区数量统计,它决定了设计完成后如何判断是否达标。
不要用“分区越多查询越快”作为默认假设。分区过细会带来小文件、元数据膨胀和写入放大,反而可能同时恶化写入吞吐与运维复杂度。任何分区粒度决策都应以需求清单中的量化约束为准。