mongoDB副本集与分片

mongoDB主从复制

主从复制是sql server 最常用的复制方式,这种方式很灵活.可用于备份,故障恢复,读扩展等.
最基本的设置方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址.
这里我们用一主一从实现mongodb的复制

网易蜂巢的容器已经安装好了mongoDB,直接就可以运行mongo Client,我们要创建自己的mongod实例,
首先把容器自行运行的先停止

mongod --shutdown

创建master实例

mongod --master --port=27081 --dbpath=/data/masterdb --logpath=/data/masterlog --fork

创建 slave实例

mongod --slave  --port=27083 --dbpath=/data/slavedb --logpath=/data/slavelog   --source=27081    --fork

查看mongo进程

root@mongodb-671984-3837ac52-ky93c:~# ps -ef|grep mongod
root       116     1  0 13:09 ?        00:00:05 mongod --master --port=27081 --dbpath=/data/masterdb --logpath=/data/masterlog --fork
root       173     1  0 13:20 ?        00:00:01 mongod --slave --port=27083 --dbpath=/data/slavedb --logpath=/data/slavelog --source=27081 --fork
root       279    64  0 13:24 pts/0    00:00:00 grep mongod

测试 master,slave

连接master

 mongo --port 27081

在mongo client 执行下列命令

> rs.isMaster()
{
    "ismaster" : true,
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2016-09-13T05:29:37.302Z"),
    "maxWireVersion" : 4,
    "minWireVersion" : 0,
    "ok" : 1
}
> use blogs
switched to db blogs
> db.blog.insert({BlogName:"ike's Blog",writer:"ike" })
WriteResult({ "nInserted" : 1 })

连接slave

 mongo --port 27083

在mongo client 执行下列命令

> rs.isMaster()

> use blogs
switched to db blogs
> db.blog.find()
Error: error: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 }

Error的原因是从机默认不支持读写 ,解决办法:

> rs.slaveOk()

mongoDB官方已经不建议大家使用这种主从复制的架构了,这种架构无法避免主机宕机后服务中断.

mongoDB副本集

副本集特点

1.副本集具有2个或者多个节点(一般最少3个)
2.副本集具有一个主节点,其他都是从节点
3.所有数据都是从主节点到从节点的.
4.当主节点故障,从节点会自行推举一个新的主节点
5.当失败节点恢复后,连接副本集后,重新作为从节点

创建多个节点(实例)

mongod --dbpath=/data/node1 --logpath=/data/node1log/nodelog.log --port=27073   --keyFile=/data/node/mongokey  --clusterAuthMode=keyFile  --replSet=nodeset --fork
mongod --dbpath=/data/node2 --logpath=/data/node2log/nodelog.log --port=27075   --keyFile=/data/node/mongokey  --clusterAuthMode=keyFile  --replSet=nodeset --fork
mongod --dbpath=/data/node3 --logpath=/data/node3log/nodelog.log --port=27077   --keyFile=/data/node/mongokey  --clusterAuthMode=keyFile  --replSet=nodeset --fork

连接其中一个实例


> conf={_id:"nodeset",members:[{_id:1 ,host:"localhost:27073"}]}    ##_id:副本集名称
{
    "_id" : "nodeset",
    "members" : [
        {
            "_id" : 1,
            "host" : "localhost:27073"
        }
    ]
}
> rs.initiate(conf)    ##初始化副本集
{ "ok" : 1 }

> use admin                     
switched to db admin

nodeset:PRIMARY> db.createUser({user:"root",pwd:"root",roles:["root"]})     ## PRIMARY 说明连接的是主节点,在admin下创建管理员
nodeset:PRIMARY> db.auth("root","root")                                     ##登入管理员账号
nodeset:PRIMARY> rs.add("127.0.0.1:27075")     ##将其他两个实例添加进副本集
nodeset:PRIMARY> rs.add("127.0.0.1 :27077")
nodeset:PRIMARY> rs.status()                   ##副本集状态,节点查询

到此,拥有3个节点的副本集就创建完了 ,更多操作执行rs.help()查询

mongoDB分片

mongoDB集群:
这里写图片描述

mongoDB分片成员节点

另外一个副本集:

# mongod --port 27011 --dbpath /data/smail_data1 --logpath /var/smail_log1/mongodb.log --keyFile /var/key/mongodb.key --shardsvr  --replSet rs_1 --clusterAut
hMode keyFile --fork --logappend
# mongod --port 27012 --dbpath /data/smail_data2 --logpath /var/smail_log2/mongodb.log --keyFile /var/key/mongodb.key --shardsvr  --replSet rs_1 --clusterAut
hMode keyFile --fork --logappend
# mongod --port 27013 --dbpath /data/smail_data3 --logpath /var/smail_log3/mongodb.log --keyFile /var/key/mongodb.key --shardsvr  --replSet rs_1 --clusterAut
hMode keyFile --fork --logappend

# mongo  --port 27011
> conf={_id:'rs_1',members:[{_id:1,host:'10.166.224.7:27011'}]}
{
    "_id" : "rs_1",
    "members" : [
        {
            "_id" : 1,
            "host" : "10.166.224.7:27011"   ## 10.166.224.7
        }
    ]
}
> rs.initiate(conf)
{ "ok" : 1 }


rs_1:PRIMARY> db.createUser({user:'root',pwd:'root',roles:["root"]})
Successfully added user: { "user" : "root", "roles" : [ "root" ] }
rs_1:PRIMARY> db.auth('root','root')
1
rs_1:PRIMARY> rs.add('10.166.224.7:27013')
{ "ok" : 1 }
rs_1:PRIMARY> rs.add('10.166.224.7:27012')
{ "ok" : 1 }

这里有两个细节:
1.节点之间需要keyfile认证,集群内节点使用keyFile使用的秘钥必须相同
2.不同的服务器使用同一网段注册节点,config server和 副本集 的配置信息不要使用127.0.0.1 或者localhost

config server

mongod --configsvr --port 27019  --dbpath=/data/medium_conf --logpath=/var/conf_log/mongodbconf.log --fork  --logappend --keyFile /var/key/mongodb.key  --clusterAuthMode keyFile
root@medium-701747-230f8712-ee7xm:~# mongo --port 27019
configsvr> use admin
switched to db admin
configsvr> db.createUser(user:'root',pwd:'root',roles:["root"])   

mongos

mongos --port 27021  --logpath=/var/mongosdb_log/mongos.log --fork --logappend  --configdb 10.166.224.4:27019 --keyFile /var/key/mongodb.key  --clusterAuthMode keyFile
                                                                                          ## 使用和分片同一网段的ip

Add Shard

momgo --port 27021

mongos> use admin
switched to db admin
mongos> db.auth('root','root')

mongos> sh.addShard("rs_2/10.166.224.4:27011")   ##添加同一主机下的shard成员
{ "shardAdded" : "rs_2", "ok" : 1 }

mongos> sh.addShard("rs_1/10.166.224.7:27011")  ##添加10.166.224.7下的shard成员
{ "shardAdded" : "rs_1", "ok" : 1 }

mongos> sh.status()   ## sharding status

Enable Sharding

测试分片集群:

mongos> use test  ##database
mongos> for(i=0;i<20000;i++){db.shardtest.insert({'url':'intricate-sutra.com','name':"ike's blog",'i':i})};   ##collection:shardtest
mongos> db.shardtest.stats()   ##查看集合状态,发现shards内只有rs_1一个shard

##数据分片
mongos> sh.enableSharding("test")  
mongos> sh.shardCollection("test.shardtest",{_id:1})  

结束后balance会根据chunk的数量进行数据迁移,直到chunk的数量平均分配到每个shard上,如图:

chunk和balance

balancing:
均衡器负责数据的迁移,会周期性的检查分片是否存在不均衡,如果存在balance进程会进行chunk的迁移.
balance进行均衡的条件是chunk数量的多少,而不是chunk大小

mongos> use config
mongos> db.locks.find({_id:"balancer"}).pretty()  ##查看balance的状态

chunk:
chunkSize的大小默认是64M,可以修改chunk的大小,使数据分布更均衡

mongos> use config
mongos> db.settings.save({"_id" : "chunksize", "value" : NumberLong(32)})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

也可以在数据插入前配置数据存储chunk

mongos> sh.enableSharding('test')
mongos> db.createCollection("job" )  ##创建集合:test.job
mongos> sh.shardCollection('test.job',{'offer':1})
mongos> sh.splitAt("test.job",{offer:20})   ##按offer的20作为split的点

splitting是后台进程,按照middle或者chunk大小splitting数据,上面的操作就是按照middle(split的点)划分.

哈希分片(hash key)

分片过程中利用哈希索引作为分片的单个键.
哈希分片的片键只能使用一个字段.
哈希片键最大的好处就是保证数据在各个节点分布基本均匀.

手动分片

请求查询机制

这里写图片描述

这里写图片描述

这里写图片描述

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页