内容纲要
一. 问题现象
在 TDDMS Webserver 页面查看 Table Warnings 详情时,部分表被标记为 Unbalanced Tablet,点击shiva表名,能看到如下统计指标:
Avg = 3, Min = 0, Max = 6, Variance = 9, Variance Bound = 1

判定规则:Variance > Variance Bound(默认1) 即判定为不均衡。典型表现为:
- Min = 0:表中有空 tablet(一个字节都没有);
- Max 明显大于 Avg:个别 tablet 远超平均大小;
- 数据只集中在部分 tablet 上,其余 tablet 全空。
二. 指标是怎么算出来的
面板指标基于每个 tablet 的磁盘大小(转成整数 GiB)统计:
| 指标 | 含义 |
|---|---|
| Avg / Min / Max | 全部 tablet 平均 / 最小 / 最大大小(GiB) |
| Variance | tablet 大小的总体方差,反映 tablet 之间的差异程度 |
| Variance Bound | 均衡度阈值(配置项,默认 1),不是计算出来的 |
可以通过如下接口获取到表的tablet大小信息:
curl -u shiva:shiva -X POST ":4567/api/shiva/table/details" -d '{"database":"","tableName":""}'
示例:一张 48 tablet 的表,前 24 个各约 6.75 GiB、后 24 个为空
- Avg=(24×6+24×0)/48=144/48 = 3
- Min=0、tablet 24–47 全空
- Max=6、7247839844 / 2^30 = 6.750 → 6(最大 tablet 7280511628 → 6.78 → 6),取整后落在 6
- Variance=9、总体方差 Σ(xᵢ−μ)²/N = [24×(6−3)² + 24×(0−3)²] / 48 = 432/48 = 9(两点分布下等价于 ((Max−Min)/2)² = 9,可用来快速核验)
- 最终 Variance=9> 1,判定 Unbalanced
这里提供一个计算脚本 variance_calculate.sh,可以通过 /api/shiva/table/details 获取表的tablet大小信息,进而根据上面的计算逻辑计算出 Avg/Min/Max/Variance
# 1. 首先通过接口获取 ads.ads_cfuture_tag_record_unstructured 表的tablet大小信息,输出到 ads_cfuture_tag_record_unstructured.txt 文件
[root@kv1 ~] curl -u shiva:shiva -X POST "172.18.131.171:4567/api/shiva/table/details" -d '{"database":"default","tableName":"ads.ads_cfuture_tag_record_unstructured_9fa252bb-97b1-4a24-9f21-864512d74533"}' > ads_cfuture_tag_record_unstructured.txt
# 2. 运行脚本,计算出 Avg/Min/Max/Variance 的值
[root@kv1 ~] sh variance_calculate.sh ads_cfuture_tag_record_unstructured.txt
===== Shiva 表 tablet 均衡度 =====
输入文件 : ads_cfuture_tag_record_unstructured.txt
表健康度 : GREEN
tablet 数 : 24 副本数: 72 tabletserver: 14
逻辑大小 : 175.38 GiB 物理占用: 525.92 GiB
有数据 tablet : 10 (41.7%) 空 tablet: 14
有数据 id : 0 1 2 3 4 5 6 7 8 9
---- 面板口径:每 tablet 大小取整 GiB ----
Avg = 7
Min = 0
Max = 17
Variance = 70
Variance Bound = 1
判定: 70 > 1 => Tablets Unbalanced
三. 根因分析
3.1 分桶、分片(tablet)、磁盘的对应关系
理解该问题的前提是明确三者的固定映射关系:
- 1 个分桶的数据仅存储在 1 个分片(tablet)上,分桶与分片的对应关系固定;
- 1 个分片仅存储在 1 块磁盘上;反过来,1 块盘可以承载多个不同副本;
- 一个分区下可能有多个 tablet,一个 tablet 上可能有多份 bucket(同一个 tablet 的数据文件落在同一台物理机的同一块磁盘上)。
3.2 大小差异是怎么产生的
由上述固定映射可知:tablet 的大小 = 该 tablet 承载的所有 bucket 数据之和。因此,当出现以下情况时,tablet 大小必然产生差异:
- 分桶数 < 分片数(常见):部分 tablet 分不到任何 bucket,成为空 tablet。
- 分桶数 % 分片数 有余数(少见):各 tablet 分到的 bucket 数不一致,数据量随之拉开差距;
常见成因是:
- 客户建表时手动指定了较少的分桶数
- 建表时未指定分桶数但是当时的
tabletserver.store.datadirs磁盘数较少,后续扩容了节点或磁盘——分片数变多了,分桶数却停留在旧值,多余的 tablet 便一直是空的。
四. 为什么 table repair 和 balance 没有作用
table repair 与 balance(rebalance)操作调整的是副本在节点/磁盘之间的摆放位置,并不改变"分桶 → 分片"的数据归属。而本问题的根因是分桶数与分片数不匹配导致的数据分布倾斜——空 tablet 无论挪到哪里都是空的,超大的 tablet 挪到别的节点还是那么大。所以无论怎么 balance,Variance 都不会下降,Unbalanced 标记也无法消除。
五. 解决方案
根本手段是重建表,提高分桶数,让数据尽量分散:
- 优先推荐:重建表时使用默认分桶数,由系统按当前磁盘数自动分配;
- 或手动指定更大的分桶数(不小于分片数,且尽量能整除),使数据利用更多磁盘、tablet 大小更均匀;
六. 预防建议
- 建 Holodesk 表时不手动指定过小的分桶数,建议直接使用默认值;
- 扩容节点/磁盘后,排查存量表的"分桶数 vs 分片数"匹配情况,对不匹配的表评估重建;