经历了九九八十一难,基本上集群分片终于有点效果了,于是赶紧梳理了一下思绪。开始做之前先把自己的服务器的防火墙关闭,用date命令查看三台服务器的时间是不是一致,如果不一致请及时修改调整时间,语法为date -s  12:00, 学会几个命令,查看防火墙命令:/etc/init.d/iptables status    关闭/开启防火墙命令:chkconfig iptables off /on  ,查看端口号:netstat -tnulp

 

mongo集群分片实战

服务器三台

 

 

                主机1172.19.0.215                 主机2172.19.0.216                                主机3172.19.0.217

     第一片(11731)                                                                     副本                                                                              仲裁

 

     第二片(11732)                  仲裁                                                                                                                                 副本

 

     第三片(11733)                    副本                                        仲裁                                                                                   

 

                    30000                     config Server                                 config Server                                                            config Server

 

                    60000                           Route Process                         Route Process                                                         Route Process

 

创建数据库目录

主机1172.19.0.215)配置文件

[root@mongodb115 ~]# mkdir -p /home/data/shard1_1

[root@mongodb115 ~]# mkdir -p /home/data/shard2_1

[root@mongodb115 ~]# mkdir -p /home/data/shard3_1

[root@mongodb115 ~]# mkdir -p /home/data/config                             #config server目录

[root@mongodb115 ~]# mkdir -p /home/config                                        #放配置文件

[root@mongodb115 ~]# mkdir -p /home/logs

 

 

进入到/home/config/目录下,分别编辑并创建以下配置文件,分别为:
 shard1_1.conf
shard2_1.conf

shard3_1.conf
config.conf                  

mongos.conf             

刚开始不知道,就直接用cat  shard1_1.conf 发现报错。后来才知道没有这个文件,需要自己用vi去编译,就是vi shard1_1.conf  ,这个文件里面写下配置文件之后,按住键盘上的esc健,写:wq! 保存退出!

分片一

[root@215 config]# cat shard1_1.conf
port=11731
dbpath=/home/data/shard1_1
logpath=/home/data/logs/shard1_1.log
directoryperdb=true
logappend=true
replSet=shard1
#bind_ip=172.19.0.215
shardsvr=true
fork=true
pidfilepath=/home/data/shard1_1.pid
maxConns=20000
oplogSize=100
noprealloc=true
nohttpinterface=true

 

 

分片二

[root@215 config]# cat shard2_1.conf
port=11732
dbpath=/home/data/shard2_1
logpath=/home/data/logs/shard2_1.log
directoryperdb=true
logappend=true
replSet=shard2
#bind_ip=172.19.0.215
shardsvr=true
fork=true
pidfilepath=/home/data/shard2_1.pid
maxConns=20000
oplogSize=100
noprealloc=true
nohttpinterface=true

 

分片三

[root@215 config]# cat shard3_1.conf
port=11733
dbpath=/home/data/shard3_1
logpath=/home/data/logs/shard3_1.log
directoryperdb=true
logappend=true
replSet=shard3
#bind_ip=172.19.0.215
shardsvr=true
fork=true
pidfilepath=/home/data/shard3_1.pid
maxConns=20000
oplogSize=100
noprealloc=true
nohttpinterface=true

 

config server 配置文件

 

[root@215 config]# cat config.conf
port=30000
dbpath=/home/data/config
logpath=/home/data/logs/config.log
directoryperdb=true
configsvr=true
logappend=true
#bind_ip=172.19.0.215
fork=true
pidfilepath=/home/data/config.pid
maxConns=20000
oplogSize=100
noprealloc=true
nohttpinterface=true

Route Proces 配置文件

[root@215 config]# cat mongos.conf
port=60000
logpath=/home/data/logs/mongos.log
logappend=true
configdb=172.19.0.215:30000,172.19.0.216:30000,172.19.0.217:30000
#bind_ip=172.19.0.215
fork=true
pidfilepath=/home/data/mongos.pid
chunkSize=5
maxConns=20000

 

主机2172.19.0.216)配置文件

[root@216~]# mkdir -p /home/data/shard1_2

[root@216~]# mkdir -p /home/data/shard2_2

[root@216~]# mkdir -p /home/data/shard3_2

[root@216~]# mkdir -p /home/data/config                               #config server目录

[root@216~]# mkdir -p /home/config                                              #放配置文件

[root@216~]# mkdir -p /home/logs

 

进入到/home/config/目录下,分别编辑并创建以下配置文件,分别为:
shard1_2.conf
shard2_2.conf

shard3_2.conf
config.conf

mongos.conf

分片一

[root@216 config]# cat shard1_2.conf
port=11731
dbpath=/home/data/shard1_2
logpath=/home/data/logs/shard1_2.log
directoryperdb=true
logappend=true
replSet=shard1
#bind_ip=172.19.0.216
shardsvr=true
fork=true
pidfilepath=/home/data/shard1_2.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

分片二

[root@localhost config]# cat shard2_2.conf
port=11732

dbpath=/home/data/shard2_2
logpath=/home/data/logs/shard2_2.log
directoryperdb=true
logappend=true
replSet=shard2
#bind_ip=172.19.0.216
shardsvr=true
fork=true
pidfilepath=/home/data/shard2_2.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

分片三:

[root@localhost config]# cat shard3_2.conf
port=11733
dbpath=/home/data/shard3_2
logpath=/home/data/logs/shard3_2.log
directoryperdb=true
logappend=true
replSet=shard3
#bind_ip=172.19.0.216
shardsvr=true
fork=true
pidfilepath=/home/data/shard3_2.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

config server 配置文件

 

[root@216 config]# cat config.conf
port=30000
dbpath=/home/data/config
logpath=/home/data/logs/config.log
directoryperdb=true
configsvr=true
logappend=true
#bind_ip=172.19.0.216
fork=true
pidfilepath=/home/data/config.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

Route Proces 配置文件

[root@216 config]# cat mongos.conf
port=60000
logpath=/home/data/logs/mongos.log
logappend=true
configdb=172.19.0.215:30000,172.19.0.216:30000,172.19.0.217:30000
#bind_ip=172.19.0.216
fork=true
pidfilepath=/home/data/mongos.pid
chunkSize=5
maxConns=20000
#nohttpinterface=true


主机3172.19.0.217)配置文件

[root@217~]# mkdir -p /home/data/shard1_3

[root@217~]# mkdir -p /home/data/shard2_3

[root@217~]# mkdir -p /home/data/shard3_3

[root@217~]# mkdir -p /home/data/config #config server目录

[root@217~]# mkdir -p /home/config #放配置文件

[root@217~]# mkdir -p /home/logs

 

分片一

[root@217  config]# cat shard1_3.conf
port=11731
dbpath=/home/data/shard1_3
logpath=/home/data/logs/shard1_3.log
directoryperdb=true
logappend=true
replSet=shard1
#bind_ip=172.19.0.217
shardsvr=true
fork=true
pidfilepath=/home/data/shard1_3.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

分片二

[root@217 config]# cat shard2_3.conf
port=11732
dbpath=/home/data/shard2_3
logpath=/home/data/logs/shard2_3.log
directoryperdb=true
logappend=true
replSet=shard2
#bind_ip=172.19.0.217
shardsvr=true
fork=true
pidfilepath=/home/data/shard2_3.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

分片三:

[root@217 config]# cat shard3_3.conf
port=11733
dbpath=/home/data/shard3_3
logpath=/home/data/logs/shard3_3.log
directoryperdb=true
logappend=true
replSet=shard3
#bind_ip=172.19.0.217
shardsvr=true
fork=true
pidfilepath=/home/data/shard3_3.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

config server 配置文件

 

[root@217  config]# cat config.conf
port=30000
dbpath=/home/data/config
logpath=/home/data/logs/config.log
directoryperdb=true
configsvr=true
logappend=true
#bind_ip=172.19.0.217
fork=true
pidfilepath=/home/data/config.pid
maxConns=20000
oplogSize=5000
noprealloc=true
nohttpinterface=true

 

Route Proces 配置文件

 

[root@217config]# cat mongos.conf
port=60000
logpath=/home/data/logs/mongos.log
logappend=true
configdb=172.19.0.215:30000,172.19.0.216:30000,172.19.0.217:30000
#bind_ip=172.19.0.217
fork=true
pidfilepath=/home/data/mongos.pid
chunkSize=5
maxConns=20000
#nohttpinterface=true

 

解压mongodb文件,配置mongodb  ,我用的是2.0.4版本

wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.4.tgz


主机1

[root@215 ~]# tar zxvf mongodb-linux-x86_64-2.0.4.tgz

[root@215 ~]# mv mongodb-linux-x86_64-2.0.4.tgz /home/mongodb

主机2

[root@216 ~]# tar zxvf mongodb-linux-x86_64-2.0.4.tgz

[root@216 ~]# mv mongodb-linux-x86_64-2.0.4.tgz/home/mongodb

主机3

[root@217 ~]# tar zxvf mongodb-linux-x86_64-2.0.4.tgz

[root@217 ~]# mv mongodb-linux-x86_64-2.0.4.tgz /home/mongodb

 

 

启动shard1,shard2,shard3

主机1

[root@215~]# /home/mongodb/bin/mongod -f /home/config/shard1_1.conf

[root@215~]# /home/mongodb/bin/mongod -f /home/config/shard2_1.conf

[root@215~]# /home/mongodb/bin/mongod -f /home/config/shard3_1.conf

 

主机2

[root@216~]# /home/mongodb/bin/mongod -f /home/config/shard1_2.conf

[root@216~]# /home/mongodb/bin/mongod -f /home/config/shard2_2.conf

[root@216~]# /home/mongodb/bin/mongod -f /home/config/shard3_2.conf

 

主机3

[root@217~]# /home/mongodb/bin/mongod -f /home/config/shard1_3.conf

[root@217~]# /home/mongodb/bin/mongod -f /home/config/shard2_3.conf

[root@217~]# /home/mongodb/bin/mongod -f /home/config/shard3_3.conf

 (注释:上面三个主机启动分片的时候一定要把路径弄正确,不然就报错了。在这个地方如果遇到报这个错误的时候,代码如下:

[root@215~]# /home/mongodb/bin/mongos -f /home/config/mongos.conf
error command line: unknown option nohttpinterface)

这个是因为我们的配置文件config.conf 中有一个参数读不到,这个参数nohttpinterface=true可以注释掉该参数。即可解决。如下代码

[root@localhost config]# cat config.conf
port=30000
dbpath=/home/data/config
logpath=/home/data/logs/config.log
directoryperdb=true
configsvr=true
logappend=true
#bind_ip=172.19.0.215
fork=true
pidfilepath=/home/data/config.pid
maxConns=20000
oplogSize=100
noprealloc=true
#nohttpinterface=true

 

配置Replica Sets

配置分片1 172.19.0.215上配置

[root@215~]# /home/mongodb/bin/mongo --port 11731

MongoDB shell version: 2.4.7

connecting to: 127.0.0.1:11731/test

>config={_id:'shard1',members:[{_id:0,host:'172.19.0.215:11731' ,priority:2},{_id:1,host:'172.19.0.216:11731'},{_id:2,host:'172.19.0.217:11731',arbiterOnly:true}]}

 

rs.initiate(config)                                           

(注释:此处在初始化分片的时候报错了,比较奇怪的是,后面的216,217都可以正常操作,且分片初始化的时候也能正常,唯有主机215报错,错误情况见图:这个地方要保证三台服务器是开启状态。解决方法就是把配置文件中的5000一个参数修改成oplogSize=100,

实战Replica <wbr>Sets+Sharding方案采用配置文件
解决方法就是把配置文件中的一个参数修改成100,代码如下:
[root@215  config]# cat shard1_1.conf
port=11731
dbpath=/home/data/shard1_1
logpath=/home/data/logs/shard1_1.log
directoryperdb=true
logappend=true
replSet=shard1
#bind_ip=172.19.0.215
shardsvr=true
fork=true
pidfilepath=/home/data/shard1_1.pid
maxConns=20000
oplogSize=100
noprealloc=true
nohttpinterface=true

 

配置分片2 172.19.0.216上配置

[root@216~]# /home/mongodb/bin/mongo --port 11732

MongoDB shell version: 2.4.7

connecting to: 127.0.0.1:11732/test

>config={_id:'shard2',members:[{_id:0,host:'172.19.0.215:11732',arbiterOnly:true},{_id:1,host:'172.19.0.216:11732',priority:2},{_id:2,host:'172.19.0.217:11732' }]}

 

rs.initiate(config)

 

配置分片3 172.19.0.217上配置 members里面的优先级priority值高的为主节点,对于仲裁点一定要加上arbiterOnly:true

[root@217~]# /home/mongodb/bin/mongo --port 11733

MongoDB shell version: 2.4.7

connecting to: 127.0.0.1:11733/test

>config={_id:'shard3',members:[{_id:0,host:'172.19.0.215:11733'},{_id:1,host:'172.19.0.216:11733',arbiterOnly:true },{_id:2,host:'172.19.0.217:11733',priority:2 }]}

 

rs.initiate(config)

 

 

启动3config server

主机1

[root@215~]# /home/mongodb/bin/mongod -f /home/config/config.conf

 

主机2

[root@216~]# /home/mongodb/bin/mongod -f /home/config/config.conf

 

主机3

[root@217~]# /home/mongodb/bin/mongod -f /home/config/config.conf

 

 

 

启动3 Route Process

主机1

[root@215~]# /home/mongodb/bin/mongos -f /home/config/mongos.conf

主机2

[root@216~]# /home/mongodb/bin/mongos -f /home/config/mongos.conf

 

主机3

[root@217~]# /home/mongodb/bin/mongos -f /home/config/mongos.conf

 

配置shard Cluser

[root@215~]# /home/mongodb/bin/mongo --port 60000

MongoDB shell version: 2.4.7

connecting to: 127.0.0.1:60000/test

mongos> use admin

switched to db admin

mongos>db.runCommand({addshard:"shard1/172.19.0.215:11731,172.19.0.216:11731,172.19.0.217:11731"})

 

mongos>db.runCommand({addshard:"shard2/172.19.0.215:11732,172.19.0.216:11732,172.19.0.217:11732"})

 

mongos> db.runCommand({addshard:"shard3/172.19.0.215:11733,172.19.0.216:11733,172.19.0.217:11733"})

 

 

(注释:此处浪费我一段时间,上面的都能够正常启动,但是这个地方确报错,最好找同事帮忙查看后发现,每个IP后面的逗号多了一个空格,删除空格即可。各位如果在搭建的时候注意不要复制,如果复制要检查各个字母之后有没有空格和中文字母。)

接下来激活分片,如下面的代码所示: 采用hash分片

db.runCommand({enablesharding:"test"})

db.runCommand({shardcollection:"test.users",key:{id:"hashed"}})

(注释:在最后这一个地方报错,见以下代码:

mongos> db.runCommand({enablesharding:"test"})
{ "ok" : 1 }
mongos> db.runCommand({shardcollection:"test.users",key:{id:"hashed"}})
{ "ok" : 0, "errmsg" : "shard keys must all be ascending" }

上面一行代码运行正常,下面这一行就提示碎片必须要按照升序。在百度查询之后,也没有找到类似错误的解决方法,最好在一个网友的点拨下,把第二行代码修改id:"hashed", 修改后的语法为:

mongos> db.runCommand({shardcollection:"test.users",key:{id:1}})
{ "collectionsharded" : "test.users", "ok" : 1 }
mongos>

问题原因可能是版本的问题。有人说2.0.4的版本不支持分片。但是修改了之后就可以鸟!

 

验证分片是不是成功,见下文:

我们可以用任意一台连接mongodb,这里以215为例:

[root@215 ~]# /home/mongodb/bin/mongo --port 30000
MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:30000/test
> show dbs
admin (empty)
config 0.078125GB
local (empty)
>

这个地方如果你插入数据,会报错,如下文:

> use text
switched to db text
> db.books.insert({x:"1",y:"2"})
can't create user databases on a --configsvr instance
>

这个时候我我检查插入语法,可是语法没有错呀,批量插入也是同样报这个错,最好在百度查询之后,经各位网友的指点,找到了结果,原因是:应该在路由里面去操作数据库,这个地方不能操作数据库,可是问题来了,哪个是我们的路由呢?记住,路由里面去show dbs  的时候,里面是没有local数据库的,也就是说我们选择的端口不对,那么我们就去60000端口里面去试试。

代码如下:进入路由

[root@215 ~]# /home/mongodb/bin/mongo --port 60000
MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:60000/test
mongos> show dbs
config 0.0625GB
test 0.078125GB
mongos>

我们批量插入一段数据

mongos> use text
switched to db text
mongos> for(var i=1;i<2000;i++)db.books.insert({id:i,book_name:"PHP",book_id:"888"});
mongos> show collections
books
system.indexes
mongos> db.books.find()
{ "_id" : ObjectId("53d076484bbffdbd489d5801"), "id" : 1, "book_name" : "PHP", "book_id" : "888" }
{ "_id" : ObjectId("53d076484bbffdbd489d5802"), "id" : 2, "book_name" : "PHP", "book_id" : "888" }
{ "_id" : ObjectId("53d076484bbffdbd489d5803"), "id" : 3, "book_name" : "PHP", "book_id" : "888" }

我们可以看到,插入的数据已经成功了!

验证分片:

由于我们是做分片,所以我们应该去验证我们的分片是不是成功的,所以我们插入一条大的数据,202000条数据

mongos> show dbs
config 0.0625GB
test 0.078125GB
text 0.078125GB
mongos> use test
switched to db test
mongos> show collections
system.indexes
users
mongos> db.users.count()      ----查询users表中所有数据的总和count
202000
mongos>

然后我们看一下分片的效果:

mongos> db.users.stats()
{
 "sharded" : true,
 "flags" : 1,
 "ns" : "test.users",
 "count" : 202000,
 "numExtents" : 7,
 "size" : 15352032,
 "storageSize" : 21250048,
 "totalIndexSize" : 12280352,
 "indexSizes" : {
  "_id_" : 6573504,
  "id_1" : 5706848
 },
 "avgObjSize" : 76.00015841584158,
 "nindexes" : 2,
 "nchunks" : 1,
 "shards" : {
  "shard1" : {
   "ns" : "test.users",
   "count" : 202000,
   "size" : 15352032,
   "avgObjSize" : 76.00015841584158,
   "storageSize" : 21250048,
   "numExtents" : 7,
   "nindexes" : 2,
   "lastExtentSize" : 10067968,
   "paddingFactor" : 1,
   "flags" : 1,
   "totalIndexSize" : 12280352,
   "indexSizes" : {
    "_id_" : 6573504,
    "id_1" : 5706848
   },
   "ok" : 1
  }
 },
 "ok" : 1
}
mongos>

注释:这个地方我们可以看到数据存在shard1分片中,并没有把202000条数据平均分布到其他的片键中,在查询资料和网友的沟通中,得知少量的数据有可能不会分配到其他的片键中,或者是版本的问题造成了没有平均分布插入数据。我们的版本是mongodb2.0.4,这个问题还要今后继续测试。也有人说是因为我们批量存入的数据是一样的,没有区分,所有mongodb没有按照不同的数据去存入。

我们输入:sh.status()

mongos> sh.status()
--- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
 {  "_id" : "shard1",  "host" : "shard1/172.19.0.215:11731,172.19.0.216:11731" }
 {  "_id" : "shard2",  "host" : "shard2/172.19.0.216:11732,172.19.0.217:11732" }
 {  "_id" : "shard3",  "host" : "shard3/172.19.0.215:11733,172.19.0.217:11733" }
  databases:
 {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
 {  "_id" : "test",  "partitioned" : true,  "primary" : "shard1" }
  test.users chunks:
    shard1 1
   { "id" : { $minKey : 1 } } -->> { "id" : { $maxKey : 1 } } on : shard1 { "t" : 1000, "i" : 0 }

mongos>

上面是我们的分片具体情况。

由于分片是昨天做的,今天早上来公司打开虚拟机的时候,发现又出了点问题。用60000的端口连接,报错如下:

[root@localhost ~]#  /home/mongodb/bin/mongo --port 60000
MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:60000/test
mongos> show dbs
Thu Jul 24 09:36:50 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }

最后问题竟然出现在启动的顺序上。

解决方案就是:

先确定我们的分片有没有问题,检查分片有没有问题运行netstat -tunlp 查看我们的各个端口号是不是正常,发现正常呀,而且还多了一个61000的mongodb端口。可是我们也没有去设置这个端口啊,原来这个端口是自己生成的,具体是干嘛用的我还没有搞清楚!

 解决方法,先查询出mongo中的服务进程,然后杀死,按照正确的顺序去启动,那么什么是正确的启动顺序呢?见下文:

[root@localhost ~]# ps axu | grep mongo
root      2347  0.5  3.1 1270252 31948 ?       Sl   08:59   0:26 /home/mongodb/bin/mongod -f /home/config/config.conf
root      2360  0.7  0.5 616392  5424 ?        Sl   09:00   0:34 /home/mongodb/bin/mongos -f /home/config/mongos.conf
root     22942  0.7  3.7 1606116 37856 ?       Sl   09:18   0:24 /home/mongodb/bin/mongod -f /home/config/shard1_1.conf
root     22999  0.7  3.6 1333648 37636 ?       Sl   09:19   0:25 /home/mongodb/bin/mongod -f /home/config/shard2_1.conf
root     23052  0.8  3.5 1594764 35820 ?       Sl   09:19   0:27 /home/mongodb/bin/mongod -f /home/config/shard3_1.conf
root     25019  6.0  0.0 103240   840 pts/0    S+   10:13   0:00 grep mongo
[root@localhost ~]# killall mongod
[root@localhost ~]# killall mongos

按照以下顺序启动,其他三台也是一样的先查出mongodb进程,然后杀死,然后和215同步一起启动:启动顺序如下

1,/home/mongodb/bin/mongod -f /home/config/shard1_1.conf

2,/home/mongodb/bin/mongod -f /home/config/shard2_1.conf

3,/home/mongodb/bin/mongod -f /home/config/shard3_1.conf

4,/home/mongodb/bin/mongod -f /home/config/config.conf

5,/home/mongodb/bin/mongos -f /home/config/mongos.conf

6,/home/mongodb/bin/mongos -f /home/config/mongos.conf

三台服务器全部启动之后,我们可以查看各个端口号是不是正常。在第六步没有启动的是时候连接的时候报错,其他三台正常连接,查看端口的时候发现少了一个端口。就重新启动了mongos.conf

全部启动之后我们进行连接:

[root@215 ~]# /home/mongodb/bin/mongo --port 60000
MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:60000/test
mongos> show dbs
config 0.0625GB
test 0.078125GB     ---这个地方已经没有报错了。
mongos> use test
switched to db test
mongos> show collections
system.indexes
users
mongos> db.users.find()
{ "_id" : ObjectId("53cf7f2239fa6a0f3720fa90"), "id" : 1, "addr_1" : "BeiJing", "addr_2" : "Shanghai" }
{ "_id" : ObjectId("53cf7f2239fa6a0f3720fa91"), "id" : 2, "addr_1" : "BeiJing", "addr_2" : "Shanghai" }
{ "_id" : ObjectId("53cf7f2239fa6a0f3720fa92"), "id" : 3, "addr_1" : "BeiJing", "addr_2" : "Shanghai" }

分片完成!