mon_godb集群

http://blog.csdn.net/luonanqin/article/details/8497860

http://blog.sina.com.cn/s/blog_3fe961ae01015aqw.html


  Mongodb是时下流行的NoSql数据库,它的存储方式是文档式存储,并不是Key-Value形式。关于Mongodb的特点,这里就不多介绍了,大家可以去看看官方说明:http://docs.mongodb.org/manual/


       今天主要来说说Mongodb的三种集群方式的搭建:Replica Set / Sharding / Master-Slaver。这里只说明最简单的集群搭建方式(生产环境),如果有多个节点可以此类推或者查看官方文档。OS是Ubuntu_x64系统,客户端用的是Java客户端。Mongodb版本是mongodb-linux-x86_64-2.2.2.tgz


Replica Set

       中文翻译叫做副本集,不过我并不喜欢把英文翻译成中文,总是感觉怪怪的。其实简单来说就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致。如下图:

       Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。

       默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,同时Java客户端提供了简单的配置方式,可以不必直接对数据库进行操作。

       仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。

介绍完了集群方案,那么现在就开始搭建了。


1.建立数据文件夹

一般情况下不会把数据目录建立在mongodb的解压目录下,不过这里方便起见,就建在mongodb解压目录下吧。

[plain] view plain copy
  1. mkdir -p /mongodb/data/master   
  2. mkdir -p /mongodb/data/slaver   
  3. mkdir -p /mongodb/data/arbiter    
  4. #三个目录分别对应主,备,仲裁节点  

2.建立配置文件

由于配置比较多,所以我们将配置写到文件里。

[plain] view plain copy
  1. #master.conf  
  2. dbpath=/mongodb/data/master  
  3. logpath=/mongodb/log/master.log  
  4. pidfilepath=/mongodb/master.pid  
  5. directoryperdb=true  
  6. logappend=true  
  7. replSet=testrs  
  8. bind_ip=10.10.148.130  
  9. port=27017  
  10. oplogSize=10000  
  11. fork=true  
  12. noprealloc=true  
[plain] view plain copy
  1. #slaver.conf  
  2. dbpath=/mongodb/data/slaver  
  3. logpath=/mongodb/log/slaver.log  
  4. pidfilepath=/mongodb/slaver.pid  
  5. directoryperdb=true  
  6. logappend=true  
  7. replSet=testrs  
  8. bind_ip=10.10.148.131  
  9. port=27017  
  10. oplogSize=10000  
  11. fork=true  
  12. noprealloc=true  
[plain] view plain copy
  1. #arbiter.conf  
  2. dbpath=/mongodb/data/arbiter  
  3. logpath=/mongodb/log/arbiter.log  
  4. pidfilepath=/mongodb/arbiter.pid  
  5. directoryperdb=true  
  6. logappend=true  
  7. replSet=testrs  
  8. bind_ip=10.10.148.132  
  9. port=27017  
  10. oplogSize=10000  
  11. fork=true  
  12. noprealloc=true  
参数解释:

dbpath:数据存放目录

logpath:日志存放路径

pidfilepath:进程文件,方便停止mongodb

directoryperdb:为每一个数据库按照数据库名建立文件夹存放

logappend:以追加的方式记录日志

replSet:replica set的名字

bind_ip:mongodb所绑定的ip地址

port:mongodb进程所使用的端口号,默认为27017

oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%

fork:以后台方式运行进程

noprealloc:不预先分配存储


3.启动mongodb

进入每个mongodb节点的bin目录下

  1. ./monood -f master.conf  
  2. ./mongod -f slaver.conf  
  3. ./mongod -f arbiter.conf  

注意配置文件的路径一定要保证正确,可以是相对路径也可以是绝对路径。


4.配置主,备,仲裁节点

可以通过客户端连接mongodb,也可以直接在三个节点中选择一个连接mongodb。

[plain] view plain copy
  1. ./mongo 10.10.148.130:27017   #ip和port是某个节点的地址  
  2. >use admin  
  3. >cfg={ _id:"testrs", members:[ {_id:0,host:'10.10.148.130:27017',priority:2}, {_id:1,host:'10.10.148.131:27017',priority:1},   
  4. {_id:2,host:'10.10.148.132:27017',arbiterOnly:true}] };  
  5. >rs.initiate(cfg)             #使配置生效  
       cfg是可以任意的名字,当然最好不要是mongodb的关键字,conf,config都可以。最外层的_id表示replica set的名字,members里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即这里的10.10.148.130:27017。特别注意的是,对于仲裁节点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。

      配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。如果生效了,执行rs.status()命令会看到如下信息:

[plain] view plain copy
  1. {  
  2.         "set" : "testrs",  
  3.         "date" : ISODate("2013-01-05T02:44:43Z"),  
  4.         "myState" : 1,  
  5.         "members" : [  
  6.                 {  
  7.                         "_id" : 0,  
  8.                         "name" : "10.10.148.130:27017",  
  9.                         "health" : 1,  
  10.                         "state" : 1,  
  11.                         "stateStr" : "PRIMARY",  
  12.                         "uptime" : 200,  
  13.                         "optime" : Timestamp(1357285565000, 1),  
  14.                         "optimeDate" : ISODate("2013-01-04T07:46:05Z"),  
  15.                         "self" : true  
  16.                 },  
  17.                 {  
  18.                         "_id" : 1,  
  19.                         "name" : "10.10.148.131:27017",  
  20.                         "health" : 1,  
  21.                         "state" : 2,  
  22.                         "stateStr" : "SECONDARY",  
  23.                         "uptime" : 200,  
  24.                         "optime" : Timestamp(1357285565000, 1),  
  25.                         "optimeDate" : ISODate("2013-01-04T07:46:05Z"),  
  26.                         "lastHeartbeat" : ISODate("2013-01-05T02:44:42Z"),  
  27.                         "pingMs" : 0  
  28.                 },  
  29.                 {  
  30.                         "_id" : 2,  
  31.                         "name" : "10.10.148.132:27017",  
  32.                         "health" : 1,  
  33.                         "state" : 7,  
  34.                         "stateStr" : "ARBITER",  
  35.                         "uptime" : 200,  
  36.                         "lastHeartbeat" : ISODate("2013-01-05T02:44:42Z"),  
  37.                         "pingMs" : 0  
  38.                 }  
  39.         ],  
  40.         "ok" : 1  
  41. }  
如果配置正在生效,其中会包含如下信息:
[plain] view plain copy
  1. "stateStr" : "RECOVERING"  

同时可以查看对应节点的日志,发现正在等待别的节点生效或者正在分配数据文件。

       现在基本上已经完成了集群的所有搭建工作。至于测试工作,可以留给大家自己试试。一个是往主节点插入数据,能从备节点查到之前插入的数据(查询备节点可能会遇到某个问题,可以自己去网上查查看)。二是停掉主节点,备节点能变成主节点提供服务。三是恢复主节点,备节点也能恢复其备的角色,而不是继续充当主的角色。二和三都可以通过rs.status()命令实时查看集群的变化。


Sharding

和Replica Set类似,都需要一个仲裁节点,但是Sharding还需要配置节点和路由节点。就三种集群搭建方式来说,这种是最复杂的。部署图如下:


1.启动数据节点

[plain] view plain copy
  1. ./mongod --fork --dbpath ../data/set1/ --logpath ../log/set1.log --replSet test #192.168.4.43  
  2. ./mongod --fork --dbpath ../data/set2/ --logpath ../log/set2.log --replSet test #192.168.4.44  
  3. ./mongod --fork --dbpath ../data/set3/ --logpath ../log/set3.log --replSet test #192.168.4.45 决策 不存储数据  

2.启动配置节点
[plain] view plain copy
  1. ./mongod --configsvr --dbpath ../config/set1/ --port 20001 --fork --logpath ../log/conf1.log #192.168.4.30  
  2. ./mongod --configsvr --dbpath ../config/set2/ --port 20002 --fork --logpath ../log/conf2.log #192.168.4.31  

3.启动路由节点
[plain] view plain copy
  1. ./mongos --configdb 192.168.4.30:20001,192.168.4.31:20002 --port 27017 --fork --logpath ../log/root.log #192.168.4.29  

       这里我们没有用配置文件的方式启动,其中的参数意义大家应该都明白。一般来说一个数据节点对应一个配置节点,仲裁节点则不需要对应的配置节点。注意在启动路由节点时,要将配置节点地址写入到启动命令里。


4.配置Replica Set

       这里可能会有点奇怪为什么Sharding会需要配置Replica Set。其实想想也能明白,多个节点的数据肯定是相关联的,如果不配一个Replica Set,怎么标识是同一个集群的呢。这也是人家mongodb的规定,咱们还是遵守吧。配置方式和之前所说的一样,定一个cfg,然后初始化配置。

[plain] view plain copy
  1. ./mongo 192.168.4.43:27017   #ip和port是某个节点的地址  
  2. >use admin  
  3. >cfg={ _id:"testrs", members:[ {_id:0,host:'192.168.4.43:27017',priority:2}, {_id:1,host:'192.168.4.44:27017',priority:1},   
  4. {_id:2,host:'192.168.4.45:27017',arbiterOnly:true}] };  
  5. >rs.initiate(cfg)             #使配置生效  


5.配置Sharding

[plain] view plain copy
  1. ./mongo 192.168.4.29:27017   #这里必须连接路由节点  
  2. >sh.addShard("test/192.168.4.43:27017") #test表示replica set的名字 当把主节点添加到shard以后,会自动找到set里的主,备,决策节点  
  3. >db.runCommand({enableSharding:"diameter_test"})    #diameter_test is database name  
  4. >db.runCommand( { shardCollection: "diameter_test.dcca_dccr_test",key:{"__avpSessionId":1}})   
       第一个命令很容易理解,第二个命令是对需要进行Sharding的数据库进行配置,第三个命令是对需要进行Sharding的Collection进行配置,这里的dcca_dccr_test即为Collection的名字。另外还有个key,这个是比较关键的东西,对于查询效率会有很大的影响,具体可以查看 Shard Key Overview

       到这里Sharding也已经搭建完成了,以上只是最简单的搭建方式,其中某些配置仍然使用的是默认配置。如果设置不当,会导致效率异常低下,所以建议大家多看看官方文档再进行默认配置的修改。


Master-Slaver

这个是最简答的集群搭建,不过准确说也不能算是集群,只能说是主备。并且官方已经不推荐这种方式,所以在这里只是简单的介绍下吧,搭建方式也相对简单。

[plain] view plain copy
  1. ./mongod --master --dbpath /data/masterdb/      #主节点  
  2.   
  3. ./mongod --slave --source <masterip:masterport> --dbpath /data/slavedb/     备节点  
       基本上只要在主节点和备节点上分别执行这两条命令,Master-Slaver就算搭建完成了。我没有试过主节点挂掉后备节点是否能变成主节点,不过既然已经不推荐了,大家就没必要去使用了。


       以上三种集群搭建方式首选Replica Set,只有真的是大数据,Sharding才能显现威力,毕竟备节点同步数据是需要时间的。Sharding可以将多片数据集中到路由节点上进行一些对比,然后将数据返回给客户端,但是效率还是比较低的说。

       我自己有测试过,不过具体的机器配置已经不记得了。Replica Set的ips在数据达到1400w条时基本能达到1000左右,而Sharding在300w时已经下降到500ips了,两者的单位数据大小大概是10kb。大家在应用的时候还是多多做下性能测试,毕竟不像Redis有benchmark。

       Mongodb现在用的还是比较多的,但是个人觉得配置太多了。。。。我看官网都看了好多天,才把集群搭建的配置和注意要点弄明白。而且用过的人应该知道mongodb吃内存的问题,解决办法只能通过ulimit来控制内存使用量,但是如果控制不好的话,mongodb会挂掉。。。



启动mongod服务

service mongod start


输入mongo进行操作:


use cnblogs    // use 命令用来切换当前数据库,如果该数据库不存在,则会先新建一个。


db.users.insert({'name':'xumingxiang','sex':'man'})
// 这条命令是向users 集合中插入一条数据。如果集合users不存在,则会先新建一个,然后再插入数据,参数以JSON格式传入。

show dbs              // 显示所有数据库

show collections       // 显示当前数据库下的所有集合

db.users.find()        // 显示users集合下的所有数据文档

db.users.update({'name':'xiangshu'},{'$set':{'sex':'women'}},upsert=true,multi=false)
upsert:如果不存在则插入
multi:是否允许修改多条记录

db. users.remove({'name':'xumingxiang'})

删除所有记录
db.users.remove()

删除collection
db.users.drop()

删除当前数据库

db.dropDatabase()


use admin         (切换到创建用户)
db.addUser(“userName”,”Pwd”)    创建用户
db.auth(“userName”,”Pwd”)       设置用户为允许连接的用户
db.createCollection(“TableName”)                                     创建表


使用密码访问

use admin

db.addUser("admin","admin")  #这里一定设置密码,不然test数据库设置的密码无效

db.auth("admin","admin")

use test

db.addUser("test","test")


=============================其他命令================================
db.AddUser(username,password)  添加用户
db.auth(usrename,password)     设置数据库连接验证
db.cloneDataBase(fromhost)     从目标服务器克隆一个数据库
db.commandHelp(name)           returns the help for the command
db.copyDatabase(fromdb,todb,fromhost)  复制数据库fromdb---源数据库名称,todb---目标数据库名称,fromhost---源数据库服务器地址
db.createCollection(name,{size:3333,capped:333,max:88888})  创建一个数据集,相当于一个表
db.currentOp()                 取消当前库的当前操作
db.dropDataBase()              删除当前数据库
db.eval(func,args)             run code server-side
db.getCollection(cname)        取得一个数据集合,同用法:db['cname'] or
db.getCollenctionNames()       取得所有数据集合的名称列表
db.getLastError()              返回最后一个错误的提示消息
db.getLastErrorObj()           返回最后一个错误的对象
db.getMongo()                  取得当前服务器的连接对象get the server
db.getMondo().setSlaveOk()     allow this connection to read from then nonmaster membr of a replica pair
db.getName()                   返回当操作数据库的名称
db.getPrevError()              返回上一个错误对象
db.getProfilingLevel()         
db.getReplicationInfo()        获得重复的数据
db.getSisterDB(name)           get the db at the same server as this onew
db.killOp()                    停止(杀死)在当前库的当前操作
db.printCollectionStats()      返回当前库的数据集状态
db.printReplicationInfo()
db.printSlaveReplicationInfo()
db.printShardingStatus()       返回当前数据库是否为共享数据库
db.removeUser(username)        删除用户
db.repairDatabase()            修复当前数据库
db.resetError()                
db.runCommand(cmdObj)          run a database command. if cmdObj is a string, turns it into {cmdObj:1}
db.setProfilingLevel(level)    0=off,1=slow,2=all
db.shutdownServer()            关闭当前服务程序
db.version()                   返回当前程序的版本信息
 
db.test.find({id:10})          返回test数据集ID=10的数据集
db.test.find({id:10}).count()  返回test数据集ID=10的数据总数
db.test.find({id:10}).limit(2) 返回test数据集ID=10的数据集从第二条开始的数据集
db.test.find({id:10}).skip(8)  返回test数据集ID=10的数据集从0到第八条的数据集
db.test.find({id:10}).limit(2).skip(8)  返回test数据集ID=1=的数据集从第二条到第八条的数据
db.test.find({id:10}).sort()   返回test数据集ID=10的排序数据集
db.test.findOne([query])       返回符合条件的一条数据
db.test.getDB()                返回此数据集所属的数据库名称
db.test.getIndexes()           返回些数据集的索引信息
db.test.group({key:...,initial:...,reduce:...[,cond:...]})
db.test.mapReduce(mayFunction,reduceFunction,<optional params>)
db.test.remove(query)                      在数据集中删除一条数据
db.test.renameCollection(newName)          重命名些数据集名称
db.test.save(obj)                          往数据集中插入一条数据
db.test.stats()                            返回此数据集的状态
db.test.storageSize()                      返回此数据集的存储大小
db.test.totalIndexSize()                   返回此数据集的索引文件大小
db.test.totalSize()                        返回些数据集的总大小
db.test.update(query,object[,upsert_bool]) 在此数据集中更新一条数据
db.test.validate()                         验证此数据集
db.test.getShardVersion()                  返回数据集共享版本号
 
六,MongoDB语法与现有关系型数据库SQL语法比较
MongoDB语法                                   MySql语法
db.test.find({'name':'foobar'}) <==> select * from test where name='foobar'
db.test.find()                  <==> select * from test
db.test.find({'ID':10}).count() <==> select count(*) from test where ID=10
db.test.find().skip(10).limit(20)     <==> select * from test limit 10,20
db.test.find({'ID':{$in:[25,35,45]}}) <==> select * from test where ID in (25,35,45)
db.test.find().sort({'ID':-1})        <==> select * from test order by ID desc
db.test.distinct('name',{'ID':{$lt:20}})  <==> select distinct(name) from test where ID<20
db.test.group({key:{'name':true},cond:{'name':'foo'},reduce:function(obj,prev){prev.msum+=obj.marks;},initial:{msum:0}})  <==> select name,sum(marks) from test group by name
db.test.find('this.ID<20',{name:1})  <==> select name from test where ID<20
db.test.insert({'name':'foobar','age':25})<==>insert into test ('name','age') values('foobar',25)
db.test.remove({})                <==> delete * from test
db.test.remove({'age':20})        <==> delete test where age=20
db.test.remove({'age':{$lt:20}})  <==> elete test where age<20
db.test.remove({'age':{$lte:20}}) <==> delete test where age<=20
db.test.remove({'age':{$gt:20}})  <==> delete test where age>20
db.test.remove({'age':{$gte:20}}) <==> delete test where age>=20
db.test.remove({'age':{$ne:20}})  <==> delete test where age!=20
db.test.update({'name':'foobar'},{$set:{'age':36}}) <==> update test set age=36 where name='foobar'
db.test.update({'name':'foobar'},{$inc:{'age':3}})  <==> update test set age=age+3 where name='foobar'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值