
# 分区分桶数量和数据量规范
#### 关于Partition和Bucket的数量和数据量的建议
- 一个表的Tablet总数量等于 (Partition num\*Bucket num)。
- 一个表的Tablet数量，在不考虑扩容的情况下，推荐略多于整个集群的磁盘数量。
- 单个Tablet的数据量理论上没有上下界，但建议在100M-3G的范围内。如果单个Tablet数据量过小，则数据的聚合效果不佳，且元数据管理压力大。如果数据量过大，则不利于副本的迁移、补齐，且会增加Schema Change或者Rollup操作失败重试的代价（这些操作失败重试的粒度是Tablet）。
- 当Tablet的数据量原则和数量原则冲突时，建议优先考虑数据量原则。
- 在建表时，每个分区的Bucket数量统一指定。但是在动态增加分区时（ADD PARTITION），可以单独指定新分区的Bucket数量。可以利用这个功能方便的应对数据缩小或膨胀。
- 一个Partition的Bucket数量一旦指定，不可更改。所以在确定Bucket数量时，需要预先考虑集群扩容的情况。比如当前只有3台host，每台host有1块盘。如果Bucket的数量只设置为3或更小，那么后期即使再增加机器，也不能提高并发度。
- 举一些例子：假设在有10台BE，每台BE一块磁盘的情况下。如果一个表总大小为500MB，则可以考虑4-8个分片。5GB：8-16个分片。50GB：32个分片。500GB：建议分区，每个分区大小在50GB左右，每个分区16-32个分片。5TB：建议分区，每个分区大小在50GB左右，每个分区16-32个分片。
 
#### 关于Random Distribution的设置以及使用场景
- 如果OLAP表没有更新类型的字段，将表的数据分桶模式设置为RANDOM，则可以避免严重的数据倾斜（数据在导入表对应的分区的时候，单次导入作业每个batch的数据将随机选择一个tablet进行写入）。
- 当表的分桶模式被设置为RANDOM时，因为没有分桶列，无法根据分桶列的值仅对几个分桶查询，对表进行查询的时候将对命中分区的全部分桶同时扫描，该设置适合对表数据整体的聚合查询分析而不适合高并发的点查询。
- 如果OLAP表的是Random Distribution的数据分布，那么在数据导入的时候可以设置单分片导入模式（将load_to_single_tablet设置为true），那么在大数据量的导入的时候，一个任务在将数据写入对应的分区时将只写入一个分片，这样将能提高数据导入的并发度和吞吐量，减少数据导入和Compaction导致的写放大问题，保障集群的稳定性。
 
#### 复合分区与单分区
- 复合分区。
  - 第一级称为Partition，即分区。用户可以指定某一维度列作为分区列（当前只支持整型和时间类型的列），并指定每个分区的取值范围。
  
  - 第二级称为Distribution，即分桶。用户可以指定一个或多个维度列以及桶数对数据进行HASH分布或者不指定分桶列设置成Random Distribution对数据进行随机分布。
   
![](https://support.huaweicloud.com/devg-cloudtable/public_sys-resources/note_3.0-zh-cn.png)
此场景推荐使用复合分区。
- 有时间维度或类似带有序值的维度，可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。
- 历史数据删除需求：如有删除历史数据的需求（比如仅保留最近N天的数据）。使用复合分区，可以通过删除历史分区来达到目的。也可以通过在指定分区内发送DELET语句进行数据删除。
- 解决数据倾斜问题：每个分区可以单独指定分桶数量。如按天分区，当每天的数据量差异很大时，可以通过指定分区的分桶数，合理划分不同分区的数据，分桶列建议选择区分度大的列。
 
- 单分区。 用户也可以不使用复合分区，即使用单分区。则数据只做Hash分布。
  
 
