分片

MongoDB 通过分片(sharding)支持大型数据集,分片是一种将数据分布到多个数据库服务器上的方法。请参考 MongoDB 文档 了解如何设置分片集群、其要求和限制。

Spring Data MongoDB 使用 @Sharded 注解来标识存储在分片集合中的实体,如下所示。

@Document("users")
@Sharded(shardKey = { "country", "userId" }) (1)
public class User {

	@Id
	Long id;

	@Field("userid")
	String userId;

	String country;
}
1 分片键的属性映射到实际的字段名称。

分片集合

Spring Data MongoDB 不会自动为集合设置分片,也不会为其设置所需的索引。以下代码片段展示了如何使用 MongoDB 客户端 API 来实现这一点。

MongoDatabase adminDB = template.getMongoDbFactory()
    .getMongoDatabase("admin");                                     (1)

adminDB.runCommand(new Document("enableSharding", "db"));           (2)

Document shardCmd = new Document("shardCollection", "db.users")     (3)
	.append("key", new Document("country", 1).append("userid", 1)); (4)

adminDB.runCommand(shardCmd);
1 分片命令需要针对 admin 数据库运行。
2 如果需要,请为特定数据库启用分片。
3 对已启用分片的数据库中的集合进行分片。
4 指定分片键。此示例使用基于范围的分片。

分片键处理

分片键由一个或多个属性组成,这些属性必须存在于目标集合中的每个文档中。它用于将文档分布到各个分片中。

在实体上添加 @Sharded 注解,使 Spring Data MongoDB 能够应用分片场景所需的最佳努力优化。这意味着在更新实体时,如果不存在,则会将所需的 shard 键信息添加到 replaceOne 过滤器查询中。这可能需要额外的服务器往返才能确定当前 shard 键的实际值。

通过设置 @Sharded(immutableKey = true),Spring Data 不会尝试检查实体 shard 键是否已更改。

有关更多详细信息,请参阅 MongoDB 文档。以下列表包含哪些操作有资格自动包含 shard 键

  • (Reactive)CrudRepository.save(…)

  • (Reactive)CrudRepository.saveAll(…)

  • (Reactive)MongoTemplate.save(…)