乐趣区

关于后端:MongoDB-分片规则

每日一句

Ideal is the beacon. Without ideal, there is no secure direction; without direction, there is no life.
现实是指路明灯。没有现实,就没有动摇的方向; 没有方向,就没有生存。

概述

对汇合进行分片时, 你须要抉择一个 片键(Shard Key), shard key 是每条记录都必须蕴含的, 且建设了索引的单个字段或复合字段,MongoDB 依照片键将数据划分到不同的 数据块 中, 并将 数据块 平衡地散布到所有分片中.

为了依照片键划分数据块,MongoDB 应用如下形式调配:

  • 基于哈希的分片形式(随机平均分配)
  • 基于范畴的分片形式(数值大小调配)

用什么字段当片键都能够,如:nickname 作为片键,但肯定是必填字段。

哈希策略

对于 基于哈希的分片 ,MongoDB 计算一个字段的哈希值, 并用这个哈希值来创立数据块.

在应用基于哈希分片的零碎中, 领有”相近”片键的文档 很可能不会 存储在同一个数据块中, 因而数据的分离性更好一些.

应用 nickname 作为片键,依据其值的哈希值进行数据分片

sh.shardCollection("articledb.comment",{"nickname":"hashed"})

范畴策略

对于 基于范畴的分片 ,MongoDB 依照片键的范畴把数据分成不同局部.

假如有一个数字的片键: 设想一个从负无穷到正无穷的直线, 每一个片键的值都在直线上画了一个点.MongoDB 把这条直线划分为更短的不重叠的片段, 并称之为 数据块 , 每个数据块蕴含了片键在肯定范畴内的数据.

在应用片键做范畴划分的零碎中, 领有”相近”片键的文档很可能存储在同一个数据块中, 因而也会存储在同一个分片中.

如应用作者年龄字段作为片键,依照点赞数的值进行分片:

sh.shardCollection("articledb.author",{"age":1})

留神

1)一个汇合只能指定一个片键,否则报错。

2)一旦对一个汇合分片,分片键和分片值就不可扭转。如:不能给汇合抉择不同的分片键、不能更新分片键的值。

3)依据 age 索引进行调配数据。

两种策略比照

基于范畴的分片形式提供了更高效的范畴查问, 给定一个片键的范畴, 散发路由能够很简略地确定哪个数据块存储了申请须要的数据, 并将申请转发到相应的分片中. 不过, 基于范畴的分片会导致数据在不同分片上的不平衡, 有时候, 带来的消极作用会大于查问性能的踊跃作用. 比方, 如果片键所在的字段是线性增长的, 肯定工夫内的所有申请都会落到某个固定的数据块中, 最终导致散布在同一个分片中. 在这种状况下, 一小部分分片承载了集群大部分的数据, 零碎并不能很好地进行扩大.

基于哈希的分片形式以范畴查问性能的损失为代价, 保障了集群中数据的平衡. 哈希值的随机性,使数据随机散布在每个数据块中, 因而也随机散布在不同分片中. 然而也正因为随机性, 一个范畴查问很难确定应该申请哪些分片, 通常为了返回须要的后果, 须要申请所有分片.

如无非凡状况,个别举荐应用 Hash Sharding。而应用 _id 作为片键是一个不错的抉择,因为它是必有的,你能够应用数据文档 _id 的哈希作为片键。

这个计划可能是的读和写都可能均匀散布,并且它可能保障每个文档都有不同的片键所以数据块可能很精密。仿佛还是不够完满,因为这样的话对多个文档的查问必将命中所有的分片。虽说如此,这也是一种比拟好的计划了。

美文佳句

一个人的自愈能力越强,才越有可能靠近幸福。做一个寡言,却心有一片海的人,不伤人害己,于恬淡中,温和自在。

你好,我是 yltrcc,日常分享技术点滴,欢送关注我的公众号:ylcoder

退出移动版