MongoDB 分片管理

发布时间:2018-11-19  栏目:NoSQL  评论:0 Comments

Mongodb版本:3.6 

于MongoDB(版本 3.2.9)中,分片集群(sharded
cluster)是同等栽档次扩展数据库系统特性的道,能够用数据集分布式存储在不同之分片(shard)上,每个分片只保留数据集的均等有些,MongoDB保证各个分片之间未会见出重的数码,所有分片保存之多少的与不畏是整的多寡集。分片集群将数据集分布式存储,能够用负载分摊至差不多独分片上,每个分片只当读写有数码,充分利用了一一shard的系统资源,提高数据库系统的吞吐量。

一律、分片概念

数集被拆分成据块(chunk),每个数据块包含多只doc,数据片分布式存储在分片集众多中。MongoDB负责追踪数据块当shard上之布信息,每个分片存储哪些数据块,叫做分片的老大数据,保存于config
server上之数据库 config中,一般以3令config server,所有config
server中之config数据库必须完全相同。通过mongos能够一直看数据库config,查看分片的首位数据;mongo
shell 提供 sh 辅助函数,能够安全地翻看分片集群的正负数据信息。

1.数据块

片呢给区间,可能在一分片如出一辙间隔与一分片大抵间距两栽情况。

无异于分片一距离:多少未会见以切除里自动移动来保持分片的多少的均匀性,需要手动拆分分片来走数据。

倘一分片大多距离情况:一个数码块默认64MB,当数块及64MB时即会创造新的丘,当然前提是当前之粒度还同意再次拆分,平衡器会保证每个分片数据块的均。但是运动块啊随分片的极,块之间的数量集不克产生交集。

以一个片[50-100)现在拆分成稀只片,那么默认会拆分成[50-75)[75-100)两单片,如果手上分片块比任何分片的块大于9那可能[75-100)改块会于挪及新的分片当中。

图片 1

2.平衡器

平衡器(balancer)负责数据的迁。它见面周期性地检查分片间是否存在未抵,如果有,则会打开块的迁徙。不平衡的展现指,一个分片明显比较其他分片拥有双重多之丘。假如发生部分汇聚达到了阈值,平衡器则会初步做块迁移。它会打负载比较比老的分片中摘一个片,并了解该分片是否要以搬之前对块进行拆分。完成必要之拆分后,就会见拿片迁移至数据较少的机器上。

针对其他一个shard进行询问,只见面获collection在当前分片上之多少子集,不是漫天数据集。Application
只需要连接到mongos,对那进展的读写操作,mongos自动将读写请求路由到相应的shard。MongoDB通过mongos将分片的最底层实现对Application透明,在Application看来,访问的凡一体数据集。

其次、分片查询

一,主分片

1.询问群集状态

sh.status

需要展示隐藏的分片信息实行

sh.status(true)

在分片集众多被,不是每个集合都见面分布式存储,只有采取sh.shardCollection()显式将collection分片后,该集才会分布式存储在不同的shard中。对于非分片集合(un-sharded
collection),其数额只是见面蕴藏于主分片(Primary
shard)中,默认情况下,主分片是因数据库最初创建的shard,用于存储该数据库中非分片集合的数目。每个数据库都发一个主分片。

2.检查部署信息

负有的配备信息都封存在配备服务器的config数据库中。

use config

show tables

图片 2

actionlog

记录平衡器的相干操作日志。

changelog

跟记录集群的操作,包括集合分片操作、块拆分和迁移、添加删减分片等。例如块拆分信息:

db.getCollection('changelog').find({"what":/split/}).sort({"time":-1}).limit(2)

历次数据库块移动还见面创造插入4长记下及changelog文档总,分别是start、commit、from、to

图片 3图片 4

{

    "_id" : "backup-2018-04-09T15:52:26.656+0800-5acb1bbaebfa528b3521327c",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:26.656Z"),

    "what" : "moveChunk.start",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "from" : "rs-b",

        "to" : "rs-a"

    }

}



/* 2 */

{

    "_id" : "backup-2018-04-09T15:52:29.289+0800-5acb1bbdebfa528b35213335",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:29.289Z"),

    "what" : "moveChunk.commit",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "from" : "rs-b",

        "to" : "rs-a"

    }

}



/* 3 */

{

    "_id" : "backup-2018-04-09T15:52:29.297+0800-5acb1bbdebfa528b3521333a",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:29.297Z"),

    "what" : "moveChunk.from",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "step 1 of 6" : 0,

        "step 2 of 6" : 10,

        "step 3 of 6" : 153,

        "step 4 of 6" : 2061,

        "step 5 of 6" : 402,

        "step 6 of 6" : 24,

        "to" : "rs-a",

        "from" : "rs-b",

        "note" : "success"

    }

}



/* 4 */

{

    "_id" : "master-2018-04-09T15:52:29.307+0800-5acb1bbd7bc60438ea626411",

    "server" : "master",

    "clientAddr" : "",

    "time" : ISODate("2018-04-09T07:52:29.307Z"),

    "what" : "moveChunk.to",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "step 1 of 6" : 22,

        "step 2 of 6" : 11,

        "step 3 of 6" : 4,

        "step 4 of 6" : 0,

        "step 5 of 6" : 2042,

        "step 6 of 6" : 373,

        "note" : "success"

    }

}

View Code

details字段中之各级一样步表示的还是时,”step N of
6″信息为毫秒为单位出示步骤耗时的长度。

当from分片收到mongos发来之moveChunks命令时,它见面举行如下操作:

(1).检查命令参数;

(2)向配置服务器申请获得一个分布锁,以便进入迁移过程;

(3)尝试连接至to分片;

(4)复制数据

(5)与to分片和布置服务器一起确认迁移是否成就。

当to分片收到from分片发来之命时,它见面执行如下操作:

(1)迁移索引;

(2)删除块范围外曾是的另数;

(3)将片被的有所文档复制到to分片;

(4)在to分片上运行复制期间针对这些文档所执行了之操作;

(5)等待to分片将迁移过来的数据复制到符合本集的多数服务器上。

(6)标志迁移是否履行成功。

chunks

存储集合分片所有片信息

collections

笔录有分片集合信息,该记录着之笔录不会见因为分片集合被剔除而吃破除。

databases

图片 5

记录集众多中数据库的信,不管数据库有无发分片。如数据库被了分片,那么”partitioned”
:字段的值也true。”primary”记录数据库所属的主分片。所有新集默认创建以数据库主分片上。比如当前的集聚在某分片上面还没多少那么非会见以拖欠分片上缔造集合。所以只要有分片存在分片的联谊,那么要用聚集的数额移走或者将集删除,否则该分片无法抹。

lockpings

笔录分片运行是否正常的ping记录信息

locks

记录存储分布式锁操作信息。

migrations

mongos

记录mongos的系信息,记录每一个mongos实例的音讯。

settings

富含平衡器和片的装信息相当。

shards

群集分片信息

tags

笔录分片标签信息

transactions

version

群集版本信息

专注:如果需要改配置信息,需要经过连日至mongos切换至config数据库操作而未是一直连接至布置服务器遭受操作。

参考:https://docs.mongodb.com/manual/reference/config-database/

Each database in a
sharded cluster has a primary shard that holds all the un-sharded
collections for that database. Each database has its own primary
shard. 

3.查网络连接

db.adminCommand({"connPoolStats":1})

比如,一个分片集群有三独分片:shard1,shard2,shard3,在分片shard1创建一个多少库blog。如果用数据库bolg分片,那么MongoDB会自动在shard2,shard3达成开创一个结构同样之数库blog,数据库blog的Primary
Shard是Shard1。

4.限制连接数量

--maxConns 

mongos可领的极其充分并发连接数。如果这个设置过操作系统配置的卓绝可怜连接跟踪阈值,则这设置无效。

只顾:在本2.6遭MongoDB删除了maxIncomingConnections 设置的上限。

图示,Collection2的主分片是ShardA。

其三、分片管理

图片 6

1.添加分片

use admin

db.auth("dba","dba")

sh.addShard("rs-a/192.168.137.10:27010,192.168.137.10:27011,192.168.137.10:27012");

sh.addShard("rs-b/192.168.137.20:28010,192.168.137.20:28011,192.168.137.20:28012");

sh.addShard("rs-c/192.168.137.30:26010,192.168.137.30:26011,192.168.137.30:26012");

sh.status();

使用 movePrimary命令变更数据库默认的Primary
shard,非分片集合将会从当下shard移动至新的主分片。

2.刨除分片

事先当前分片对应数据库挪到其他的分片上。这里的”products”指的凡数额库名

db.runCommand( { movePrimary: "products", to: "rs-b" })

``然后再删除分片

db.runCommand({"removeShard":"rs-c"});

图片 7

 图片 8

留神:需要反复尽db.runCommand({“removeShard”:”rs-c”});命令来删除分片,首先平衡器会将分片上之数量进行搬迁,可以透过sh.isBalancerRunning()命令查询是否搬迁完成,迁移完成以后再度实施删除分片命令彻底移除分片。

图片 9

db.runCommand( { movePrimary : "test", to : "shard0001" } )

3.平衡器管理

3.1开启平衡器

use admin
sh.startBalancer()
或者
sh.setBalancerState(true)

3.2闭馆平衡器

use admin
sh.stopBalancer()
或者
sh.setBalancerState(false);

翻是否关闭,返回flase标识平衡器已关门,还用查询均衡器正在运转情况

sh.getBalancerState();

while( sh.isBalancerRunning() ) {

          print("waiting...");

          sleep(1000);

}

当实行数据库管理操作前应当关闭平衡器,关闭平衡器之后,系统不会见再度进入平衡过程,
但是均衡器的关不是当时就好,所以还亟需查询均衡器是否正在运行.

3.3查平衡器开启状态

db.settings.find({"_id":"balancer"})
或者
sh.getBalancerState()

3.4翻平衡器是否在运转

sh.isBalancerRunning()

回到ture代表正运行,false代表时没当运行。

3.5点名平衡时

务必先行保证平衡器是翻开状态

use config
sh.setBalancerState( true )

db.settings.update({"_id":"balancer"},
{"$set":{"activeWindows":{"start":"13:00","stop":"16:00"}}},
{upsert:true}
)
  • For HH values, use hour values ranging from 00 – 23.
  • For MM value, use minute values ranging from 00 – 59.

3.6关门平衡时

use config

db.settings.update({ _id : "balancer" }, { $unset : { activeWindows : true } })

3.7关开启指定文档的平衡器

关闭

sh.disableBalancing("test.aa")

开启

sh.enableBalancing("test.aa")

询问是否关闭文档的平衡器,返回true代表关闭。没有结果返回没有停歇,返回报错代表文档不在或者文档没有被分片

db.getSiblingDB("config").collections.findOne({_id : "test.aa"}).noBalance;

3.8.备份时注意事项

于推行备份前要关闭平衡器,但是均衡器的关不是当下就好,所以还待查询均衡器是否正在运作,不要当平衡器处于活动状态时备份,可以备份操作前履行以下查询:

sh.getBalancerState()

sh.isBalancerRunning()

专注:保证平衡器处于关闭状态又sh.isBalancerRunning()返回的莫是ture
;也得通过安装平衡器的平衡时来保安备份。

参考:https://docs.mongodb.com/manual/tutorial/manage-sharded-cluster-balancer/

于使用movePrimary命令变更数据库的主分片之后,config
server中之部署信息是时髦的,mongos缓存的布置信息易得过时了。MongoDB提供命令:flushRouterConfig
强制mongos从config server获取最新的安排信息,刷新mongos的缓存。

4.块管理

db.adminCommand({"flushRouterConfig":1})

1.修改数据片大小

单位MB,默认块大小为64MB。块越大迁移至分片的耗时就越长。

use config;
查询当前块大小
db.settings.find({"_id":"chunksize"})
修改块大小
db.settings.save( { _id:"chunksize", value: 64 } );

亚,分片的长数据

2.手动移动数据块

2.1查询文档块信息

db.getCollection('chunks').find({"ns":"test.xxxx"})

图片 10

2.2用片”$minKey”移动及分片rs-c上

运动块就待指定块的归来外之无论一个价即可,注意块的限量未包含上限。

sh.moveChunk("test.xxxx",{"username":"$minKey"},"rs-c")

图片 11

 

图片 12

2.3拆分块

若块的尺寸超过setting设置的不过酷块大时,系统会禁止移动块,这时候要用片进行拆分。这里需要指定新的片范围,指定下限即可。

图片 13

 

sh.splitAt("test.xxxx",{ "username" :"p" })

图片 14

2.4查询块的尺寸

db.runCommand({ dataSize: "test.xxxx", keyPattern: { "username": 1 }, min: { "username" : "b" }, max: { "username" : "c" } })

单位字节,需要指定块的限定。

2.5无法拆分的巨块拍卖

假设以year/month/day字段作为分片,某平龙工作被攻击造成这天的数据量暴增,但是由分片的价都的极致小单位了无法再拆分了,这个时节经过块拆分已经力不从心解决问题,可以手动将片移动至无热门的分片上。

甭一直到config
server上查看分片集群的初次数据信息,这些数量好重要,安全之计是经过mongos连接到config数据查看,或者使用sh辅助函数查看。

5.刷新配置信息

mongos有时无法从部署服务器是更新配备信息,可以采取flushRouterConfig命令手动刷新缓存,如果刷新还无法化解要再次开mongos进程。

db.adminCommand({"flushRouterConfig":1})

采取sh辅助函数查看

6.剔除分片数据库

use news

db.dropDatabase()

 

 

 

 

 

 

 

 

备注:

    作者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接,否则保留追究责任的权利。

《欢迎交流讨论》

 

sh.status()

连续到mongos查看config数据库被之集合 

mongos> use config

1,shards 集合保存分片信息

db.shards.find()

shard的数目存储于host指定的 replica set 或 standalone mongod中。

{
    "_id" : "shard_name",
    "host" : "replica_set_name/host:port",
    "tag":[shard_tag1,shard_tag2]  
}

2,databases集合保存分片集众多中负有数据库的信,不管数据库是否分片

db.databases.find()

假若在数据库及实施sh.enableSharding(“db_name”),那么字段partitioned字段值就是true;primary
字段指定数据库的主分片(primary shard)。

{
    "_id" : "test",
    "primary" : "rs0",
    "partitioned" : true
}

3,collections集合保存有曾经分片集合的音讯,不包非分片集合(un-sharded
collections)

key是:分片的片键

db.collections.find()

{
    "_id" : "test.foo",
    "lastmodEpoch" : ObjectId("57dcd4899bd7f7111ec15f16"),
    "lastmod" : ISODate("1970-02-19T17:02:47.296Z"),
    "dropped" : false,
    "key" : {
        "_id" : 1
    },
    "unique" : true
}

4,chunks 集合保存数据片信息,

ns:分片的集合,结构是:db_name.collection_name

min 同 max: 片键的极端小值和极致大值

shard:块所于的分片 

db.chunks.find()

{
    "_id" : "test.foo-_id_MinKey",
    "lastmod" : Timestamp(1, 1),
    "lastmodEpoch" : ObjectId("57dcd4899bd7f7111ec15f16"),
    "ns" : "test.foo",
    "min" : {
        "_id" : 1
    },
    "max" : {
        "_id" : 3087
    },
    "shard" : "rs0"
}

5,changelog集合记录分片集群的操作,包括chunk的拆分和迁移操作,Shard的增或者删除操作

what 字段:表示操作的品种,例如:multi-split表示chunk的拆分,

"what" : "addShard",
"what" : "shardCollection.start",
"what" : "shardCollection.end", 
"what" : "multi-split",

6,tags 记录shard的tag和相应的片键范围

{
    "_id" : { "ns" : "records.users", "min" : { "zipcode" : "10001" } },
    "ns" : "records.users",
    "min" : { "zipcode" : "10001" },
    "max" : { "zipcode" : "10281" },
    "tag" : "NYC"
}

7,settings 集合记录均衡器状态和chunk的轻重,默认的chunk size是64MB。

{ "_id" : "chunksize", "value" : 64 }

{ "_id" : "balancer", "stopped" : false }

8,locks 集合记录分布锁(distributed lock),保证单独来一个mongos
实例能够当分片集众多中履行管理职责。

mongos在出任balancer时,会获得一个分布锁,并为config.locks中插入一长达doc。

The locks collection stores a distributed
lock. This ensures that only one mongos instance can perform
administrative tasks on the cluster at once. The mongos acting as
balancer takes a lock by inserting a document resembling the following
into the locks collection.

{
    "_id" : "balancer",
    "process" : "example.net:40000:1350402818:16807",
    "state" : 2,
    "ts" : ObjectId("507daeedf40e1879df62e5f3"),
    "when" : ISODate("2012-10-16T19:01:01.593Z"),
    "who" : "example.net:40000:1350402818:16807:Balancer:282475249",
    "why" : "doing balance round"
}

老三,删除分片

去除分片时,必须管该分片上的数量让挪到外分片中,对于以平分秋色的集聚,使用均衡器来搬迁数据块,对于非分片的聚集,必须修改集合的主分片。

1,删除已分片的集数据

step1,保证均衡器是敞开之

sh.setBalancerState(true);

step2,将都分片的聚众全搬到另外分片

use admin
db.adminCommand({"removeShard":"shard_name"})

removeShard命令会将数据块从眼前分片上迁移至其他分片上去,如果分片上的数据块比较多,迁移过程也许耗时非常丰富。

step3,检查数据块迁移的状态

use admin
db.runCommand( { removeShard: "shard_name" } )

应用removeShard命令能查阅数据块迁移的状态,remaining
字段表示剩余数据块的多少

{
     "msg" : "draining ongoing",
    "state" : "ongoing",
    "remaining" : {
        "chunks" : 42,
        "dbs" : 1
    },
    "ok" : 1
}

step4,数据块好搬迁

use admin
db.runCommand( { removeShard: "shard_name" } )

{
    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "shard_name",
    "ok" : 1
}

2,删除不分片的数据库

step1,查看未分片的数据库

非分片的数据库,包括个别有:

  • 数据库未被一分为二,该数量没有运用sh.enableSharding(“db_name”),在数据库config中,该数据库的partitioned字段是false
  • 数据库被留存collection未受一分为二,即当前底分片是欠集的主分片

    use config
    db.databases.find({$or:[{“partitioned”:false},{“primary”:”shard_name”}]})

对此partitioned=false的数据库,其数据全保留于现阶段shard中;对于partitioned=true,primary=”shard_name“的数据库,表示在不分片(un-sharded
collection)存储在拖欠数据库中,必须变更这些聚集的主分片。

step2,修改数据库的主分片

db.runCommand( { movePrimary: "db_name", to: "new_shard" })

季,增加分片

由分片存储的凡数据集的相同片段,为了保证数据的高可用性,推荐下Replica
Set作为shard,即使Replica
Set中独含有一个成员。连接至mongos,使用sh辅助函数增加分片。

sh.addShard("replica_set_name/host:port")

免推荐用standalone mongod作为shard

sh.addShard("host:port")

五,特大块

于小情况下,chunk会频频增高,超出chunk size的范围,成为特大块(jumbo
chunk),出现特大块的由来是chunk中之装有doc使用及一个片键(shard
key),导致MongoDB无法拆分该chunk,如果该chunk持续增强,将会见促成chunk的分布不统匀,成为性瓶颈。

于chunk迁移时,存在限制:每个chunk的尺寸不可知跳2.5万久doc,或者1.3倍增于配置值。chunk
size默认的配置值是64MB,超过限制的chunk会吃MongoDB标记为特大块(jumbo
chunk),MongoDB不能够拿大块迁移至外shard上。

MongoDB cannot move a chunk if the number
of documents in the chunk exceeds either 250000 documents or 1.3 times
the result of dividing the configured chunk size by the average document
size.

1,查看特大块

采取sh.status(),能够察觉大块,特大块的后是 jumbo 标志

 { "x" : 2 } -->> { "x" : 3 } on : shard-a Timestamp(2, 2) jumbo

2,分发特大块

大幅度块不能够拆分,不克经过均衡器自动分发,必须手动分发。

step1,关闭均衡器

sh.setBalancerState(false)

step2,增大Chunk Size的配置值

出于MongoDB不容许倒大小超出限制的偌大块,因此,必须临时增chunk
size的布置值,再将巨大块均衡地分发到分片集众多中。

use config
db.settings.save({"_id":"chunksize","value":"1024"})

step3,移动特大块

sh.moveChunk("db_name.collection_name",{sharded_filed:"value_in_chunk"},"new_shard_name")

step4,启用均衡器

sh.setBalancerState(true)

step5,刷新mongos的部署缓存

强制mongos从config server同步部署信息,并刷新缓存。

use admin
db.adminCommand({ flushRouterConfig: 1 } )

六,均衡器

均衡器是出于mongos转变的,就是说,mongos不仅担当将查询路由至对应的shard上,还要负担数据块的均匀。一般情况下,MongoDB会自动处理数据均,通过config.settings能够查阅balancer的状态,或通过sh辅助函数查看

sh.getBalancerState()

返回true,表示均衡器在刚刚运行,系统活动处理多少均,使用sh辅助函数能够关闭balancer

sh.setBalancerState(false)

balancer不能够就终止在周转的片迁移操作,在mongos转变也balancer时,会申请一个balancer
lock,查看config.locks 集合,

use config
db.locks.find({"_id":"balancer"})

--or 
sh.isBalancerRunning()

倘state=2,表示balancer正处在活跃状态,如果state=0,表示balancer已被关闭。

均衡过程实际上是用数据块从一个shard迁移到其它shard,或者先将一个十分的chunk拆分多少的chunk,再以略片迁移至任何shard上,块的搬和拆分都见面大增系统的IO负载,最好以均衡器的活泼时间限定于系空闲时开展,可以装balancer的龙腾虎跃时间窗口,限制balancer在指定的年月间隔内开展数据块的拆分和迁移操作。

use config

db.settings.update(
  {"_id":"balancer"},
  "$set":{"activeWindow":{"start":"23:00","stop":"04:00"}}),
  true
)

均衡器拆分和动的目标是chunk,均衡器只包chunk数量在各个shard上是平均的,至于每个chunk包含的doc数量,并不一定是均衡的。可能有有chunk包含的doc数量众多,而略chunk包含的doc数量好少,甚至不含有其他doc。因此,应该慎重选择分片的索引键,即片键,如果一个字段既能满足绝大多数询问的要求,又会如doc数量均匀分布,那么该字段是片键的最佳选择。

 

参考文档:

Config
Database

Sharding

Shards

movePrimary

Sharded Cluster
Administration

Data Partitioning with
Chunks

留下评论

网站地图xml地图