• 售前

  • 售后

热门帖子
入门百科

详解MongoDB范围片键和哈希片键

[复制链接]
万胜 显示全部楼层 发表于 2021-8-14 15:13:22 |阅读模式 打印 上一主题 下一主题
目次


  • 01 片键
  • 02 范围片键(递增片键)
  • 03 哈希片键

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默认的分片方式,它有好处也有弊端。
好处:
    可以高效的读取一连范围内的目标文档。如果你利用范围查询,则可以比较快速的拿到全部的结果值。由于数据所在的数据chunk比较少。
弊端:
    如果我们写入的数据都几种在某一个分片区间,那么读写性能都大概由于片键分别不均匀而低落。(比方下图中,数据的基数大部分在20~maxKey,则大部分都在chunk C的位置,本因素布不均匀),Chunk C的写入压力将会增大。

在下列场景中,利用范围片键比较符合:
1、数据的基数比较大
2、分片的写入频率比较低(插入较少不轻易产生chunk的搬运)
3、非单调变革的分片(如果单调写,则会分到同一个块内里,轻易到达chunk割裂的条件,产生chunk的搬运)
如果数据满意上面的三个条件,则我们写入的数据大概是这样的:

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

03 哈希片键

    哈希片键利用哈希索引在共享集群中对数据进行分区。哈希索引计算单个字段的哈希值作为索引值,该值用作片键(注意,这里并不是字段本身的值,而是hash之后的值)。
    利用哈希索引,我们写入数据之后,对应写入数据块的图示大概如下:

从图中我们看出来,固然我们输入的x值比较接近,分别是25、26、27,但是,颠末hash函数之后,他们所在的数据块序号大概差距很远。
哈希分片在分片集群中提供了更均匀的数据分布,集合中那些具有近似值的文档,大概会被分到不同的块上,mongos更有大概实验广播利用来完成给定的范围查询。
哈希值得计算,是由MongoDB来负责的,不是应用步伐负责的
作为哈希片键的索引字段应该有如下特点:
1、具有大量不同的值
2、哈希索引恰当单调变革的字段,比方自增值,时间值等(由于可以将单调的字段通过hash函数映射到不同的块上去,从而分散写入压力,比方下图,固然数据一连,但是写入了不同的数据块中)

它的缺点也比较明显,当我们查询某个范围的值的时候,hash索引会查找更多的数据分片,并将终极的结果汇总起来交给我们。
在实际生产环境中,我们必要联合本身的需求来确定利用哪种类型的片键,再次夸大,在设定某个字段作为片键之前,必要先在当前字段创建对应类型的索引,大概创建一个以当前字段开头的团结索引。否则设定片键的语句会报错。
下面是分片创建从无到有的过程举例:
  1. 1、创建表,只有一个字段name,并插入数据
  2. mongos> use aaa
  3. switched to db aaa
  4. mongos> db.aaa.insert({name:1})
  5. WriteResult({ "nInserted" : 1 })
  6. mongos> db.aaa.insert({name:2})
  7. WriteResult({ "nInserted" : 1 })
  8. mongos> db.aaa.insert({name:3})
  9. WriteResult({ "nInserted" : 1 })
  10. mongos> db.aaa.insert({name:4})
  11. WriteResult({ "nInserted" : 1 })
  12. mongos>
  13. 2、查看数据
  14. mongos> db.aaa.find()
  15. { "_id" : ObjectId("5fdb7d54d91f2f9bae3b09a1"), "name" : 1 }
  16. { "_id" : ObjectId("5fdb7d56d91f2f9bae3b09a2"), "name" : 2 }
  17. { "_id" : ObjectId("5fdb7d59d91f2f9bae3b09a3"), "name" : 3 }
  18. { "_id" : ObjectId("5fdb7d5cd91f2f9bae3b09a4"), "name" : 4 }
  19. 3、允许数据库分片
  20. mongos> sh.enableSharding("aaa")
  21. {
  22. "ok" : 1,
  23. "operationTime" : Timestamp(1608220038, 3),
  24. "$clusterTime" : {
  25.   "clusterTime" : Timestamp(1608220038, 3),
  26.   "signature" : {
  27.    "hash" : BinData(0,"shemm3xvSYrMiy9t7gSYcVtFUuE="),
  28.    "keyId" : NumberLong("6894922308364795934")
  29.   }
  30. }
  31. }
  32. mongos>
  33. 4、在name字段创建hash索引
  34. mongos> db.aaa.createIndex({name:"hashed"},{background:true})
  35. {
  36. "raw" : {
  37.   "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020" : {
  38.    "createdCollectionAutomatically" : false,
  39.    "numIndexesBefore" : 1,
  40.    "numIndexesAfter" : 2,
  41.    "ok" : 1
  42.   }
  43. },
  44. "ok" : 1,
  45. "operationTime" : Timestamp(1608220115, 3),
  46. "$clusterTime" : {
  47.   "clusterTime" : Timestamp(1608220115, 3),
  48.   "signature" : {
  49.    "hash" : BinData(0,"S3Wz9G26eJyOcwa1OLS6TVYu6SE="),
  50.    "keyId" : NumberLong("6894922308364795934")
  51.   }
  52. }
  53. }
  54. 5、以name字段作为片键创建哈希分片
  55. mongos> sh.shardCollection("aaa.aaa",{name:"hashed"})
  56. {
  57. "collectionsharded" : "aaa.aaa",
  58. "collectionUUID" : UUID("20a3895e-d821-43ae-9d28-305e6ae03bbc"),
  59. "ok" : 1,
  60. "operationTime" : Timestamp(1608220238, 10),
  61. "$clusterTime" : {
  62.   "clusterTime" : Timestamp(1608220238, 10),
  63.   "signature" : {
  64.    "hash" : BinData(0,"qeQlD3jsSvRZkyamEa2hjbezEdM="),
  65.    "keyId" : NumberLong("6894922308364795934")
  66.   }
  67. }
  68. }
  69. 6、查看分片信息
  70. mongos> db.printShardingStatus()
  71. --- Sharding Status ---
  72. sharding version: {
  73. "_id" : 1,
  74. "minCompatibleVersion" : 5,
  75. "currentVersion" : 6,
  76. "clusterId" : ObjectId("5fafaf4f5785d9965548f687")
  77. }
  78. shards:
  79. { "_id" : "sharding_yeyz", "host" : "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020", "state" : 1 }
  80. { "_id" : "sharding_yeyz1", "host" : "sharding_yeyz1/127.0.0.1:27024,127.0.0.1:27025,127.0.0.1:27026", "state" : 1 }
  81. active mongoses:
  82. "4.0.6" : 1
  83. autosplit:
  84. Currently enabled: yes
  85. balancer:
  86. Currently enabled: yes
  87. Currently running: no
  88. Failed balancer rounds in last 5 attempts: 2
  89. Last reported error: Could not find host matching read preference { mode: "primary" } for set sharding_yeyz
  90. Time of Reported error: Wed Nov 18 2020 17:08:14 GMT+0800 (CST)
  91. Migration Results for the last 24 hours:
  92.   No recent migrations
  93. databases:
  94. { "_id" : "aaa", "primary" : "sharding_yeyz", "partitioned" : true, "version" : { "uuid" : UUID("26e55931-d1c1-4dc5-8a03-b5b0e70f6f43"), "lastMod" : 1 } }
  95.   aaa.aaa
  96.    shard key: { "name" : "hashed" }
  97.    unique: false
  98.    balancing: true
  99.    chunks:
  100.     sharding_yeyz 1
  101.    { "name" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 } } on : sharding_yeyz Timestamp(1, 0)
复制代码
以上就是详解MongoDB范围片键和哈希片键的详细内容,更多关于MongoDB范围片键和哈希片键的资料请关注脚本之家别的相干文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作