这一篇日志记录一下MongoDB分布式相关的操作,方便查询。

在开始真正的分布式之前,先说一下主从复制和副本集。

 

主从复制

主从复制的主要目的是读写分离,即主服务器提供增删改服务,从服务器保持同步并只提供查询服务。

mongod --dbpath=D:\master --port 27700 --master            #主服务器
mongod --dbpath=E:\slave --port 27701 --slave              #从服务器 

 

副本集

副本集是具有自动故障恢复功能的主从集群,主服务器不固定,主服务器挂掉后,会在剩下的从服务器里选一个变成主服务器(根据优先级权重),即一个活跃节点primary和多个备份节点secondary。

mongod --dbpath=D:\node1 --logpath D:\node1\logs.txt --logappend --port 27701 --replSet yumefx/localhost:27702 --master            #活跃节点

mongod --dbpath=D:\node2 --logpath D:\node2\logs.txt --logappend --port 27702 --replSet yumefx/localhost:27701                     #备份节点1

mongod --dbpath=D:\node3 --logpath D:\node3\logs.txt --logappend --port 27703 --replSet yumefx/localhost:27701,localhost:27702     #备份节点2

上面yumefx是副本集的名称,后面则是声明和备份节点的关系。

副本集启动后还需要初始化一次(只能初始化一次),随意登录一个节点,以27701为例。

mongo localhost:27701 
use admin
db.runCommand({
    "replSetInitiate":{
        "_id":"yumefx",
        "members":[
        {
            "_id":1,
            "host":"localhost:27701",
            "priority":30
        },
        {
            "_id":2,
            "host":"localhost:27702",
            "priority":20
        },  
        {
            "_id":3,
            "host":"localhost:27703",
            "priority":10
        }
        ]
    }
});                        #rs.initiate({...})
rs.conf()                                  #显示当前配置
rs.add("localhost:27704")                  #添加一个副本
rs.remove("localhost:27704")               #删除一个副本
rs.slaveOk()                               #当slave默认不允许读写时

 

分片(sharding)分布式存储

分片是指将数据拆分,分散存在不同机器上,有时也用分区(partitioning)来表示这个概念。分片之前运行一个路由进程mongos,将数据按某一键值(key)进行拆分,从而该进程可以知道所有数据的存放位置,所有应用可以连接它来发送请求,应用只知道自己连接了一个正常的mongod。

mongod --dbpath=D:\node1 --port 27801
mongod --dbpath=D:\node2 --port 27802
mongod --dbpath=D:\node3 --port 27803
mongod --dbpath=D:\configNode --port 27804 --configsvr     #开启config服务器
mongos --port 27805 --configdb=localhost:27804             #开启mongos服务器

config服务器与mongos服务器连接,里面存放数据与分片的对应关系。

接下来就是连接mongos初始化。

db.runCommand({"addshard":"localhost:27801",allowLocal:true})    
db.runCommand({"addshard":"localhost:27802",allowLocal:true}) 
db.runCommand({"addshard":"localhost:27803",allowLocal:true})   
#sh.addShard("localhost:27803")
db.runCommand({"enablesharding":"yumedb"})
#sh.enableSharding("yumedb")
db.runCommand({"shardcollection":"yumedb.person","key":{age:1}})    #以age作为区分,将yumedb这个数据库分片存储。
#sh.shardCollection("yumedb.person",{age:1})

for(var i=1;i<=40;i++) { sh.splitAt('yumedx.person',{userid:i*1000}) } 
#手动预先分片,预先切分好空的chunk,会均匀移动到各分片上,之后添加数据会自动存到预先分配好的chunk上。

allowLocal意思是可以允许应用直接连接分片服务器,yumedb是要分片的数据库。

 

分片结合副本集

以分片为主,每个分片配多个副本集。

sh.addShard("yumefx/localhost:27803")          #yumefx为副本集名称

 

其他

下面将一些其他常用操作也列举一下。

db.c1.insert({name:"yumefx",age:26})
db.c1.remove({name:"yumefx"},true)                          #删除第一个符合条件的
db.c1.update({age:26},{name:"yume"}})                       #结果是第一个数据的name被修改,age丢失
db.c1.update({age:26},{$set:{name:"yume"}})                 #结果是第一个数据的name被修改,age依然在
db.c1.update({age:26},{$set:{name:"yume"}},1,1)             #所有数据的name被修改,age不变
#第一个参数是搜索条件,第二个参数是要改成的数据,第三个参数是如果搜不到是否添加新数据,第四个参数是是否修改所有搜到的数据。
#$set设置,$unset删除,$inc加,$rename重命名。

比较运算符:
$gt(>),$gte(>=),$in(in),$lt(<),$lte(<=),$ne(!=),$nin(not in),$all(数组所有单元匹配),
$or(or),$and(and),$not(not),$nor(所有条件均不满足),
$exists(某列存在),$mod(满足某求余条件),$type
$where(js表达式为真),$regex(正则表达式匹配)。

db.c1.count()
db.c1.find({age:21} ).explain()                #展示查询时间等详细信息
db.c1.ensureIndex({age:1})                     #以age键值,建立索引

var i=db.c1.find({age:21})
i.next()
i.hasnext()

db.c1.find({age:{$gt:18}},{name:1,gender:1})       #查询所有年龄18的并列出姓名和性别

mongoexport -h localhost:27701 -d yumedb -c collection1 -o D:\collection1.xls                         #数据导出
mongoimport -h localhost:27701 -d yumedb -c  collection1 -o D:\collection1.xls                         #数据导入

mongodump -h localhost:27701 -d yumedb -o D:\dbbake      #数据库备份
mongorestore -h localhost:27701 -d yumedb -directoryperdb D:\dbbake\yumedb      #数据库恢复

db.createCollection("collectionName",{capped:true,size:10000,max:100})          #固定集合(固定大小或者条数,先进先出被覆盖)
size指定集合大小,单位KB,max指文档大小;当指定文档数量上限时,必须同时指定大小。

我并不期待人生过得很顺利,
但我希望碰到人生难关的时候,
自己可以是它的对手。

《加缪手记第三卷》
——阿尔贝·加缪