一、案例
mongos: 192.168.1.3 hadoop1.abc.com hadoop1
config server: 192.168.1.4 hadoop2.abc.com hadoop2
Shard1: 192.168.1.5 hadoop3.abc.com hadoop3
Shard2: 192.168.1.6 hadoop4.abc.com hadoop4
二、启动配置服务器
配置服务器是存储集群元信息的 mongod 实例.使用 --configsvr 指定一个 mongod 为配置服务器,每个配置服务器都存储了集群的一份完整的元信息.
在生产环境下,你必须部署三个配置服务器,每个配置服务器都运行在不同的服务器上以保证良好的正常运行时间和数据安全.在测试环境下,你可以将三台配置服务器运行在一台服务器上.
1、为配置服务器创建数据目录,默认情况下,配置服务器将数据文件存储在/data/configdb目录下.你也可以自己指定不同的位置用来存储数据文件.通过简单的命令创建数据目录:
1
2
|
[root@hadoop2 ~]# mkdir -pv /mongodb/data
[root@hadoop2 ~]# chown -R mongod.mongod /mongodb/
|
2、启动配置服务器,每台都通过一下命令启动:
mongod --configsvr --dbpath <path> --port <port>
配置服务器的默认端口是 27019 .你也可以自己指定.以下示例使用默认的端口和默认的数据目录启动一个配置服务器.
1
|
[root@hadoop2 ~]# mongod --configsvr --dbpath /mongodb/data --port
27019
&
|
也可以编辑配置文件
dbpath = /mongod/data
configsvr = true
配置文件的配置格式:
<setting> = <value>
三、配置mongos
在集群中, mongos 负责将查询与写入分发到 分片 中.使用 mongos,应用有了访问集群的统一入口,而不需要直接访问集群的每个分片
通过缓存 配置服务器 中集群的元信息, mongos 可以得知数据所位于的分片. mongos 使用这些元信息将应用的读写请求分发到不同的分片, mongos 不存储集群 持续 的状态(意思是, mongos 可以随时被重启或者添加,而不会造成集群的数据丢失,也不会造成集群的异常.),并且占有较少的系统资源.
``mongos``如何决定哪个分片应该接收到请求
在 cluster <sharded cluster>`中, :program:`mongos 使用以下步骤分发请求:
-
确定必须接收请求的 分片 列表.
-
在所有目标分片上建立游标.
在某些情况下,当查询条件包含 shard key 或者 shard key 的前缀时,:program:mongos可以将请求分发到部分分片上,否则, mongos 会将请求分发到 所有 存储这个集合的分片上.
检测连接的是否为 mongos
为了检测应用连接的是不是 mongos,可以使用 isMaster 命令.如果应用连接的是一个 mongos , isMaster 返回一个包含 isdbgrid 字符串的 msg ,比如:
{ "ismaster" : true, "msg" : "isdbgrid", "maxBsonObjectSize" : 16777216, "ok" : 1}
mongos属于轻量级应应用,完全可以与其他服务运行于同一节点:启动时,需要为mongos实例指明各config服务器的访问地址:
默认情况下,mongos监听于27017端口;可以使用如下命令启动mongos实例
#mongos --configdb <config server hostnames((IP|Hostname):Port)>
示例:使用以下配置服务器,在默认端口上启动 mongos :
-
cfg0.example.net
-
cfg1.example.net
-
cfg2.example.net
你需要使用以下命令:
mongos --configdb cfg0.example.net:27019,cfg1.example.net:27019,cfg2.example.net:27019
每个 mongos 必须使用 configDB 按照相同的顺序指定配置服务器列表.
如果你启动一个 mongos 时,指定的配置服务器列表与其他 mongos 中指定的不同, mongos 会返回 配置服务器字符串错误错误并退出启动.
也可以直接编辑配置文件
1、注释dbpath指令
2、添加configdb指令,并指定config服务器的地址;
而后使用如下命令启动mongos实例
#mongos -f /etc/mongod.conf
向集群中添加分片
一个 shard 可以是一个单独的:program:mongod或者一个 replica set.在生产环境中,每个分片都应该是一个复制集
1、使用以下命令,从 mongo 终端连接到 mongos.
mongo --host <hostname of machine running mongos> --port <port mongos listens on>
1
2
3
4
5
6
7
|
[root@hadoop2 ~]# mongo --host
192.168
.
1.3
MongoDB shell version:
3.0
.
4
connecting to:
192.168
.
1.3
:
27017
/test
Server has startup warnings:
2015
-
08
-07T18:
01
:
34.816
+
0800
I CONTROL ** WARNING: You are running
this
process
as
the root user, which
is
not recommended.
2015
-
08
-07T18:
01
:
34.816
+
0800
I CONTROL
mongos>
|
2、正如下面的示例,使用 sh.addShard() 在集群中添加分片.每次使用 sh.addShard() 添加一个分片.如果分片是复制集,需要指定复制集的名字与一个成员名字.在生产环境中,所有分片都应该是复制集.
假设一个分片使用了复制集,复制集名字为 rs1 ,有一个运行在 mongodb0.example.net 且端口为 27017 的成员,使用以下命令添加这个分片:
sh.addShard( "rs1/mongodb0.example.net:27017" )
如果添加的shard是独立的mongod实例,则使用如下格式:
1
|
sh.addShard(
"RS_SEVER:P"
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
mongos> sh.addShard(
"192.168.1.5:27017"
)
{
"shardAdded"
:
"shard0001"
,
"ok"
:
1
}
mongos> sh.addShard(
"192.168.1.6:27017"
)
{
"shardAdded"
:
"shard0001"
,
"ok"
:
1
}
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id"
:
1
,
"minCompatibleVersion"
:
5
,
"currentVersion"
:
6
,
"clusterId"
: ObjectId(
"55c481b81d1ceaba52187728"
)
}
shards:
{
"_id"
:
"shard0000"
,
"host"
:
"192.168.1.5:27017"
}
{
"_id"
:
"shard0001"
,
"host"
:
"192.168.1.6:27017"
}
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds
in
last
5
attempts:
0
Migration Results
for
the last
24
hours:
No recent migrations
databases:
{
"_id"
:
"admin"
,
"partitioned"
:
false
,
"primary"
:
"config"
}
mongos>
|
注意,由于添加shard是独立mongod实例,所以你要到192.168.1.5和192.168.1.6把mongod服务启动起来,否则会出现如下错误提示
1
2
3
4
|
mongos> sh.addShard(
"192.168.1.6:27017"
)
{
"ok"
:
0
,
"errmsg"
:
"couldn't connect to new shard socket exception [CONNECT_ERROR] for 192.168.1.6:27017"
|
为集群开启分片
在对集合进行分片之前,必须开启数据库的分片.对数据库开启分片不会导致数据的重新分配,但这是对这个数据库中集合进行分片的前提.
一旦为数据库开启了分片,MongoDB就会为这个数据库指定一个 primary shard,所有未分片的数据都会存储在这个分片上.
-
mongo --host <hostname of machine running mongos> --port <port mongos listens on>
-
使用 sh.enableSharding() 需要指定要开启分片的数据库的名字,语法如下:
sh.enableSharding("<database>")
你也可以使用 enableSharding 命令对数据库开启分片,语法如下:
db.runCommand( { enableSharding: <database> } )
开启如下
1
2
|
mongos> sh.enableSharding(
"testdb"
)
{
"ok"
:
1
}
|
对集合开启分片
分片以集合为基本单位.
-
首先选择一个 shard key ,所选择的片键会影响集群的效率.
-
如果集合中已经包含有数据,需要使用 ensureIndex() 在片键上创建索引.如果集合是空的,MongoDB会在 sh.shardCollection() 过程中自动创建索引.
-
在 mongo 终端中使用 sh.shardCollection() 对一个集合开启分片,语法如下:
sh.shardCollection("<database>.<collection>", shard-key-pattern)
将 <database>.<collection> 字符串换成你数据库的ns,由数据库的全名,一个点(即 . ),和集合的全名组成, shard-key-pattern 换成你的片键,名字为 创建索引 时指定的名字.
示例
The following sequence of commands shards four collections:
sh.shardCollection("records.people", { "zipcode": 1, "name": 1 } )sh.shardCollection("people.addresses", { "state": 1, "_id": 1 } )sh.shardCollection("assets.chairs", { "type": 1, "_id": 1 } )sh.shardCollection("events.alerts", { "_id": "hashed" } )
按照顺序操作分片:
-
records 数据库中的 people 集合使用 { 片键开启分片.
这个集合使用 zipcode 字段重新分配数据.如果很多文档都有相同的 zipcode 值, chunk 会按照 name 的值进行 分裂.
-
people 数据库中的 addresses 集合使用片键 {.
这个片键使用 state 字段重新分配数据.如果很多文档都有相同的 state 值, chunk 会按照 _id 的值进行 分裂.
-
assets 数据库中的 chairs 集合使用 { 做片键.
这个片键使用 type 字段重新分配数据.如果很多文档都有相同的 type 值, chunk 会按照 _id 的值进行 分裂.
-
events 数据库中的 alerts 集合使用 { 做片键.
2.4 新版功能.
这个片键使用 _id 的散列值重新分配数据.MongoDB为 散列索引 计算 _id 的值,可以保证集群中数据的均衡.
-
1
2
|
mongos>
for
(i=
1
;i<=
100
;i++) db.testcoll.insert({Name:
"User"
+i,Age: i,Gender:
"M"
,PreferBook: [
"first book"
,
"Second book"
]})
WriteResult({
"nInserted"
:
1
})
|
先根据年龄作顺序索引,再根据名字做顺序分区
1
2
|
mongos> sh.shardCollection(
"testdb.testcoll"
,{Age:
1
,Name:
1
})
{
"collectionsharded"
:
"testdb.testcoll"
,
"ok"
:
1
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id"
:
1
,
"minCompatibleVersion"
:
5
,
"currentVersion"
:
6
,
"clusterId"
: ObjectId(
"55c481b81d1ceaba52187728"
)
}
shards:
{
"_id"
:
"shard0000"
,
"host"
:
"192.168.1.5:27017"
}
{
"_id"
:
"shard0001"
,
"host"
:
"192.168.1.6:27017"
}
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds
in
last
5
attempts:
0
Migration Results
for
the last
24
hours:
No recent migrations
databases:
{
"_id"
:
"admin"
,
"partitioned"
:
false
,
"primary"
:
"config"
}
{
"_id"
:
"test"
,
"partitioned"
:
false
,
"primary"
:
"shard0000"
}
{
"_id"
:
"testdb"
,
"partitioned"
:
true
,
"primary"
:
"shard0000"
}
testdb.testcoll
shard key: {
"Age"
:
1
,
"Name"
:
1
}
chunks:
shard0000
1
{
"Age"
: {
"$minKey"
:
1
},
"Name"
: {
"$minKey"
:
1
} } -->> {
"Age"
: {
"$maxKey"
:
1
},
"Name"
: {
"$maxKey"
:
1
} } on : shard0000 Timestamp(
1
,
0
)
|