方案背景——为什么要进行分区?
一是老板通Tidb集群每天涉及50+张表、2亿多条数据回流,合理使用Hash可以把写入压力打散到不同的TiKV;
二是对于大集团数据做聚合,利用分区裁剪原理,查询时可以充当前置索引,预先过滤出部分数据,加速查询效率。
分区方案
由于TiDB不支持对多列进行分区(例如:group_id + report_date),因此我们目前的解决办法是将 需要分区的字段组合成一个值,由数仓计算出,放在 partition_id 这个字段中,建表时通过partition_id分区。
通过不断探索,目前得到相对最优的公式:partition_id = (group_id * 100000000 + report_date) % 29
为什么要对29取余?
因为group_id本身不离散,因此需要把它离散掉。通过测试,发现如果对质数(素数)取余相对比较离散,而如果对非素数(10,20,128…)取余离散性较差。
参考如下:
图1是对10取余进行分区,数据回流时tidb kv999,可以看到存在热点kv,数据不离散。
图2是对29进行取余分区,数据回流时tidb kv999,可以看到无热点kv,相对均衡。
分区与不分区查询测试对比
总得来说,随着查询记录数的增多,分区表比不分区表查询效率高出30%。