第 4 章 重新分片

当应用程序的数据集超出最初分配给应用程序的数据库容量时,就需要添加更多数据库,并且通常希望将数据重新分布到各个分片中(为了实现适当的负载均衡或满足应用程序的不变性) - 这被称为重新分片。重新分片是一个复杂的问题,如果在设计时没有考虑到它,它可能会给生产应用程序的管理带来重大问题。为了减轻与重新分片相关的某些痛苦,Hibernate Shards 提供了对虚拟分片的支持。

4.1. 虚拟分片

在一般情况下,每个对象都存在于一个分片上。重新分片包括两个任务:将对象移动到另一个分片,以及更改对象-分片映射。对象-分片映射通过编码到对象 ID 中的分片 ID 或对象使用的分片解析策略的内部逻辑来捕获。在前一种情况下,重新分片将需要更改所有对象 ID 和 FK。在后一种情况下,重新分片可能需要从更改给定ShardResolutionStrategy的运行时配置ShardResolutionStrategy到更改

的算法。不幸的是,一旦我们考虑到 Hibernate Shards 不支持跨分片关系,更改对象-分片映射的问题就变得更加糟糕了。此限制阻止我们将对象图的子集从一个分片移动到另一个分片。通过添加一层间接性,可以简化更改对象-分片映射的任务 - 每个对象都存在于一个虚拟分片上,每个虚拟分片都映射到一个物理分片。在设计过程中,开发人员必须确定应用程序将永远需要的物理分片的最大数量。此最大值将用作虚拟分片的数量,然后将这些虚拟分片映射到应用程序当前需要的物理分片。由于 Hibernate Shards', ShardResolutionStrategyShardSelectionStrategyShardEncodingIdentifierGenerator

都在虚拟分片上运行,因此对象将正确地分布在虚拟分片上。在重新分片过程中,现在只需更改虚拟分片到物理分片的映射,即可更改对象-分片映射。

如果您担心正确估计应用程序将永远需要的物理分片的最大数量,请尽量高估。虚拟分片很便宜。以后,您拥有额外的虚拟分片比必须添加虚拟分片要好得多。为了启用虚拟分片,您需要使用从虚拟分片 ID 到物理分片 ID 的映射创建您的ShardedConfiguration

Map<Integer, Integer> virtualShardMap = new HashMap<Integer, Integer>();
virtualShardMap.put(0, 0);
virtualShardMap.put(1, 0);
virtualShardMap.put(2, 1);
virtualShardMap.put(3, 1);
ShardedConfiguration shardedConfig =
    new ShardedConfiguration(
        prototypeConfiguration,
        configurations,
        strategyFactory,
        virtualShardMap);
return shardedConfig.buildShardedSessionFactory();

。以下是一个示例,其中我们有 4 个虚拟分片映射到 2 个物理分片。为了稍后更改虚拟分片到物理分片的映射,只需更改传递给此构造函数的virtualShardToShardMap

即可。