该实验在两台虚拟机搭建一个自动故障转移集群,因为副本集只会自动切换主库,而应用是不会自动变换IP的,为了实现应用对主数据库的自动查找,可以利用mongodb的mongos,为此需要将两台虚拟机搭建成一个分片节点。

环境:

两台服务器[windows与Linux是宿主的关系]:

Ubuntu Linux:192.168.56.101

Windows:192.168.56.1

其中Linux上启动3个mongod来创建副本集,windows服务上创建路由服务器,配置服务器和一个分片。

 

Linux上创建副本集:

启动3个mongod进程分别为:

192.168.56.101:10101

192.168.56.101:20101

192.168.56.101:30101

其中192.168.56.101:30101为仲裁机器

 

./mongod--dbpath=/usr/local/mongodb2.0.1/db --logpath=/usr/local/mongodb2.0.1/log/mongod.log --logappend --fork --port=10101-replSet test

 

./mongod--dbpath=/usr/local/mongodb2.0.2/db --logpath=/usr/local/mongodb2.0.2/log/mongod.log --logappend --fork --port=20101-replSet test

 

./mongod--dbpath=/usr/local/mongodb2.0.3/db --logpath=/usr/local/mongodb2.0.3/log/mongod.log --logappend --fork --port=30101-replSet test

 

登陆192.168.56.101:10101配置初始化副本集:

./mongo 192.168.56.101:10101

use admin

 

db.runCommand({"replSetInitiate":{"_id":"test","members":[{"_id":0,"host":"192.168.56.101:10101"},{"_id":1,"host":"192.168.56.101:20101"},{"_id":2,"host":"192.168.56.101:30101",arbiterOnly:true}]}})

 

返回:

{

    "info" : "Config now saved locally. Should come online in about a minute.",

    "ok" : 1

}

说明初始化配置成功。

运行rs.status();

 

PRIMARY> rs.status();

{

    "set" : "test",

    "date" : ISODate("2013-04-01T03:15:09Z"),

    "myState" : 1,

    "members" : [

        {

            "_id" : 0,

            "name" : "192.168.56.101:10101",

            "health" : 1,

            "state" : 1,

            "stateStr" : "PRIMARY",

            "optime" : {

                "t" : 1364786052000,

                "i" : 1

            },

            "optimeDate" : ISODate("2013-04-01T03:14:12Z"),

            "self" : true

        },

        {

            "_id" : 1,

            "name" : "192.168.56.101:20101",

            "health" : 1,

            "state" : 2,

            "stateStr" : "SECONDARY",

            "uptime" : 51,

            "optime" : {

                "t" : 1364786052000,

                "i" : 1

            },

            "optimeDate" : ISODate("2013-04-01T03:14:12Z"),

            "lastHeartbeat" : ISODate("2013-04-01T03:15:08Z"),

            "pingMs" : 0

        },

        {

            "_id" : 2,

            "name" : "192.168.56.101:30101",

            "health" : 1,

            "state" : 7,

            "stateStr" : "ARBITER",

            "uptime" : 51,

            "optime" : {

                "t" : 0,

                "i" : 0

            },

            "optimeDate" : ISODate("1970-01-01T00:00:00Z"),

            "lastHeartbeat" : ISODate("2013-04-01T03:15:08Z"),

            "pingMs" : 2899947

        }

    ],

    "ok" : 1

}

 

PRIMARY表示192.168.56.101:10101为主节点。192.168.56.101:20101为从节点SECONDARY,仲裁节点为192.168.56.101:30101.

 

至此,副本集已经建立完毕【测试副本集过程省略】。

 

创建分片:

Winows机器上启动3个mongod.

192.168.56.1:10001【配置服务器】

192.168.56.1:20001【mongos服务器】

192.168.56.1:30001【分片节点】

1:开启config服务器192.168.56.1:10001

mongod -dbpath D:\software\mongodb2.4.1\db -logpath D:\software\mongodb2.4.1\log\mongod.log -port 10001 -logappend

 

2. 开启mongos服务器192.168.56.1:20001

mongos --port=20001 --configdb=192.168.56.1:10001 [指定配置服务器192.168.56.1:10001],以后添加查询都是通过mongos服务器对外接口的

 

3:启动mongod分片服务器192.168.56.1:30001

mongod -dbpath D:\software\mongodb2.4.3\db -logpath D:\software\mongodb2.4.3\log\mongod.log -port 30001 -logappend

 

4:服务配置

登陆mongos[192.168.56.1:20001]

mongo 192.168.56.1:20001

use admin

添加分片:

A添加192.168.56.1:30001这台分片。运行:

db.runCommand({"addshard":"192.168.56.1:30001",allowLocal:true})

B 添加刚才创建的副本集,添加主节点192.168.56.101:10101为分片,运行:

db.runCommand({addshard:"test/192.168.56.101:10101"})

【test为副本集名称,192.168.56.101:10101为副本集主节点】

C 设置分片

  1. 开启数据库分片功能,命令很简单 enablesharding(),这里我就开启ShardTest数据库。运行:

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

  1. 指定集合中分片的片键,这里我就指定为person.name字段。运行:

    db.runCommand({"shardcollection":"ShardTest.person","key":{"name":1}})

查看效果:

至此我们的分片操作全部结束,接下来我们通过mongosmongodb插入10w记录,然后通过printShardingStatus命令查看mongodb的数据分片情况。运行:

use ShardTest

for(var i=0;i<100000;i++) db.person.insert({"name":"guo"+i,"age":i})

 

db. printShardingStatus();

可以看出有两个分片shard0000和test。

片键的分配:test上一个片键,shard0000两个片键集。

1.{ "name" : { "$minKey" : 1 } } -->> { "name" : "guo0" }

on : test从无穷小到guo0的片键在test分片上,记在192.168.101:10101这个副本集上。

2.{ "name" : "guo0" } -->> { "name" : "guo9999" } on : sha

rd0000即在192.168.56.1:30001机器上。

3.{ "name" : "guo9999" } -->> { "name" : { "$maxKey" : 1 }on : shard00009999到无穷大的片键也分片在shard0000

分区情况为:31,从后面的 on shardXXXX也能看得出。

 

此时登陆到192.168.101:10101查询person集合的数据,发现并没有记录,根据上面的片键分片策略无穷小到guo0分配到test副本集上,这也是正常的。因为我们添加的记录都是》=0的。为了测试片键分配策略,我们添加一些负数记录,看是否存储到test副本集上。

mongos上执行:

for(var i=-10000;i<-1;i++) db.person.insert({"name":"guo"+i,"age":i})

发现目前已经有110000条记录,那么新增加的是否是分配到副本集上了呢,登陆192.168.56.101:10101进行查询:

发现新增加的10000条记录已经添加到副本集中,同理登陆192.168.56.101:20101进行查看,发现也已经有数据。

    按照分片的原则,令一个分片192.168.56.1:30001上应该还是最初添加的10000条记录,刚加的10000条记录由于不符合片键的分配原则并没有分配到192.168.56.1:30001这台机器上。登陆30001进行查询验证:

验证副本集:

为了验证副本集的健壮性,我们将test副本集中的主节点192.168.56.1:10101停掉,同时在mongos中查询{"name":"guo-1000"}的记录。

其中1786这个pid为端口10101这个mongod进程。将其停掉后查询{"name":"guo-1000"}的记录。

发现已经不能查询。停几秒钟后又可以进行查询,说明副本集test已经生效。

登陆到副本集的从节点192.168.56.101:20101上发现20101已经变为主节点。

root@guo-VirtualBox:/usr/local/mongodb2.0.1/bin# ./mongo 192.168.56.101:20101

MongoDB shell version: 2.0.5

connecting to: 192.168.56.101:20101/test

PRIMARY> rs.status();

{

    "set" : "test",

    "date" : ISODate("2013-04-01T04:57:42Z"),

    "myState" : 1,

    "syncingTo" : "192.168.56.101:10101",

    "members" : [

        {

            "_id" : 0,

            "name" : "192.168.56.101:10101",

            "health" : 0,

            "state" : 8,

            "stateStr" : "(not reachable/healthy)",

            "uptime" : 0,

            "optime" : {

                "t" : 1364791344000,

                "i" : 246

            },

            "optimeDate" : ISODate("2013-04-01T04:42:24Z"),

            "lastHeartbeat" : ISODate("2013-04-01T04:54:43Z"),

            "pingMs" : 0,

            "errmsg" : "socket exception"

        },

        {

            "_id" : 1,

            "name" : "192.168.56.101:20101",

            "health" : 1,

            "state" : 1,

            "stateStr" : "PRIMARY",

            "optime" : {

                "t" : 1364791344000,

                "i" : 246

            },

            "optimeDate" : ISODate("2013-04-01T04:42:24Z"),

            "self" : true

        },

        {

            "_id" : 2,

            "name" : "192.168.56.101:30101",

            "health" : 1,

            "state" : 7,

            "stateStr" : "ARBITER",

            "uptime" : 6193,

            "optime" : {

                "t" : 0,

                "i" : 0

            },

            "optimeDate" : ISODate("1970-01-01T00:00:00Z"),

            "lastHeartbeat" : ISODate("2013-04-01T04:57:41Z"),

            "pingMs" : 0

        }

    ],

    "ok" : 1

}

PRIMARY>

在通过mongos[192.168.56.1:20001]添加一条记录{"name":"guo-10001"},看副本集是否还能进行添加。

再登陆副本集节点192.168.56.101:20101查询。

发现副本集中的从节点192.168.56.1::20101已经接替节点192.168.56.1:10101成为主节点。

 

综上所述,可以对数据库服务器做副本集并使所有的访问都通过mongos来达到数据库服务器故障的自动转移。