文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MongoDB范围片键和哈希片键是什么

2023-06-14 07:21

关注

这篇文章给大家分享的是有关MongoDB范围片键和哈希片键是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

01 片键

    MongoDB的片键决定了集合中存储的数据在集合中的分布情况,具体的方法是使用片键值的范围来对集合中的数据进行分区。举个例子:

假如我们以年龄age来作为片键,那么age的范围理论上是0~80,此时,MongoDB会为我们定义age的四个范围区间,他们分别是:0~20,20~40,40~60,60~80,每个范围都是一个chunk,这样我们写入数据之后,数据里面的数据块就有:

chunk1:  age  0~20

chunk2:  age  20~40   

chunk3:age  40~60

chunk4:age  60~80

需要注意的是,在一个集合中,被选为片键的这个字段上必须有一个支持片键的索引,或者是必须有一个以这个字段开头的联合索引。

通常情况下,我们给字段添加的索引,最常见的是普通索引或者哈希索引,

普通的索引字段如果作为片键,那么这个片键我们称为范围片键;

哈希索引字段如果作为片键,那么这个片键我们称为哈希片键。

下面我们来看二者的不同之处:

02 范围片键(递增片键)

范围片键,顾名思义,就是将数据根据片键划分到连续的范围里面,在这个模型中,那些值"相似"的文档可能位于同一个片中。例如下面这样:

MongoDB范围片键和哈希片键是什么

这中分片方式是MongoDB默认的分片方式,它有好处也有坏处。

好处:

    可以高效的读取连续范围内的目标文档。如果你使用范围查询,则可以比较快速的拿到所有的结果值。因为数据所在的数据chunk比较少。

坏处:

    如果我们写入的数据都几种在某一个分片区间,那么读写性能都可能因为片键划分不均匀而降低。(例如下图中,数据的基数大部分在20~maxKey,则大部分都在chunk C的位置,本身分布不均匀),Chunk C的写入压力将会增大。

MongoDB范围片键和哈希片键是什么

在下列场景中,使用范围片键比较合适:

数据的基数比较大

分片的写入频率比较低(插入较少不容易产生chunk的搬运)

非单调变化的分片(如果单调写,则会分到同一个块里面,容易达到chunk割裂的条件,产生chunk的搬运)

如果数据满足上面的三个条件,则我们写入的数据可能是这样的:

MongoDB范围片键和哈希片键是什么

就是比较均匀的写入到了数据块中。

03 哈希片键

    哈希片键使用哈希索引在共享集群中对数据进行分区。哈希索引计算单个字段的哈希值作为索引值,该值用作片键(注意,这里并不是字段本身的值,而是hash之后的值)。

    使用哈希索引,我们写入数据之后,对应写入数据块的图示可能如下:

MongoDB范围片键和哈希片键是什么

从图中我们看出来,虽然我们输入的x值比较接近,分别是25、26、27,但是,经过hash函数之后,他们所在的数据块序号可能差距很远。

哈希分片在分片集群中提供了更均匀的数据分布,集合中那些具有近似值的文档,可能会被分到不同的块上,mongos更有可能执行广播操作来完成给定的范围查询。

哈希值得计算,是由MongoDB来负责的,不是应用程序负责的

作为哈希片键的索引字段应该有如下特点:

具有大量不同的值

哈希索引适合单调变化的字段,例如自增值,时间值等(因为可以将单调的字段通过hash函数映射到不同的块上去,从而分散写入压力,例如下图,虽然数据连续,但是写入了不同的数据块中)

MongoDB范围片键和哈希片键是什么

它的缺点也比较明显,当我们查询某个范围的值的时候,hash索引会查找更多的数据分片,并将最终的结果汇总起来交给我们。

在实际生产环境中,我们需要结合自己的需求来确定使用哪种类型的片键,再次强调,在设定某个字段作为片键之前,需要先在当前字段创建对应类型的索引,或者创建一个以当前字段开头的联合索引。否则设定片键的语句会报错。

下面是分片创建从无到有的过程举例:

1、创建表,只有一个字段name,并插入数据mongos> use aaaswitched to db aaamongos> db.aaa.insert({name:1})WriteResult({ "nInserted" : 1 })mongos> db.aaa.insert({name:2})WriteResult({ "nInserted" : 1 })mongos> db.aaa.insert({name:3})WriteResult({ "nInserted" : 1 })mongos> db.aaa.insert({name:4})WriteResult({ "nInserted" : 1 })mongos> 2、查看数据mongos> db.aaa.find(){ "_id" : ObjectId("5fdb7d54d91f2f9bae3b09a1"), "name" : 1 }{ "_id" : ObjectId("5fdb7d56d91f2f9bae3b09a2"), "name" : 2 }{ "_id" : ObjectId("5fdb7d59d91f2f9bae3b09a3"), "name" : 3 }{ "_id" : ObjectId("5fdb7d5cd91f2f9bae3b09a4"), "name" : 4 }3、允许数据库分片mongos> sh.enableSharding("aaa"){ "ok" : 1, "operationTime" : Timestamp(1608220038, 3), "$clusterTime" : {  "clusterTime" : Timestamp(1608220038, 3),  "signature" : {   "hash" : BinData(0,"shemm3xvSYrMiy9t7gSYcVtFUuE="),   "keyId" : NumberLong("6894922308364795934")  } }}mongos> 4、在name字段创建hash索引mongos> db.aaa.createIndex({name:"hashed"},{background:true}){ "raw" : {  "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020" : {   "createdCollectionAutomatically" : false,   "numIndexesBefore" : 1,   "numIndexesAfter" : 2,   "ok" : 1  } }, "ok" : 1, "operationTime" : Timestamp(1608220115, 3), "$clusterTime" : {  "clusterTime" : Timestamp(1608220115, 3),  "signature" : {   "hash" : BinData(0,"S3Wz9G26eJyOcwa1OLS6TVYu6SE="),   "keyId" : NumberLong("6894922308364795934")  } }}5、以name字段作为片键创建哈希分片mongos> sh.shardCollection("aaa.aaa",{name:"hashed"}){ "collectionsharded" : "aaa.aaa", "collectionUUID" : UUID("20a3895e-d821-43ae-9d28-305e6ae03bbc"), "ok" : 1, "operationTime" : Timestamp(1608220238, 10), "$clusterTime" : {  "clusterTime" : Timestamp(1608220238, 10),  "signature" : {   "hash" : BinData(0,"qeQlD3jsSvRZkyamEa2hjbezEdM="),   "keyId" : NumberLong("6894922308364795934")  } }}6、查看分片信息mongos> db.printShardingStatus()--- Sharding Status ---  sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5fafaf4f5785d9965548f687") } shards: { "_id" : "sharding_yeyz", "host" : "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020", "state" : 1 } { "_id" : "sharding_yeyz1", "host" : "sharding_yeyz1/127.0.0.1:27024,127.0.0.1:27025,127.0.0.1:27026", "state" : 1 } active mongoses: "4.0.6" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 2 Last reported error: Could not find host matching read preference { mode: "primary" } for set sharding_yeyz Time of Reported error: Wed Nov 18 2020 17:08:14 GMT+0800 (CST) Migration Results for the last 24 hours:   No recent migrations databases: { "_id" : "aaa", "primary" : "sharding_yeyz", "partitioned" : true, "version" : { "uuid" : UUID("26e55931-d1c1-4dc5-8a03-b5b0e70f6f43"), "lastMod" : 1 } }  aaa.aaa   shard key: { "name" : "hashed" }   unique: false   balancing: true   chunks:    sharding_yeyz 1   { "name" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 } } on : sharding_yeyz Timestamp(1, 0)

感谢各位的阅读!关于“MongoDB范围片键和哈希片键是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯