数据库

 首页 > 数据库 > MongoDB > MongoDB数据库集群的配置与使用

MongoDB数据库集群的配置与使用

分享到:
【字体:
导读:
         摘要:一、数据备份最流行保险的办法是使用master-slave模式,然后在slave机器上先获得写入锁,让其他不能再写入,然后备份所有数据文件再解锁,这样不会影响master在系统中的使用一般需要备份的slave的机器可以加上延时同步MongoDB的replication机制除了最普通...

MongoDB数据库集群的配置与使用

一、数据备份
最流行保险的办法是使用master-slave模式,然后在slave机器上先获得写入锁,让其他不能再写入,然后备份所有数据文件再解锁,这样不会影响master在系统中的使用
一般需要备份的slave的机器可以加上延时同步


MongoDB 的replication机制除了最普通的Master/Slave模式之外,更强大的就是其支持自动故障转移的Replica Sets模式了


二、配置master、slave模式

如果我们要启用Master/Slave模式,而且开启了Auth功能
则需要同时在Master和Slave上的local数据库上增加一名为repl的用户和密码:
use local
db.addUser('repl','password')
 
在master需要加上oplogSize选项,指定日志大小
--oplogSize命令行参数(与--master一同使用)配置用于存储给从节点可用的更新信息占用的磁盘空间(M为单位),如果不指定这个参数,默认大小为当前可用磁盘空间的5%(64位机器最小值为1G,32位机器为50M)。

1、从机器第一次启动(默认情况下第一次启动系统会自动从master机器复制文件到slave,但是如果数据库很大,会非常耗时)
slave第一次启动时最好是用scp命令把主机器的mongodb的所有目录和文件远程拷贝
到从机器上去,,否则启动从的时候会报错(mongodb ERROR: Client::~Client _context should be null but is not; client:replslave)
如果出现这个错误, 只需要把数据文件data目录下的所有文件删除,重新启动即可

2、在slave从数据库服务器上查看是否和主机连接配置正确
db.printSlaveReplicationInfo();
如果成功将会出现以下信息
    source:   172.16.2.213:556600
    syncedTo: Fri Mar 26 2010 12:55:19 GMT+0800
         = 33390 secs ago (9.27hrs)(表示最近的一次同步是在9个多小时以前)
  
3、最好不要加--slavedelay延迟,这样的话当插入数据从slave查询时会查不到,如果定义了该值系统可能会延迟的时间不止设置的值
一般是把slave做为延时备份,不需要实时查询时可以使用该参数

4、--autoresync=true 参数会在系统发生意外情况造成主从数据不同步时,可使从节点在不同步情况发生10秒钟之后,自动重启复制操作(从节点在10分钟以内自动重新同步数据的操作只会执行一次)。
(该参数仅能保证在slave down机期间master的所有操作在oplog中都能记录下,如果slave down机时间太长,oplog里的记录都有给覆盖了___因为oplog是固定大小的,那么就只能进行全量的复制)
如何判断是否需要全部重新同步:
在master机器执行
db.printReplicationInfo()
configured oplog size:   47.6837158203125MB
log length start to end: 262641secs (72.96hrs)
oplog first event time:  Sun Nov 27 2011 13:42:45 GMT+0800 (CST)
oplog last event time:   Wed Nov 30 2011 14:40:06 GMT+0800 (CST)
now:                     Wed Nov 30 2011 14:40:09 GMT+0800 (CST)
它会显示oplog日志的开始时间,结束时间
在slave机器执行
>db.printReplicationInfo()
this is a slave, printing slave replication info.
source:   10.10.9.116:27017
         syncedTo: Wed Nov 30 2011 14:40:06 GMT+0800 (CST)
                 = 95 secs ago (0.03hrs)
它记录slave机器同步的最后时间,如果该时间在master机器的oplog first event time, oplog last event time范围之内,表示可以通过oplog进行继续同步;否则就只能全量重新同步
               
5、全量复制
当新加一台slave机器或slave down的时间太久,master中的oplog没有记录下所有的操作时需要进行全部的复制
有下面2种方法
  A、可以把slave /data/db下的需复制的数据库数据文件全部删掉,以非slave模式启动mongod将local里source的记录清空,再以slave启动时它会自动进行复制,但是但数据特别大的时候会很慢
  B、把master上/data/db需要同步的库对应的所有数据文件拷贝到slave机器上,然后在slave启动时加上fastsync=true参数,重启slave机器会自动复制(在拷贝过程中master进行的操作也会在启动时同步到slave)这种方式适合处理db数据很大的情况,速度很快
     必须先把master killall 然后再拷贝数据,否则拷贝的数据有可能是不正确的
     如果不想killall master,那么就需要使用 fsync and lock的方式进行安全拷贝

6、该种配置slave机器只能进行读,如果进行写就会出错:
Exception in thread "main" com.mongodb.MongoException: not master

7、它不能进行故障自动转移,适用于mongodb低版本(<1.6) 在高版本中使用下面的方式进行复制,他能进行故障自动转移

8、典型配置
master的配置
port = 27017
master = true
fork = true
auth = true
journal = true
dbpath = /data/db
logpath = /var/log/mongodb.log
logappend = true
oplogSize = 500   #单位是M

slave的配置
port = 27017
slave = true
source = 10.10.9.116:27017
only = zqc_db
autoresync = true
fastsync=true
fork = true
auth = true
journal = true
dbpath = /data/db
logpath = /var/log/mongodb.log


三、Replica Sets(副本级)模式______官方推荐
http://www.mongodb.org/display/DOCS/Replica+Set+Configuration介绍了该种方式的配置详情


数据库自动协调某个时间点上的主从关系。开始的时候,数据库会判断哪个是从哪个是主,一旦主服务器负载过高或down掉,另一台就会自动成为主服务器
启动mongod时需要如下参数
port = 10001
rest=true
replSet=zqc (set集名字)
fork = true
journal = true
dbpath = /data/db_1
logpath = /var/log/mongodb_1.log
logappend = true
在116,117上启动4个mongodb实例,其中三个作为完成数据库,一个作为arbiter,arbiter只参与投票,不存储具体数据
在任意机器上mongo让后初始化
>cfg = { _id: "zqc", members: [
... { _id:0, host:"10.10.9.116:10001" },
... { _id:1, host:"10.10.9.116:10002" },
... { _id:2, host:"10.10.9.117:10001"},
{ _id:3, host:"10.10.9.117:10002",arbiterOnly:true}
... ]}

>rs.initiate(cfg)

通过rs.status()来查看集群状态


可以动态的修改节点属性(必须在当前的primary节点上执行)如果在secondary节点上执行必须加上force--->rs.reconfig(c,{force:true});



 // we should be primary here.  can be checked with rs.status() or with:
> rs.isMaster();
>
> // view existing config
> var c = rs.conf();
{_id: 'foo', members: [
                       {_id: 0, host: 'localhost:27017'},
                       {_id: 1, host: 'localhost:27018'},
                       {_id: 2, host: 'localhost:27019'}]
}
>
> // reconfig
> c.members[2].priority = 0;
> c
{_id: 'foo', members: [
                       {_id: 0, host: 'localhost:27017'},
                       {_id: 1, host: 'localhost:27018'},
                       {_id: 2, host: 'localhost:27019', priority: 0}]
}
> rs.reconfig(c);
> // done. to see new config,and new status:
> rs.conf()
> rs.status()


上面是修改一个节点的priority=0 (表示该节点只能作为secondary节点,不能作为primary节点,即使在没有任何primary节点的时候)

可以通过如下方式动态增加、减少节点,增加裁判
rs.addArb("10.10.9.117:27017");//增加仲裁
rs.add("10.10.9.117:27017");增加节点
如果有更多的配置项,按下面方式增加
> // add an arbiter
> rs.add({_id: 3, host: "10.10.9.117:27017", arbiterOnly: true})
>
> // add a hidden member
> rs.add({_id: 3, host: "10.10.9.117:27017", priority: 0, hidden: true})
>
> // add a member with tags
> rs.add({_id: 3, host: "10.10.9.117:27017", tags: {dc : "nyc", rack: "rack1"}})

通过如下链接查看ReplicaSet对应的命令项
http://www.mongodb.org/display/DOCS/Replica+Set+Commands

不要去试图改变每个节点的votes,如果想要设置首选的master,那么通过修改节点的priorities值
不要去修改每个节点的votes值,更好的做法是使用仲裁者
默认情况下,每个members成员拥有1票;必须获得大多数的投票才能成为primary节点;
大多数的定义是memembrs成员数/2+1
比如我配置有3个members,其中2个server,1个arbiter,当其中一个server down掉后,剩余的1个server+arbiter拥有2票
他们可以把剩下的一个server选为primarty,因为它能达到大多数票数(3/2+1)
如果我配置了4个members,其中3个server,1个arbiter,当其中一个server down掉后,剩下的能选出primarty ,但是如果有2个server down掉后
只剩下一个server+1个arbiter拥有2票,小于大多数票数的要求(4/2+1) 这时剩下的一个server始终不能成为primary,也就是说这时系统只能读,不能写
一般系统配置是2个server+1个arbiter


在该模式下,如果在secondary的shell中运行查询会报如下错误:
13435 not master and slaveok=false
所以在secondary的shell中想运行查询按下面方式运行:
rs.slaveOk(); // enable querying a secondary
db.users.find(...)


 

客户端使用如下方式进行连接:

   client端可以与Replica Sets中的任一member进行连接,也可以指定所有members进行连接,

   连接原理:

   1、先指定需要连接服务地址(一个或多个

   2、分别连接服务地址中的地址,发送db.isMaster()的请求,只要有一个server返回了信息,client不再去试图连接其他server

  3、通过server返回的信息,client就会确切的知道Replica Sets中的所有机器部署:哪台机器是primary,那些机器是seconary,哪些机器是仲裁;然后client再向master机器发送一条确认信息,确认其当前是否是primary

  4、该种方式会确保failover,当某台机器down掉,client会试着去访问剩下的server,同样可以得到Replica Sets的信息,所以某台server机器的down掉或身份转移(primary转成secondary等等)并不会影响client端

  5、最好是在client配置Replica Sets中的所有机器(可以不配仲裁),如果只配置一台,当刚好这台机器down掉,client端将无法再连到Replica Sets 

 
四、分片
基础配置,参见"http://www.w3ccollege.org/index/cluster-structures-mongodb-sharding.html"
可以登录mongs,使用sh.help()来查看分片命令信息

使用体验:
   只有表记录很大的才需要分片,在db中可以部分collection分片,部分不分
   所有分片信息都存储在config中,可以登录config的mongod,
   use config
   db.chunks.find();查看,它里面记录了每个块存放在哪个片上
   配置服务器和分片数据服务器之间没有任何的物理连接关系。他们之间的逻辑关系也完全通过路由服务器来建立
   配置服务器只能是奇数个。可以是一个,也可以3个
   可以登录mongos,通过db.collection.stats()来查看该collection的具体分片情况
   常用命令:
   登录mongos
   sh.addShard("shardName/arete:30000,arete:30001"); 增加分片
   sh.status() 列出当前分片信息
   sh.enableSharding("testdb")  让一个db能够支持分片
   db.runCommand({"removeshard" : "localhost:20002"});移除某个分片,移除分片时系统会自动把该片上的数据平均分配到其他片上,数据移除完成后最终把该片踢下线
   //注意在移除前要先判断该shard是否是主分片
   use config
 > db.databases.find()
 { "_id" : "cloud-docs", "partitioned" : true, "primary" : "shardA" }
   如果是主分片,要先进行移动
   db.runCommand({removeshard: "shard-1/arete:30100,arete:30101"})
   然后再进行移除分片
  
     
  
   sh.shardCollection("db.collection", {username: 1, _id: 1})// 对某个collection进行分片
   初始通过mongos建立的collection是不会分片的,他们会始终存到一台机器上)我,们需要不停的调用db.runCommand({"removeshard" : "localhost:20002"});来观察这个移除操作进行到哪里了
   初始通过mongos建立的database也是不会分片的,他们始终会存在开始创建的那台机器上,除非调用db.runCommand({enablesharding:’test’})及对应的表分片
   use config
   db.changelog.find({what: "moveChunk.commit"}) //查看分片块移动信息
  
   分片的collection只允许在_id或shard key上建立唯一索引,其它键能建索引但不能建唯一索引
 
 shard key:选择原则
      尽量不要使用_id作为key,因为默认情况下,递增的_id,会连续放入一个chunk中,也就是最近的多次插入基本上是会往一个shard里插数据,没有达到负载均衡的目地
      但是完全随机的shard key,会消耗掉更多的 shard 内存,因为每次插入的都要建索引,而随机的是key是无序的,而有序的id创建时索引消耗的内存更小
      完全随机的shard key还有一个问题,任何的查询都会去查询所有的shard,减低了性能
      一般根据业务逻辑进行选择,比如存储用户照片,那么就选择user_id,作为shard key,但是使用user_id会出现当一个用户数据超过chunk的大小时也继续存在单一的shard中
      这样就达不到均衡效果,所以理想的做法是使用 userid:1,_id:1联合作为shard key,大部分用户的数据是只会存在具体的一个shard中,对于部分数据量很大的用户也会
      根据id进行分块,存到不同的shard中
     

MongoDB数据库集群的配置与使用
分享到:
部署高可用MongoDB服务器集群(一)
部署高可用MongoDB服务器集群(一) 在大数据的时代,传统的关系型数据库要能更高的服务必须要解决高并发读写、海量数据高效存储、高可扩展性和高可用性这些难题。不过就是因为这些问题Nosql诞生了。 NOSQL有这些优势: 大数据量,可以通过廉价服务器存储大量的数据,轻松摆脱传统mysql单表存储量级限制。 高扩展...
MongoDB数据库查询指南
MongoDB数据库查询指南 1.多查询条件 向查询文档加入多个键/值对的方式可以实现多个查询条件的组合。例如要查询所有用户名为“joe”且年龄为27岁的用户,可以像下面这样:  >db.users.find({“username” : “joe”, “age” : 27}) 2.指定返回结果的键 例如,如果只需要用户集合的“username”和“email”...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……