前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >控制MongoDB中的集群分片

控制MongoDB中的集群分片

作者头像
Hero
发布2018-01-08 16:51:34
1.2K0
发布2018-01-08 16:51:34
nananananananananananana-300x187.jpg
nananananananananananana-300x187.jpg

分片标记是MongoDB 2.2.0版中的一项新功能。它应该强制写入到本地数据中心,但也可以用来将集合固定到一个分片或一组分片。

注意:要试用这个,你必须使用2.2.0-rc0或更高版本。

要使用此功能,首先需要启动一个分片集群:

代码语言:javascript
复制
> sharding = new ShardingTest({shards:3,chunksize:1})

这个命令将启动3个分片,一个配置服务器和一个mongos。它也将开始从所有的服务器日志输出到标准输出,所以我建议把这个shell放在一边,并从这里使用一个不同的。

启动一个新的shell并连接到mongos(默认为端口30999),并创建一些分片的集合和数据来使用:

代码语言:javascript
复制
> // remember, different shell
> conn = new Mongo("localhost:30999")
> db = conn.getDB("villains")
>
> // shard db
> sh.enableSharding("villains")
>
> // shard collections
> sh.shardCollection("villains.joker", {jokes:1});
> sh.shardCollection("villains.two-face", {luck:1});
> sh.shardCollection("villains.poison ivy", {flora:1});
> 
> // add data
> for (var i=0; i<100000; i++) { db.joker.insert({jokes: Math.random(), count: i, time: new Date()}); }
> for (var i=0; i<100000; i++) { db["two-face"].insert({luck: Math.random(), count: i, time: new Date()}); }
> for (var i=0; i<100000; i++) { db["poison ivy"].insert({flora: Math.random(), count: i, time: new Date()}); }

现在我们有三个分片和数据库villains的三个不同命名。如果你看看chunks块在哪里,你应该看到它们在分片之间相当平均:

代码语言:javascript
复制

> use config
> db.chunks.find({ns: "villains.joker"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
> db.chunks.find({ns: "villains.two-face"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
> db.chunks.find({ns: "villains.poison ivy"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }

joker-133x300.jpg
joker-133x300.jpg

或者哈雷会说,“布丁”。

然而,数据库villains不同的名称不会和每一个分片在一起,不同的数据库villains会和不同的分片在一起。我们的目标:

分片

命名空间

shard0000

“villains.joker”

shard0001

“villains.two-face”

shard0002

“villains.poison ivy”

要做到这一点,我们将使用标签标签描述了一个分片的属性,任何属性(他们非常灵活)。所以,你可能把一个分片标记为“fast”或“slow”或“east coast”或“rockspace”

在这个例子中,我们要标记一个分片属于某个数据库空间,所以我们将空间的昵称作为标签。

代码语言:javascript
复制
> sh.addShardTag("shard0000", "mr. j")
> sh.addShardTag("shard0001", "harv")
> sh.addShardTag("shard0002", "ivy")

这就是说,“chunks标签"mr.j"标记在shard0000上。“

我们要做的第二件事就是制定一个规则:“对于在villains.joker系列中创建的所有数据块区域,给他们标签mr.j。“要做到这一点,我们可以使用addTagRange助手:

代码语言:javascript
复制
> sh.addTagRange("villains.joker", {jokes:MinKey}, {jokes:MaxKey}, "mr. j")

这就是说,“用'mr.j'来标记villains.joker中的每一个块。j标签(MinKey是负无穷大,MaxKey是正无穷大,所以所有的块落在这个范围内)。

现在让我们为其他两个集合做同样的事情:

代码语言:javascript
复制

> sh.addTagRange("villains.two-face", {luck:MinKey}, {luck:MaxKey}, "harv")
> sh.addTagRange("villains.poison ivy", {flora:MinKey}, {flora:MaxKey}, "ivy")

现在等几分钟(重新平衡需要一点时间),然后看看这些集合的块。

代码语言:javascript
复制

> use config
> db.chunks.find({ns: "villains.joker"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
> db.chunks.find({ns: "villains.two-face"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
> db.chunks.find({ns: "villains.poison ivy"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }

用标签进行缩放

显然,Two-Face对这种安排并不满意,并立即要求两台服务器提供数据。我们可以通过操纵标签将Joker和Poison的集合移动到一个碎片,并将哈维的集合扩展到两个:

代码语言:javascript
复制
> // move Poison Ivy to shard0000
> sh.addShardTag("shard0000", "ivy")
> sh.removeShardTag("shard0002", "ivy")
>
> // expand Two-Face to shard0002
> sh.addShardTag("shard0002", "harv")

现在,如果您等待几分钟并查看数据块,您将看到Two-Face的集合分布在2个分片上,另外两个集合分布在shard0000上。

代码语言:javascript
复制

> db.chunks.find({ns: "villains.poison ivy"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
{ "shard" : "shard0000" }
> db.chunks.find({ns: "villains.two-face"}, {shard:1, _id:0}).sort({shard:1})
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0001" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }
{ "shard" : "shard0002" }

Badheads-300x225.jpg
Badheads-300x225.jpg

“坏人,你得到EBS。”

然而,对于哈维来说,这仍然不太合适,他希望一块分片好,一块坏。比方说,我们利用亚马逊的新产品,并用SSD代替shard0002。然后我们划分流量:将哈维的50%的写入发送到SSD分片,50%发送到机械磁盘分片。首先,我们将标签添加到碎片,描述它们:

代码语言:javascript
复制
> sh.addShardTag("shard0001", "spinning")
> sh.addShardTag("shard0002", "ssd")

“luck”字段的值在0和1之间,所以我们要说“如果luck<0.5,发送到机械磁盘。如果luck>=0.5,发送到SSD。“

代码语言:javascript
复制

> sh.addTagRange("villains.two-face", {luck:MinKey}, {luck:.5}, "spinning")
> sh.addTagRange("villains.two-face", {luck:.5}, {luck:MaxKey}, "ssd")
 

当我现在,“bad luck”文档将被写入机械磁盘,“good luck”文档将写入SSD。

们添加新的服务器,我们可以控制他们得到什么样的负载。标记为操作员提供了对集合在哪里的控制权。

最后,我写了一个小脚本,为集合添加一个“home”方法,将它们固定在一个标签上。用法示例:

代码语言:javascript
复制
> // load the script
> load("batman.js")
> // put foo on bar
> db.foo.home("bar")
> // put baz on bar
> db.baz.home("bar")
> // move foo to bat
> db.foo.home("bat")
评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 用标签进行缩放
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档