依然饭跑跑 发表于 2018-10-26 13:44:35

mongoDB主从和副本集群配置

mongoDB主从和副本集群配置
  Mongodb是时下流行的NoSql数据库(MongoDB是一个基于分布式文件存储的数据库),它的存储方式是文档式存储,并不是Key-Value形式。
  
  优势:
  快速!(当然,这和具体的应用方式有关,通常来说,它比一般的关系型数据库快5位左右。)
  很高的可扩展性–轻轻松松就可实现PB级的存储(但是可能我们并不需要PB级的存储,10TB可能就够了)
  他有一个很好的 replication 模式 (replica sets)
  有很完善的Java API
  他的存储格式是Json的,这对Java来说非常好处理,对javascirpt亦然。
  运维起来非常方便,你不用专门为它安排一个管理员。
  它有一个非常活跃的社区(我提出的一个bug在20分钟内就能得到修复。多谢Elliot)
  他的版本控制非常清楚。
  MongoDB 背后的公司(10gen)已经准备好了明天在 MongoDB 上面的投入的资金了。
  劣势
  应用经验缺乏,我们都没有相关NoSQL 产品的使用经验。
  项目相对来说还比较新。
  和以往的存储相比,数据的关系性操作不再存在。
  
  
  版本历史
  时间
  版本
  说明
  编写者
  2014-07-25
  1.0
  mondoDB主从和副本集群配置
  csc
  2014-11-5
  1.1
  mondoDB主从和副本集群配置-修改
  csc
一、配置mongoDB主从集群
1、介绍:
  服务器资源有限,主从服务 都部署在一台服务器上面,开启不同的端口运行。
  该集群优点:master 读写,slave读 可以减轻master 的压力,数据做冗余备份
  缺点: 主master挂了之后,服务不能自动切换到从slave,存在单点故障
  mv mongodb-linux-x86_64-1.6.5.tgz /usr/local/
  cd /usr/local/
  tar -xvzf mongodb-linux-x86_64-1.6.5.tgz
2、配置master 服务:
  cp -rmongodb-linux-x86_64-1.6.5mongodb-01
  mkdir-p /usr/local/mongodb-01/data/master
  #/usr/local/mongodb-01/bin/mongod--dbpath=/usr/local/mongodb-01/data/master --port=10000--master --logpath=/usr/local/mongodb-01/data/mongodb.log --rest &
  或者写入配置文档master.conf:
  1.port = 27017
  2.dbpath = /data/db
  3.logpath = /var/log/mongodb.log
  4.logappend = true
  5.journal = true
  6.pidfile = /var/run/mongodb.pid
  7.fork = true
  8.master = true
  9.
  10.启动方式:./mongod -f master.conf
  11.
  12.关闭方式
  13../ mongod--shutdown -f master.conf
  14.
  15.
  启动后测试是否正常运行:
  #/usr/local/mongodb-01/bin/mongo 127.0.0.1:10000
  MongoDB shell version: 1.6.5
  connecting to: 127.0.0.1:10000/test
  > show dbs;
  admin
  local
3、配置slave 服务:
  cp -rmongodb-linux-x86_64-1.6.5mongodb-02
  mkdir-p /usr/local/mongodb-01/data/slave
  /usr/local/mongodb-02/bin/mongod--dbpath=/usr/local/mongodb-02/data/slave --port=10001--slave --source=localhost:10000 --logpath=/usr/local/mongodb-02/data/mongodb.log--rest
  或者写入配置文档(slave.conf):
  1.port=27017
  2.dbpath = /data/db
  3.logpath = /var/log/mongodb.log
  4.logappend = true
  5.journal = true
  6.fork = true
  7.slave = true
  8.source = 10.11.20.140:27017
  9.
  10.启动方式:./mongod -f master.conf
  11.
  启动后测试是否正常运行:
  #/usr/local/mongodb-02/bin/mongo 127.0.0.1:10001
  MongoDB shell version: 1.6.5
  connecting to: 127.0.0.1:10001/test
  > show dbs;
  admin
  local
4、测试主从功能:
  登入 slave 创建表:
  创建一个“myTest”的数据库,
  先运行use myTest命令,之后就做一些操作(如:db.createCollection('user')),这样就可以创建一个名叫“myTest”的数据库。
  在从服务上面创建数据库myTest;
  /usr/local/mongodb-02/bin/mongo 127.0.0.1:10001
  > use mytest
  switched to db mytest
  > db.createCollection('user')
  { "errmsg" : "not master", "ok" :0 }
  报错信息显示该服务不是主服务,不能插入数据。
  但是能查询数据:
> show dbs;
  admin
  local
在主服务上面创建数据库myTest
  /usr/local/mongodb-01/bin/mongo 127.0.0.1:10000
  > use mytest
  switched to db mytest
  > db.createCollection('user')
  { "ok" : 1 }
  从服务器查询数据库,看是否该库同步过来。如果从服务器没有查询到该库,则检查服务的正确性。
  > show dbs;
  admin
  local
  myTest
  test
查询数据库状态:
  > db.version();
  1.6.5
> db.stats();
  {
  "collections" : 3,
  "objects" : 4,
  "avgObjSize" : 51,
  "dataSize" : 204,
  "storageSize" : 16384,
  "numExtents" : 3,
  "indexes" : 1,
  "indexSize" : 8192,
  "fileSize" : 201326592,
  "ok" : 1
  }
查看当前db的链接机器地址
  > db.getMongo();
  connection to 127.0.0.1:10000
创建用户
  > db.addUser('names');
  {
  "user" :"names",
  "readOnly" : false,
  "pwd" :"29cdbdd1255032d35e099aa7ebf8c3f9"
  }
查看用户
  > show users;
  {
  "_id" :ObjectId("53d0bcfaafa6df02ce900daf"),
  "user" :"names",
  "readOnly" : false,
  "pwd" :"29cdbdd1255032d35e099aa7ebf8c3f9"
  }
查看数据
  db.test_1.find();
创建数据:
  db.test_1.save({id:1});
创建新的数据库
  我们通过使用“use new-databasename”的语法去使用一个新的数据库,注意,即使你的数据库还没建立起来,依然可以这样使用,因为mongodb会在真正插入了数据后,才会真正建立起来。
  >use mkyongdb
  switched to db mkyongdb
  > show dbs
  admin   0.03125GB
  local   (empty)
  注意,在use mkyongdb后,mkyongdb实际上还没真正建立起来,只是表明目前是在使用mkyongdb了。
保存数据
  定义一个collection,名为“users”,然后插入数据,如下:
  db.users.save({username:"mkyong"} )
  db.users.find()
  { "_id" : ObjectId("4dbac7bfea37068bd0987573"),"username" : "mkyong" }
  db.users.count();
  1
  show dbs
  admin   0.03125GB
  local   (empty)
  mkyongdb      0.03125GB
关闭mongoDB
  # ./mongod --shutdown -f../data/slaver.conf
  不推荐用kill方法杀掉进程
  杀掉之后,如果要重启,请先删除掉 *.pid文件
二、配置mongoDBReplicaSet (副本集)
  集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致。如下图:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。
  默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做ReadPreference Modes,同时Java客户端提供了简单的配置方式,可以不必直接对数据库进行操作。
  仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。
  介绍完了集群方案,那么现在就开始搭建了。
1.建立数据文件夹
  一般情况下不会把数据目录建立在mongodb的解压目录下,不过这里方便起见,就建在mongodb解压目录下吧。
   viewplaincopy
  10.10.148.130   mkdir -p /mongodb/data/master
  10.10.148.131 mkdir -p /mongodb/data/slaver
  10.10.148.132   mkdir -p /mongodb/data/arbiter
  #三个目录分别对应主,备,仲裁节点
2.建立配置文件
  由于配置比较多,所以我们将配置写到文件里。
  10.10.148.130 master 服务器配置:
   viewplaincopy
  #master.conf
  dbpath=/mongodb/data/master
  logpath=/mongodb/log/master.log
  pidfilepath=/mongodb/master.pid
  directoryperdb=true
  logappend=true
  replSet=testrs
  bind_ip=10.10.148.130
  port=27017
  oplogSize=10000
  fork=true
  noprealloc=true
  
   viewplaincopy
  10.10.148.131slaver服务器配置:
  #slaver.conf
  dbpath=/mongodb/data/slaver
  logpath=/mongodb/log/slaver.log
  pidfilepath=/mongodb/slaver.pid
  directoryperdb=true
  logappend=true
  replSet=testrs
  bind_ip=10.10.148.131
  port=27017
  oplogSize=10000
  fork=true
  noprealloc=true
  
  
   viewplaincopy
  10.10.148.132arbiter服务器配置:
  #arbiter.conf
  dbpath=/mongodb/data/arbiter
  logpath=/mongodb/log/arbiter.log
  pidfilepath=/mongodb/arbiter.pid
  directoryperdb=true
  logappend=true
  replSet=testrs
  bind_ip=10.10.148.132
  port=27017
  oplogSize=10000
  fork=true
  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目录下
   viewplaincopy
  ./monood -f master.conf
  ./mongod -f slaver.conf
  ./mongod -f arbiter.conf
  注意配置文件的路径一定要保证正确,可以是相对路径也可以是绝对路径。r
  如果要开启图形界面管理,则后面加上 --rest 启动
  如:
  ./monood -f master.conf --rest
4.配置主,备,仲裁节点
  方法一:添加节点时候,同时设置优先级,指定节点类型
  可以通过客户端连接mongodb,也可以直接在三个节点中选择一个连接mongodb。
  随便在一个终端进行,这个终端会被当成primary节点,但是需要把该终端的优先级设置高。
  priority 数字越大,优先级越高
   view plaincopy
  ./mongo 10.10.148.130:27017   #ip和port是某个节点的地址
  >use admin
  >cfg={ _id:"testrs", members:[ {_id:0,host:'10.10.148.130:27017',priority:2}, {_id:1,host:'10.10.148.131:27017',priority:1},
  {_id:2,host:'10.10.148.132:27017',arbiterOnly:true}] };
  >rs.initiate(cfg)             #使配置生效
  方法二:只添加节点,后期设置或者更改优先级和节点类型(不做介绍)
  #####################以下可忽略#################################
  版本为:2.4.3 按照上诉方法设置通过。
  版本为:1.76 的设置过程会报错:
  errmsg" : "couldn't parse cfgobject bad config for member this version of mongod only supports priorities0 and 1",
  配置的时候报错,只支持0跟1 的优先级
  随便在一个终端进行,这个终端会被当成primary节点,因此连接的这个终端priority优先级要设置高,如果设置成 priority:0,primary节点会报错:
  备注:Priority为0的节点永远不能成为主节点,所以设置Secondary-only节点只需要将其priority设置为0.
  errmsg" : "couldn't initiate :initiation and reconfiguration of a replica set must be sent to a node that canbecome primary",
  >cfg={_id:"testrs", members:[ {_id:0,host:'127.0.0.1:10001',priority:1},{_id:1,host:'127.0.0.1:10002',priority:0},{_id:2,host:'127.0.0.1:10003',arbiterOnly:true}] };
  >rs.initiate(cfg)             #使配置生效
  ############################################################################
  cfg是可以任意的名字,当然最好不要是mongodb的关键字,conf,config都可以。最外层的_id表示replicaset的名字,members里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即这里的10.10.148.130:27017。特别注意的是,对于仲裁节点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。
  配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。如果生效了,执行rs.status()命令会看到如下信息:
   viewplaincopy
  {
  "set" : "testrs",
  "date" : ISODate("2013-01-05T02:44:43Z"),
  "myState" : 1,
  "members" : [
  {
  "_id" : 0,
  "name" : "10.10.148.130:27017",
  "health" : 1,
  "state" : 1,
  "stateStr" : "PRIMARY",
  "uptime" : 200,
  "optime" : Timestamp(1357285565000, 1),
  "optimeDate" : ISODate("2013-01-04T07:46:05Z"),
  "self" : true
  },
  {
  "_id" : 1,
  "name" : "10.10.148.131:27017",
  "health" : 1,
  "state" : 2,
  "stateStr" : "SECONDARY",
  "uptime" : 200,
  "optime" : Timestamp(1357285565000, 1),
  "optimeDate" : ISODate("2013-01-04T07:46:05Z"),
  "lastHeartbeat" : ISODate("2013-01-05T02:44:42Z"),
  "pingMs" : 0
  },
  {
  "_id" : 2,
  "name" : "10.10.148.132:27017",
  "health" : 1,
  "state" : 7,
  "stateStr" : "ARBITER",
  "uptime" : 200,
  "lastHeartbeat" : ISODate("2013-01-05T02:44:42Z"),
  "pingMs" : 0
  }
  ],
  "ok" : 1
  }
  如果配置正在生效,其中会包含如下信息:
   viewplaincopy
  "stateStr" : "RECOVERING"
  同时可以查看对应节点的日志,发现正在等待别的节点生效或者正在分配数据文件。
5.备注--笔记:      
1增节点到副本中。
  新增加一台服务加入到副本集中:
  rs.add('192.168.200.25:27017')
  
  加入后,执行,rs.status(); 显示:"errmsg" : "initial sync pending"显示初始化过程中,一会儿后正常。
2删除副本中的节点:
  rs.remove('192.168.200.25:27017')
3查看副本集的状态
  rs.status()
  db.isMaster();    查看主备(从)节点的状态
4.操作Secondary
  默认情况下,Secondary是不提供服务的,即不能读和写。会提示:
  error: { '$err' : 'not master and slaveOk=false', 'code' : 13435 }
  在特殊情况下需要读的话则需要执行命令:
  rs.slaveOk() ,只对当前连接有效。
5.关闭节点命令
  051.mmm:PRIMARY> use admin
  052.switched to db admin
  053.mmm:PRIMARY> db.shutdownServer()
  054.
  或者见目录一关闭mongodb
6.备注、仲裁节点
  所有的Secondary都宕机、或则副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群智能进行读操作而不能进行写操作,当其他的恢复时,之前的primary节点仍然是primary节点。
  当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。
  官方推荐的最小的副本集也应该具备一个primary节点和两个secondary节点,或者1个primary节点和1个secondary节点,加上一个arbiter节点。两个节点的副本集不具备真正的故障转移能力。
  1 primary+2 secondary 或者1 primary + 1secondary + 1 arbiter
  
  使用仲裁者主要是因为MongoDB副本集需要奇数成员,而又没有足够服务器的情况。
  在服务器充足的情况下,不应该使用仲裁者节点
  
  
4 更改节点优先级(by网络)
  
  修改节点的优先级可以触发重新选举,这样可以人工指定主节点。
  使用如下命令,在主节点登录,将192.168.1.3提升为Master。
  rs.conf();
  cfg=rs.conf();
  cfg.members.priority=1
  cfg.members.priority=1
  cfg.members.priority=10
  rs.reconfig(cfg);
  需要注意的是,修改节点优先级需要登录Master节点运行。否则报错。
  http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  再次查看集群状态,可以看到192.168.1.3已经作为Master运行
  
7 副本集成员状态(by网络)
  副本集成员状态指的是rs.status()的stateStr字段
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  STARTUP:刚加入到复制集中,配置还未加载
  STARTUP2:配置已加载完,初始化状态
  RECOVERING:正在恢复,不适用读
  ARBITER: 仲裁者
  DOWN:节点不可到达
  UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂
  REMOVED:移除复制集
  ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
  FATAL:出错。查看日志grep“replSetFATAL”找出错原因,重新做同步
  PRIMARY:主节点
  SECONDARY:备份节点
  
  
12 读写分离 by(网络)
  如果Master节点读写压力过大,可以考虑读写分离的方案。
  http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  
  
  不过需要考虑一种场景,就是主服务器的写入压力非常的大,所以副本节点复制的写入压力同样很大。
  这时副本节点如果读取压力也很大的话,根据MongoDB库级别读写锁的机制,
  很可能复制写入程序拿不到写锁,从而导致副本节点与主节点有较大延迟。
  如果进行读写分离,首先需要在副本节点声明其为slave,
  http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  然后在JAVA程序中进行设置
  http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  其中的ReadRreference有几种设置,
  http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  primary:默认参数,只从主节点上进行读取操作;
  primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。
  secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
  secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;
  nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。
  参考:
6.使用Web控制台,Web端口为28017
  Mongodb自带了Web控制台,默认和数据服务一同开启。他的端口在Mongodb数据库服务器端口的基础上加1000,如果是默认的Mongodb数据服务端口(Which is 27017),则相应的Web端口为28017
  我的控制台测试:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  点击 Replica set status 报错:REST is not enableduse --rest turn on
  解决方式:
  启动的时候加上 --rest
  ./monood -f master.conf--rest
  ./mongod -f slaver.conf--rest
  就可以看到Replica set status 界面了
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif

页: [1]
查看完整版本: mongoDB主从和副本集群配置