为什么不用取模?

节点数发生变化时,会导致很多关键字需要做节点数据迁移,会大大增加再平衡的成本。

固定数量的分区

创建远超实际节点数的分区数量,然后再为每个节点分配多个分区。

新加入节点

从现有的节点上匀走几个分区,直到分区再次达到平衡。

删除节点

采取和上面相反的过程。

优点

  • 分区总数量不变,也不会改变关键字的分区映射关系。
  • 唯一需要调整的分区与节点的映射关系。
  • 分区和节点的映射关系调整可以逐步完成。

缺点

  • 分区数量需要数据库创建时确定,并不能更改

动态分区

分区数据增长超过一个可配参数的阈值(HBase 10GB),它就拆分为两个分区,相反则合并相邻的分区。过程类似B-trees 的分裂操作。

每个分区总是分配一个节点,一个节点可以承载多个分区。

分区分裂

将其中的一半转移到其他节点以平衡负载。

优点

  • 分区数量可以自动适配数据总量。
  • 空数据库可以配置初始分区解决少量数据集就一个分区避免系统热点(HBase 和 MongoDB)

按节点比例分区

使分区数与集群节点数成正比关系(Cassandra 和 Ketama),就是每个节点具有固定数量的分区。 当节点数不变时,每个分区的大小与数据集大小保持正比增长关系。

新加入节点

随机选择固定数量的现有分区进行分裂,然后拿走这些分区的一半数据量。

优点

  • 较大的数据可以使每个分区的大小保持稳定。

缺点

  • 存在不公平分裂。