mongo 设置分片键

1、mongo分片集群相关知识点

mongo集群介绍:https://www.cnblogs.com/clsn/p/8214345.html

分片键的选择:https://www.cnblogs.com/lijiaman/p/14289713.html

再结合官网确认一下相关版本的规定:https://docs.mongodb.com/manual/sharding/

 

2、设置分片键

在MongoDB4.2以及4.2之前,文档的分片字段只有一个,且是不可以修改的。从4.2版本开始,除非分片键是不可变的_id字段,否则你可以更新文档的分片字段。

MongoDB4.4版本中已经可以针对复合索引字段进行哈希分片。

将一个集合设成分片集合步骤:

 

2.1、 mongo集群必须是分片集群

    一般mongo分片集群都是由mongos,各个分片复制集群组成。当外部业务直接连接到mongos服务器上,由mongos负责路由到指定分片上读取数据。

    config Server: 存储集群的配置信息

    mongod: 存储数据的节点。

    chunk :对数据进行逻辑分区,逻辑块。每个mongod上可以存储多个chunk。在创建分片键时就设置了chunk个数,可以一定程度上避免频繁后续分片分裂及迁移。

    Shard :基本就是mongod在集群里的名称,加一台机器就是加一个shard。每个shard上可以分布多个chunk。

 

2.2、设置对应集合的数据库支持分片

shell:

     use dbname

     db.adminCommand({ enablesharding:dbname })

go: 

     先访问admin数据库,再调用RunCommand接口执行以上命令即可

 

2.3、 设置collection可分片

    一旦集合设置为分片集合,则不再接受插入不分片的数据。目前mongo设置collection是不可逆的过程!!!!必须要注意设置分片键的各参数,否则后续想要修改,只能通过数据迁移完成。分片键大小限制512bytes。

 命令与上面设置数据库一样,下面看一下具体参数:

{
shardCollection: "<database>.<collection>",
key: { <field1>: <1|"hashed">, ... },
unique: <boolean>,
numInitialChunks: <integer>,     //Optional 
presplitHashedZones: <boolean>,    //Optional
collation: { locale: "simple" }    //Optional
}

key字段:1表示按照范围划分分片,通常能很好地支持基于片键的范围查询;hashed表示按照哈希划分分片,通常能将写入均衡分布到各Shard节点中。需要注意的是如果表内已有数据了,则必须先建立对应的索引,比如1时就需要先建普通升序索引,hash就需要先建哈希索引。如果是空表,则创建分片时会默认创建。

unique字段:unique是指分片键的唯一性。在分片数据库里,是没法全局保证唯一索引的,只有分片键可以设置全局唯一,所以可以在比较符合业务特性时,可以考虑把需要唯一性的字段设置为分片键。分片键设置为unique则只能采用按照范围划分分片,不能用哈希分片方式。

numInitialChunks:当表是空的时,可以直接分好区,避免后续再频繁分区,只支持对哈希方式进行设置;设成按照范围划分默认1个分区,按照哈希划分默认6个。

eg:

  比如testdb下test表,对其name字段进行设置分片
  db.adminCommand({ shardcollection: "testdb.test", key: { name: 1 } }) 
  db.adminCommand({ shardcollection: "testdb.test", key: { name: 1 },unique:true })
  db.adminCommand({ shardcollection: "testdb.test", key: { name: "hashed" } })
  db.adminCommand({ shardcollection: "testdb.test", key: { name: "hashed" },numInitialChunks:9 })

 

3、常用命令

db.printShardingStatus()
可以查看集群的分片情况,以及各表各分片键设置情况

sh.isBalancerRunning("testdb.test") 
   是否正在迁移分片
sh.enableBalancing("testdb.test")
   开启可以迁移分片; 默认是开启可以迁移分片的
sh.disableBalancing("testdb.test")
   关闭迁移分片,比如在修改配置时,可以先关闭分片

db.getCollection("test").getShardDistribution()
   查看chunks个数以及大小,以及其在shard上的分布情况

use config
db.settings.save({_id:"chunksize",value:1}) //单位MB
设置chunk块大小

 

4、关于检查表是否已分片问题

通过db.printShardingStatus()可以查看表是否已分片,但官网特别说明这是个手动执行的命令,只可以在shell中执行。

比如想通过mongo的某种语言driver执行,是没有这个命令的!!!!!比如go的RunCommand是没有这个命令的。这个问题我在网上查找了很多,发现java/python driver都有这个问题.。

但是我自己查找后,在config数据库下的collections表里找到这个信息,所以我尝试用这种方法:

use config
db.getCollection("collections").find({"_id":"testdb.test","dropped": false }) 
输出:
{
    "_id": "testdb.test",
    "lastmodEpoch": ObjectId("606fb2bd1aeb26f18dd6b51e"),
    "lastmod": ISODate("1970-02-19T17:02:47.296Z"),
    "dropped": false,
    "key": {
        "shard": 1
    },
    "unique": false,
    "uuid": UUID("5e2a37a0-dd1c-4f8f-acc3-f765418bf804"),
    "noBalance": true
}

但是这种做法是否有风险,还存有疑惑。否则各类驱动为何不支持这个命令。如果大家有答案,欢迎在评论下留言,共同探讨。


版权声明:本文为yshhuan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。