OPTIONS
翻译或纠错本页面

片键

片键决定了集群中一个集合的 documents 在不同 shards 中的分布.片键字段必须被索引,且在集合中的每条记录都不能为空,可以是单个字段或复合字段.

MongoDB使用片键的范围把数据分布在分片中,每个范围,又称为数据块,定义了一个不重叠的片键范围,MongoDB把数据块与他们存储的文档分布到集群中的不同分片中.

Diagram of the shard key value space segmented into smaller ranges or chunks.

Diagram of the shard key value space segmented into smaller ranges or chunks.

当一个数据块的大小超过 数据块最大大小 时,MongoDB会依据片键的范围将数据块 分裂为 更小的数据块.

注意事项

片键在写入后不能被改变,参见 集合的限制 以获取更多信息.

片键上的索引 不能多键索引

哈希片键

2.4 新版功能.

哈希片键使用单字段上的 哈希索引 进行数据在分片之间的分发.

被选为片键的字段必须有足够大的基数,或者足够多的不同的值,对于单调递增的字段,如 ObjectId 或者时间戳,哈希索引效果更好.

如果在一个空的集合创建哈希片键,MongoDB会自动创建并迁移数据块,以保证每个分片上都有两个数据块,你可以在执行 shardCollection 指定 numInitialChunks 参数以控制初始化时MongoDB创建的数据块数目,或者手动调用 split 命令在分片上分裂数据块.

要在集合上使用哈希片键,参见 使用哈希片键对集合分片 .

小技巧

对使用了哈希片键分片的集合进行请求时,MongoDB会自动计算哈希值,应用方 不需要 解析哈希值.

片键对集群操作的影响

片键可以影响数据在分片间的分布,也影响 mongos 对集群直接操作的效率,因此可以影响集群的读写性能, 可以考虑以下的操作受片键的影响.

写扩展

一些片键会使应用程序能够达到集群能够提供的最大的写性能,有一些则不能,比如使用默认的 _id 做片键的情况.

在插入文档时,MongoDB会生成一个全局唯一的 ObjectId 标识符_id,不过,需要注意的一点是, 这个标识符的前几位代表时间戳,这意味着_id是以常规的并且可预测的方式增长,即使_id有 大的基数 ,在使用 _id或者任意其他单调递增的数据 作为片键时,所有的写入操作都会集中到一个分片中

不过,如果你的写入频率很低或者大多都是 update() 操作,单调递增的片键不会对性能有很大影响,一般来说,选择的片键要 同时 具有较大的基数与将请求分布在整个集群中两个特性.

通常,一个经过计算的片键会有一定的”随机性”,比如一个包含了其他字段加密哈希(例如 MD5或者SHA1)的片键,会使集群具有较好的写扩展性能.不过,随机的片键通常不会提供 查询隔离 的特性,而查询隔离同样是片键一个很重要的特性.

2.4 新版功能: MongoDB可以使用哈希片键为数据库分片,哈希片键提供了较好的写扩展性能,参见 使用哈希片键对集合分片 获得更多细节.

查询

The mongos provides an interface for applications to interact with sharded clusters that hides the complexity of data partitioning. A mongos receives queries from applications, and uses metadata from the config server, to route queries to the mongod instances with the appropriate data. While the mongos succeeds in making all querying operational in sharded environments, the shard key you select can have a profound affect on query performance.

参见

参见文档 集群的查询路由分发 与文档 配置服务器 部分以获得关于集群环境概览与查询的详细信息.

查询隔离

mongos根据查询条件中的片键与 配置服务器 的元信息做对比决定查询被发往哪些分片,集群中最快的查询是那些被发往单个分片的查询,对于那些不带片键的查询, mongos 必须把查询发往所有的分片,等待所有分片都返回数据后处理完成后再发给应用,这种”分发/聚合”查询有可能耗费大量的时间.

如果你的查询包含了片键或者片键的前缀字段 [1], mongos 可以将请求直接分发到单个或较少数量的分片中,这会提供较好的性能.即使你的查询所需要的数据分布在不同的数据块中, program:mongos 也可以直接将请求发往正确的分片.

为集合选择一个好的片键

  • 在给定的应用中,确定一个查询中最常见的字段.

  • 确认这些操作中哪个对性能依赖最严重.

如果这个字段基数比较低(即没有足够的选择性),你需要添加第二个字段,构成复合字段片键,在使用复合片键时,数据可以被更好地分离.

注意

集群的查询路由分发 for more information on query operations in the context of sharded clusters.

[1]

从很多方面来说,你可以认为片键是集群尺度上的唯一索引.不过,需要注意的是,在集群中, 除非 你的唯一索引包含了片键,否则不能确保索引的唯一性.参见 索引概念 查看索引以及复合索引的信息.

排序

在集群中, mongos 对从所有分片返回的数据进行合并排序,参见 集群的查询路由分发使用索引来排序查询结果 以获得更多信息.