MongoDB Sharding

MongoDB Sharding使用总结 Shard Keys 切片字段的选择 切片方式的选择 查询效果的验证 Balancer Others MongoDB的Sharding机制能够让数据库系统以接近线性的方式进行扩展,非常适合具备大数据集或者高吞吐量的业务。 官方文档参考:https://docs.mongodb.com/manual/sharding/ 文档上已经写得很详细了,这里主要针对其中的几个关键点做使用总结 阅读详情

为什么需要Shard

MongoDB的Shard是一种水平分片,主要目的无非就是提高总存储空间,减少单击压力这些,提高总负载这样。

Shard的基本介绍可以参照官方文档

建立Shard集群

MongoDB Shard集群的物理结构如上图所示,主要有三种节点(这几个中文名字是本人自己定义的):路由节点(Routers),配置节点(config server),数据节点(shard)。三种节点的具体功能就不多少了,看完官方文档也差不多理解了。

上图中推荐的机器数目并非强制要求,主要是为了热备,提升性能,数据备份等。

Shard这一部分,上图所示是一个replica set,就是多机数据备份集合,结构是这样的:一个primary node,多个secondary node,还有一个arbiter(裁决节点),所有的读写操作都集中在primary node节点上,然后primary和 secondary之间会做数据同步。当primary宕机或者不可能之后,arbiter会从secondary中挑选一个成为新的primary node。arbiter不是必须的,甚至secondary也不是强制的。

Shard可以只是单台机器而非replica set

下面是本人操作的一些步骤,所有操作在一台Ubuntu虚拟机上完成:

1 启动数据节点

./bin/mongod --port 27021 --dbpath data_27021 --fork --logpath logs/27021.log
./bin/mongod --port 27022 --dbpath data_27022 --replSet test27022 --fork --logpath logs/27021.log
./bin/mongod --port 27023 --dbpath data_27023 --replSet test27023 --fork --logpath logs/27021.log

这边我启动了三个数据节点,--fork表示已后台进程的方式运行, --replSet指定了这个节点所属replica set的名称,这里有test27022和test27023两个replica set,并且每个set只有一个节点。端口27021对应的实例留作演示shard为单台机器用。

2 启动config server

./bin/mongod --configsvr --port 27024 --dbpath data_27024 --fork --logpath logs/27024.log

3 启动router

./bin/mongos --configdb localhost:27024 --port 27025 --fork --logpath logs/27021.log 

启动的时候指明config server的地址,如果有多个以,分隔。

4 配置replica set

./bin/mongo localhost:27022 #登录至replica set中任一机器

> use admin
switched to db admin

> rsconfig={_id:"test27022", members:[{_id:0, host:"localhost:27022",priority:1}]}
{
    "_id" : "test27022",
    "members" : [
        {
            "_id" : 0,
            "host" : "localhost:27022",
            "priority" : 1
        }
    ]
}

> rs.initiate(rsconfig)  #设置replica set
{
    "info" : "Config now saved locally.  Should come online in about a minute.",
    "ok" : 1
}

> rs.status() # 查看设置结果
{
    "set" : "test27022",
    "date" : ISODate("2014-11-10T14:29:52Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "localhost:27022",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 507,
            "optime" : Timestamp(1415629406, 1),
            "optimeDate" : ISODate("2014-11-10T14:23:26Z"),
            "electionTime" : Timestamp(1415629407, 1),
            "electionDate" : ISODate("2014-11-10T14:23:27Z"),
            "self" : true
        }
    ],
    "ok" : 1
}

重复上面的操作建立replica set "test27023"。

5 配置Sharding

./bin/mongo localhost:27025 #登录至router

mongos> use admin #所有操作必须在admin下进行
switched to db admin

mongos> sh.addShard("test27022/localhost:27022"); #test27022是replica set的名字,localhost:27022是该set中primary node的地址
{ "shardAdded" : "test27022", "ok" : 1 }

mongos> sh.addShard("test27023/localhost:27023");
{ "shardAdded" : "test27023", "ok" : 1 }

mongos> db.runCommand({enableSharding:"uus_test"}) #设置允许shard的DB
{ "ok" : 1 }

mongos> db.runCommand({shardCollection:"uus_test.user", key:{"userId":1}}); 
#设置允许shard的collection,及其对应的shard key,这里"userId":1 表示选择userId作为shard key,值为1表示按范围分片。
{ "collectionsharded" : "uus_test.user", "ok" : 1 }

mongos> sh.status() 
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
  shards:
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022" }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27022   1
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : { "$maxKey" : 1 } } on : test27022 Timestamp(1, 0) 

添加shard还可以用另外的命令db.runCommand({addShard:""}),至此MongoDB Sharding集群搭建完毕。

关于Shard key的选择,MongoDB会为shard key这个字段建立索引,shard key的选择很关键,对于性能会有比较大的影响,尽量使用那些选择性比较大的字段(有点类似于关系型数据库建立索引)。如果查询包含shard key则只在一个shard里面查询即可,如果不包含则需要到所有shard里面查询(大多数时候。这样会比前一种情况慢)。这方面了解的不多,可以参考这里 和 这里

修改chunk size

这是一个全局的参数。 默认是64MB。

小的chunk会让不同的shard数据量更均衡。 但会导致更多的Migration。

大的chunk会减少migration。不同的shard数据量不均衡。

这样修改chunk size。先连接上任意mongos

db.settings.save( { _id:"chunksize", value: 1 } )

单位是MB,这里修改为1M,方便插入数据之后看到多个chunk。另外可以通过在启动router的时候用参数 --chunkSize=1来指定chunk大小。

插入数据

./bin/mongo localhost:27025 #登录到router

mongos> use uus_test;
switched to db uus_test

mongos> db.user.count();
0

mongos> for(i=0;i<100000;i++){db.user.insert({"userId":i,"name":"francis", "createDate": new Date()});}  # 插入10W数据
WriteResult({ "nInserted" : 1 })

mongos> db.user.count();
100000

mongos> db.user.stats() #查看user状态
{
    "sharded" : true,
    "systemFlags" : 1,
    "userFlags" : 1,
    "ns" : "uus_test.user",
    "count" : 100000,
    "numExtents" : 12,
    "size" : 11200000,
    "storageSize" : 22364160,
    "totalIndexSize" : 6066592,
    "indexSizes" : {
        "_id_" : 3254048,
        "userId_1" : 2812544
    },
    "avgObjSize" : 112,
    "nindexes" : 2,
    "nchunks" : 11,
    "shards" : {                            # sharding信息
        "test27022" : {
            "ns" : "uus_test.user",
            "count" : 36378,
            "size" : 4074336,
            "avgObjSize" : 112,
            "storageSize" : 11182080,
            "numExtents" : 6,
            "nindexes" : 2,
            "lastExtentSize" : 8388608,
            "paddingFactor" : 1,
            "systemFlags" : 1,
            "userFlags" : 1,
            "totalIndexSize" : 2207520,
            "indexSizes" : {
                "_id_" : 1185520,
                "userId_1" : 1022000
            },
            "ok" : 1
        },
        "test27023" : {
            "ns" : "uus_test.user",
            "count" : 63622,
            "size" : 7125664,
            "avgObjSize" : 112,
            "storageSize" : 11182080,
            "numExtents" : 6,
            "nindexes" : 2,
            "lastExtentSize" : 8388608,
            "paddingFactor" : 1,
            "systemFlags" : 1,
            "userFlags" : 1,
            "totalIndexSize" : 3859072,
            "indexSizes" : {
                "_id_" : 2068528,
                "userId_1" : 1790544
            },
            "ok" : 1
        }
    },
    "ok" : 1
}

从db.user.stats()的结果可以看出来,user这个collection被sharded,数据分布在test27022和test27023两个shard上面,test27022上面有36378条数据,大小为4.07MB;test27023上面有63622条数据,大小为7.12MB。

mongos> use admin
switched to db admin

mongos> sh.status()  #查看整个shard的信息
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
  shards:
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022" }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27022   5
                test27023   6
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27022 Timestamp(2, 1) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27022 Timestamp(1, 3) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27022 Timestamp(3, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27022 Timestamp(4, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27022 Timestamp(5, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(5, 1) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27023 Timestamp(3, 4) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(4, 2) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 

上面的结果中: "shards"表示当前集群有哪些shards;"databases"列出了所有的DB,"partitioned"表示是否可以shard, "primary"表示该DB的主分区,未被sharded的collection会存储在主分区上。

然后chunks这一部分是user这个collection中数据分布的情况,从上面可以看出 user的数据在test27022中有5个chunk,在test27023中有6个chunk。

{ "userId" : 0 } -->> { "userId" : 4978 } on : test27022 Timestamp(1, 3)表示userId在[0,4987)这个区间的,存储在test27022上面, Timestamp表示什么意思我也还没搞清楚。

{ "$minKey" : 1 }和{ "$maxKey" : 1 }表示极小值和极大值。

数据分布的并不是十分平均,range shard这种方式具体是怎么样的原理,还没搞清楚。

新增shard

新增的shard可以不为空,但是不允许包含现有集群中已有的DB。这点没有具体尝试,本例中添加的是一个空的shard。

上面已经建立了一个shard集群,现在把最开始启动的localhost:27021这个实例添加进来,作为单台机器添加进来,至于replica set操作步骤一致。

./bin/mongo localhost:27025

mongos> use admin
switched to db admin

mongos> sh.addShard("localhost:27021");
{ "shardAdded" : "shard0000", "ok" : 1 }

mongos> sh.status();
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
  shards:
    {  "_id" : "shard0000",  "host" : "localhost:27021" }
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022" }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                shard0000   3
                test27022   4
                test27023   4
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : shard0000 Timestamp(7, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27022 Timestamp(7, 1) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27022 Timestamp(3, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27022 Timestamp(4, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27022 Timestamp(5, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : shard0000 Timestamp(6, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : shard0000 Timestamp(8, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

新增shard很简单,另外也可以看到新增shard之后mongoDB自动就开始同步数据了。

当chunk过多的时候(大概是超过20个), sh.status()的结果不会显示每个chunk的信息,若需要强制显示:sh.status(true);

之所以会自动同步数据是因为MongoDB有个balancer在运行,查看balancer信息:

mongos> use config
switched to db config

mongos> db.locks.find({_id: "balancer"}).pretty();
{
    "_id" : "balancer",
    "state" : 0,
    "who" : "user-VirtualBox:27025:1415629297:1804289383:Balancer:1681692777",
    "ts" : ObjectId("5460ddef20ab13caa089ccd7"),
    "process" : "user-VirtualBox:27025:1415629297:1804289383",
    "when" : ISODate("2014-11-10T15:46:55.249Z"),
    "why" : "doing balance round"
}

可以通过命令来设置balancer是否运行: sh.startBalancer(), sh.stopBalancer()。更多命令请参考官方文档

config数据库下面有这些collection:

mongos> show collections;
changelog
chunks
collections
databases
lockpings
locks
mongos
settings
shards
system.indexes
tags
version

chunks可查看每个chunk的详细信息, settings可查看系统参数,如chunkSize

移除shard

移除shard需要等待balancer将需要移除的shard上面的数据迁移到其他shards。如果移除的shard是某个DB的primary shard,则需要为该DB设置新的primary shard。

mongos> use admin
switched to db admin

mongos> db.runCommand({removeShard:"localhost:27021"})
{
    "msg" : "draining started successfully",
    "state" : "started",
    "shard" : "shard0000",
    "ok" : 1
}

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
  shards:
    {  "_id" : "shard0000",  "host" : "localhost:27021",  "draining" : true }
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022" }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27022   6
                test27023   5
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27022 Timestamp(9, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27022 Timestamp(7, 1) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27022 Timestamp(3, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27022 Timestamp(4, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27022 Timestamp(5, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(10, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27022 Timestamp(11, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

mongos> db.runCommand({removeShard:"localhost:27021"})
{
    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "shard0000",
    "ok" : 1
}

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
  shards:
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022" }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27022   6
                test27023   5
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27022 Timestamp(9, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27022 Timestamp(7, 1) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27022 Timestamp(3, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27022 Timestamp(4, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27022 Timestamp(5, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(10, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27022 Timestamp(11, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

首先db.runCommand({removeShard:"localhost:27021"}), 提示"draining started successfully",这个时候开始迁移localhost:27021上面的数据。

这个时候查看shard信息会看到localhost:27021这个shard显示"draining" : true,表明正在迁移数据。当user只存在test27022和test27023这两个shard上面的时候,表明27021以完成数据迁移。

此时再次运行db.runCommand({removeShard:"localhost:27021"}),完成shard的移除。

下面尝试移除test27022,该分区是uus_test的primary shard:

mongos> db.runCommand({removeShard:"localhost:27022"})
{
    "msg" : "draining started successfully",
    "state" : "started",
    "shard" : "test27022",
    "note" : "you need to drop or movePrimary these databases",
    "dbsToMove" : [
        "uus_test"
    ],
    "ok" : 1
}

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
  }
  shards:
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022",  "draining" : true }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27023   7
                test27022   4
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27023 Timestamp(12, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27023 Timestamp(13, 0) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27022 Timestamp(13, 1) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27022 Timestamp(4, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27022 Timestamp(5, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(10, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27022 Timestamp(11, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
  }
  shards:
    {  "_id" : "test27022",  "host" : "test27022/localhost:27022",  "draining" : true }
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27022" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27023   11
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27023 Timestamp(12, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27023 Timestamp(13, 0) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27023 Timestamp(14, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27023 Timestamp(15, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27023 Timestamp(16, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(10, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27023 Timestamp(17, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

mongos> db.runCommand({moveprimary:"uus_test", to:"localhost:27023"})  #迁移至新的primary shard
{ "primary " : "test27023:test27023/localhost:27023", "ok" : 1 }

mongos> db.runCommand({removeShard:"localhost:27022"})
{
    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "test27022",
    "ok" : 1
}

mongos> sh.status();
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 4,
    "minCompatibleVersion" : 4,
    "currentVersion" : 5,
    "clusterId" : ObjectId("5460c9f220ab13caa089c97c")
}
shards:
    {  "_id" : "test27023",  "host" : "test27023/localhost:27023" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "uus_test",  "partitioned" : true,  "primary" : "test27023" }
        uus_test.user
            shard key: { "userId" : 1 }
            chunks:
                test27023   11
            { "userId" : { "$minKey" : 1 } } -->> { "userId" : 0 } on : test27023 Timestamp(12, 0) 
            { "userId" : 0 } -->> { "userId" : 4978 } on : test27023 Timestamp(13, 0) 
            { "userId" : 4978 } -->> { "userId" : 15714 } on : test27023 Timestamp(14, 0) 
            { "userId" : 15714 } -->> { "userId" : 26181 } on : test27023 Timestamp(15, 0) 
            { "userId" : 26181 } -->> { "userId" : 36378 } on : test27023 Timestamp(16, 0) 
            { "userId" : 36378 } -->> { "userId" : 47401 } on : test27023 Timestamp(10, 0) 
            { "userId" : 47401 } -->> { "userId" : 57463 } on : test27023 Timestamp(17, 0) 
            { "userId" : 57463 } -->> { "userId" : 69238 } on : test27023 Timestamp(8, 1) 
            { "userId" : 69238 } -->> { "userId" : 80487 } on : test27023 Timestamp(4, 4) 
            { "userId" : 80487 } -->> { "userId" : 90351 } on : test27023 Timestamp(5, 2) 
            { "userId" : 90351 } -->> { "userId" : { "$maxKey" : 1 } } on : test27023 Timestamp(5, 3) 

操作步骤同移除普通的shard一样,多了移动uustest到新的primary shard的操作`db.runCommand({moveprimary:"uustest", to:"localhost:27023"})`。

其他

  • 手动移动chunk

手动移动chunk的机会很少

mongos> db.adminCommand({moveChunk: "uus_test.user", find:{userId:10}, to:"localhost:27021"})
  • 故障恢复 当集群中某个分片宕掉以后,只要不涉及到该节点的操纵仍然能进行。当宕掉的节点重启后,集群能自动从故障中恢复过来。
【MongoDB】Sharding分片概念及原理 面对海量的数据,如何提升数据读写效率?了解过DB的应该都知道数据库的分区,分区是主要提升数据查询的效率。面对海量数据的IO能力限制以及扩展性,Sharding是一个利器,我们不用关心具体的实现,从而实现性能的提升。Sharding不是一门技术,而是一个理念,解决数据的水平扩展,突破单节点的IO限制。很多成熟的NoSQL以及NewSQL就自带了sharding实现,使用者直接指定需要分片的字段,集群... 阅读详情

相关推荐

MongoDB ·sharding chunk 分裂与迁移详解

写入数据时,当 chunk 上写入的数据量,超过分裂阈值时,就会触发 chunk 的分裂,chunk 分裂后,当出现各个 shard 上 chunk 分布不均衡时,就会触发 chunk 迁移。如果使用 range 分片,因为 shardKey 的取值不确定,预分片意义不大,很容易出现部分 chunk 为空的情况,所以 range 分片只支持 hash 分片。mongoDB 的自动 chunk 分裂只会发生在 mongos 写入数据时,当写入的数据超过一定量时,就会触发 chunk 的分裂,具体规则如下。

snowyar的专栏 1673

MongoDB分片(Sharding)技术

C/C++Linux服务器开发/后台架构师知识体系整理 分片(sharding)是 MongoDB 用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法。尽管分片起源于关系型数据库分区,但 MongoDB 分片完全又是另一回事。 和 MySQL 分区方案相比,MongoDB 的最大区别在于它几乎能自动完成所有事情,只要告诉 MongoDB 要分配数据,它就能自动维护数据在不同服务器之间的均衡。 1. MongoDB分片介绍 1.1 分片的目的 高数据量和吞吐量的数据库应用会对单机的性能造成较大压力

C/C++Linux、音视频、DPDK 5924

单机环境下构建和管理 MongoDB sharding 分片集步骤

MongoDB Sharding分片简介 MongoDB sharding是一种讲海量的数据水平扩展到数据库集群系统,数据分别存储在sharding的各个节点上,使用者通简单的配置就可以很方便地构建一个分布式MongoDB集群。 MongoDB的数据分块称为 chunk 。每个chunk都是collection中一段连续的数据记录,通常最大尺寸是200MB,超出则生成新的数

yumushui的专栏 2078

Mongodb-sharding

Practical MongoDB Aggregations Book 概述 分片(sharding)是一种跨多台机器分布数据的方法, MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。 MongoDB分片群集包含以下组件: 分片(存储):每个分片包含分片数据的子集。 每个分片都可以部署为副本集。 mongos(路由):mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口 config servers(“调度”的配置):配置服务器存储群集的元数据和配置设置。 从MongoD

weixin_43394724的博客 2306

基于python+mediapipe的手势拖动识别(无gpu)

手势点方块拖动

weixin_38029956的博客 5982

MongoDB分片集群(sharded cluster)搭建过程

1.分片集群概述 MongoDB分片集群,英文名称为: Sharded Cluster 旨在通过横向扩展,来提高数据吞吐性能、增大数据存储量。 分片集群由三个组件:“mongos”, “config server”, “shard” 组成。 框架如下(图片来自mongodb官网说明): mongos:数据库请求路由。负责接收所有客户端应用程序的连接查询请求,并将请求路由到集群内部对应的分片上。...

duanbeibei的专栏 1万+

基于51单片机的简易计算器设计(原理图+仿真+源代码+参考论文)

本设计以51单片机为核心,矩阵键盘输入数字,通过1602显示屏显示计算结果,能够实现整数的加、减、乘、除四则运算,具备清除功能。

u012759563的博客 7696

实战:MongoDB 分片集群Shard Cluster 搭建(1台路由节点,3台配置节点,9台分片节点)

MongoDB 分片集群搭建 一、搭建要求 一台路由节点 IP地址:192.168.80.110 端口:11111 三套复制集(每个分片节点中的复制集 都需要有仲裁节点) IP地址: 192.168.80.55 , 端口:15555/15556/15557 IP地址: 192.168.80.56 , 端口:15555/15556/15557 IP地址: 192.168.80.57 , 端口:15555/15556/15557 一

chuanchengdabing的博客 4282

从PHY芯片看工业网络精准时钟:IEEE 1588v2(PTP)协议实现与选型指南

本文深入解析了工业网络中IEEE 1588v2(PTP)协议的实现与PHY芯片选型要点。通过对比KG7101、RTL8211F等芯片的关键参数,揭示硬件时间戳对纳秒级时钟同步的决定性作用,并提供PTP网络设计中的拓扑布局与配置优化技巧,助力工业自动化场景实现精准时间同步。

weixin_42628688的博客 500

python 爬虫 xpath 存储到数据库

参考

我是张先生 1289

MongoDB集群之分片集群 Shard Cluster

介绍了MongoDB的分片集群,以及其搭建方法。

凉茶铺的博客 2073

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4656

Mongodb中Sharding集群

随着mongodb数据量的增多,可能会达到单个节点的存储能力限制,以及application较大的访问量也会导致单个节点无法承担,所以此时需要构建集群环境,并通过sharding方案将整个数据集拆分成多个更小的chunk,并分布在集群中多个mongod节点上,最终达到存储和负载能力扩容、压力分流的作用。在sharding架构中,每个负责存储一部分数据的mongod节点称为shard(分片),shard上分布的数据块称为chunk,collections可以根据“shard key”(称为分片

u012565458的博客 1509

Avalonia+ReactiveUI跨平台路由:从零到舞者,你的UI也能跨界起舞?

至此,你已掌握了Avalonia+ReactiveUI的跨平台路由精髓!你的应用现在能够优雅地在各个界面间穿梭,就像是在不同星球间跳跃的宇宙飞船。无论是初探跨平台开发的新手,还是经验丰富的老船长,这段旅程都能让你的UI编排技能更上一层楼。现在,是时候让世界见证你的跨平台魔术了!💫记住,每一次实践都是向着完美编舞迈进的一步,勇敢地在你的项目中尝试吧!如果在航行中遇到风暴,别忘了回来看看这篇指南,或者在评论区抛出你的救生圈,我们一起解决!🌊。

java专栏 1534

基于YOLOv8深度学习的火焰与烟雾检测系统详解:UI界面 + YOLOv8 + 数据集的实现

通过自动化检测火焰和烟雾,可以提高响应速度,减少潜在的火灾损失,保障人身和财产安全。此外,应用还会显示标记了检测框的视频画面,方便用户直观了解检测效果。同时,前端界面将使用Streamlit来实现,因其可以快速搭建交互式应用,适合我们的需求。要训练一个有效的火焰和烟雾检测模型,我们需要一个包含火焰和烟雾图片的数据集。为了保证模型的准确性和泛化能力,建议收集至少500张火焰和烟雾的图片,保证数据的多样性和代表性。训练过程中,模型会输出每个Epoch的训练损失和验证准确率,便于我们监控模型的学习情况。

YOLO 1321

MongoDB学习整理之Sharding

环境准备:                      启动Shard服务器:         /app/mongo/mongodb/bin/mongod --shardsvr --port 20000 --dbpath=/app/mongo/mongodb/data/shard/s0                                         --fork -

崇尚狼性的专栏 1280

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

mongodb sharding安装的备份以及恢复

mongodb sharding安装以及备份恢复 安装机器:三个linux(centos7、x86_64)机器、mongo版本:3.2.11 安装的服务有:mongos(路由服务)2个复制集、mongoc(配置服务)3个复制集、mongod(分片服务)3个分片,每个分片都是3个复制集,总的启动9个mongod服务,如下图所示: 机器1:一个mongos、1个mongoc、3个mongod 机器2:一个mongos、1个mongoc、3个mongod 机器3:1个mongoc、3个mongod 安装开始

weixin_43737711的博客 998

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

linux 搭建mongodb sharding集群,搭建MongoDB Sharding集群

从1.6版本起,MongoDB开始正式支持Sharding同时,MongoDB也推出了Replica Sets,用以替代之前版本的Replica Pairs通过把Sharding从1.6版本起,MongoDB开始正式支持Sharding同时,MongoDB也推出了Replica Sets,用以替代之前版本的Replica Pairs通过把Sharding和Replica Sets相结合,我们可以搭...

weixin_29301059的博客 241

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

MongoDB Sharding Cluster 分片集群

将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每份数据都有相应的备份,这样就可以确保有服务器坏掉时,其他的从库可以立即接替坏掉的部分继续工作。mongos就是掌握统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。哈希索引适合单调变化的字段,例如自增值,时间值等(因为可以将单调的字段通过hash函数映射到不同的块上去,从而分散写入压力,例如下图,虽然数据连续,但是写入了不同的数据块中)

2402_88627342的博客 900

Mongodb ReplicaSet + Sharding集群实现

1 集群概述 1.1 Sharding cluster介绍 是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建monodb系统。 要构建一个 MongoDB Sharding Cluster,需要三种角色: Shard Server: mongod 实例,用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica

每天进步一点点 5812

mongodb 集群shard_mongodb sharding cluster(分片集群)

MongoDB的auto-sharding功能是指mongodb通过mongos自动建立一个水平扩展的数据库集群系统,将数据库分表存储在sharding的各个节点上。通过把Sharding和Replica Sets相结合,可以搭建一个分布式的,高可用性,自动水平扩展的集群。要构建MongoDB Sharding Cluster,需要三种角色:Shard Server: mongod 实例, 使用 ...

weixin_39602967的博客 202

Linux中mongodb复制集+sharding

(一)首先搭建一个最基础的mongodb数据库过程如下 解压压缩包 tar -zxvf mongodb-linux-x86_64-3.2.10.tgz 2.然后讲压缩包移动到/usr/local/目录下同时改名字为mongodb sudo mv mongodb-linux-x86_64-3.2.10 /usr/local/mongodb 3.此时就算是安装好了 4.然后可以开始搭建复制集...

理木客 516

MongoDB sharding

MongoDB 的 sharding 有如此强大的功能,它的实现机制是怎样的呢?下图就是 MongoDB sharding 的结构图。 从图中可以看出,MongoDB sharding 主要分为 3 大部分。shard 节点、config 节点和 config 节点。对客户端来说,直接访问的是 图中绿色的 mongos 节点。背后的 config 节点和 shard 节点是客户端不能直接访问

tycoon的专栏 665
上一篇: 创建高性能索引
下一篇: 锁的意义--MySQL加锁分析--MVCC实现简要分析
java_4_ever
博客等级 码龄16年 8粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值