Welcome 微信登录

首页 / 数据库 / MySQL / MongoDB的数据复制和数据切片

MongoDB简介MongoDB由C++开发,是NoSQL中比较接近关系型数据库的一种。MongoDB中的数据以类似于json的格式存储,性能非常优越,且支持大量的数据存储。但是MongoDB不支持事务性的操作,使得其适用场景受到限制。MongoDB副本集MongoDB的数据复制有两种类型:    1)master/slave    2)replica set第一种为类似于MySQL的主从复制模型,第二种为副本集复制方式。现在主要应用的为副本集复制模型。结构图如下:一个副本集即为服务于同一数据集的多个MongoDB实例,其中一个为主节点,其余的都为从节点。主节点上能够完成读写操作,从节点仅能用于读操作。主节点需要记录所有改变数据库状态的操作,这些记录保存在oplog中,这个文件存储在local数据库,各个从节点通过此oplog来复制数据并应用于本地,保持本地的数据与主节点的一致。oplog具有幂等性,即无论执行几次其结果一致,这个比mysql的二进制日志更好用。集群中的各节点还会通过传递心跳信息来检测各自的健康状况。当主节点故障时,多个从节点会触发一次新的选举操作,并选举其中的一个成为新的主节点(通常谁的优先级更高,谁就是新的主节点),心跳信息默认每2秒传递一次。实现过程副本集的实现至少需要三个节点,且应该为奇数个节点,可以使用arbiter(仲裁节点)来参与选举。实验环境:主节点:192.168.1.132从节点:192.168.1.139,192.168.1.1401)安装配置MongoDB在各个节点上安装MongoDB服务器端需要的rpm包(安装包的下载地址:http://downloads-distro.mongodb.org/repo/RedHat/os/):1 [root@mongo1 mongodb-2.6.5]# yum install -y mongodb-org-server-2.6.5-1.x86_64.rpm mongodb-org-tools-2.6.5-1.x86_64.rpm mongodb-org-shell-2.6.5-1.x86_64.rpm配置文件信息:[root@mongo1 ~]# vim /etc/mongod.conf
logpath=/var/log/mongodb/mongod.log
logappend=true
fork=true
dbpath=/mongodb/data
pidfilepath=/var/run/mongodb/mongod.pid
bind_ip=0.0.0.0
httpinterface=true
rest=true
replSet=rs0
replIndexPrefetch = _id_onlyreplSet指定副本集的名称,这个至关重要,这个决定了对应的每一个节点加入的是哪一个副本集的集群。replIndexPrefetch指定副本集的索引预取,如果有预取功能可以让复制过程更为高效,有3个值none,_id_only,all。none:不预取任何索引,_id_only:预取ID索引,all:预取所有索引。这个预取操作只能定义在从节点上。在各节点上创建数据存放目录,然后启动服务:[root@mongo1 ~]# mkdir -pv /mongodb/data
mkdir: created directory `/mongodb"
mkdir: created directory `/mongodb/data"
[root@mongo1 ~]# chown -R mongod.mongod /mongodb
 
[root@mongo1 ~]# service mongod start
Starting mongod:                                          [  OK  ]2)配置集群的成员查看集群信息(此时没有任何节点)[root@mongo1 ~]# mongo --host 192.168.1.132
MongoDB shell version: 2.6.5
connecting to: 192.168.1.132:27017/test
> rs.status()
{
    "startupStatus" : 3,
    "info" : "run rs.initiate(...) if not yet done for the set",
    "ok" : 0,
    "errmsg" : "can"t get local.system.replset config from self or any seed (EMPTYCONFIG)"
}添加集群成员,首先配置cfg定义集群信息,然后执行rs.initiate(cfg)完成节点的添加。在定义集群时,需要指定每一个节点的属性信息,例如_id,host。还有很多属性字段,常见的有priority,votes,arbiterOnly.....  具体的信息可以参考官方网站http://docs.mongodb.org/manual/reference/command/replSetGetConfig/#replsetgetconfig-output。> cfg={_id:"rs0",members:[ 
... ... {_id:0,host:"192.168.1.132:27017"}, 
... ... {_id:1,host:"192.168.1.139:27017"},
... ... {_id:2,host:"192.168.1.140:27017"}] 
... ... }
{
    "_id" : "rs0",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.1.132:27017"
        },
        {
            "_id" : 1,
            "host" : "192.168.1.139:27017"
        },
        {
            "_id" : 2,
            "host" : "192.168.1.140:27017"
        }
    ]
}
#################################
> rs.initiate(cfg)
{
    "info" : "Config now saved locally.  Should come online in about a minute.",
    "ok" : 1
}查看各节点的状态信息:> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2015-09-04T23:02:13Z"),
    "myState" : 1,
    "members" : [                                                      #显示副本集的所有成员信息
        {
            "_id" : 0,                                          #节点的标识符
            "name" : "192.168.1.132:27017",                    #节点名称   
            "health" : 1,                                      #节点的健康状态           
            "state" : 1,                                                                               
            "stateStr" : "PRIMARY",                            #该节点为主节点                               
            "uptime" : 1750,                                    #运行时长                 
            "optime" : Timestamp(1441407002, 1),                #oplog最后一次操作的时间戳                                                   
            "optimeDate" : ISODate("2015-09-04T22:50:02Z"),    #oplog最后一次操作的时间                               
            "electionTime" : Timestamp(1441407011, 1),          #选举时间                     
            "electionDate" : ISODate("2015-09-04T22:50:11Z"),  #选举日期                                 
            "self" : true                                      #表示是否为当前节点
        },
        {
            "_id" : 1,
            "name" : "192.168.1.139:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",                            #从节点
            "uptime" : 730,
            "optime" : Timestamp(1441407002, 1),
            "optimeDate" : ISODate("2015-09-04T22:50:02Z"),
            "lastHeartbeat" : ISODate("2015-09-04T23:02:13Z"),
            "lastHeartbeatRecv" : ISODate("2015-09-04T23:02:12Z"),
            "pingMs" : 0,
            "syncingTo" : "192.168.1.132:27017"                  #指向的主节点
        },
        {
            "_id" : 2,
            "name" : "192.168.1.140:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 730,
            "optime" : Timestamp(1441407002, 1),
            "optimeDate" : ISODate("2015-09-04T22:50:02Z"),
            "lastHeartbeat" : ISODate("2015-09-04T23:02:13Z"),
            "lastHeartbeatRecv" : ISODate("2015-09-04T23:02:12Z"),
            "pingMs" : 0,
            "syncingTo" : "192.168.1.132:27017"
        }
    ],
    "ok" : 1
}在创建副本集时,有3种方式:1、db.runCommand( { replSetInitiate : <config_object> } )2、rs.initiate(<config_object>)3、rs.initiate()      #先在其中一个节点上初始化,再通过rs.add添加另外的节点这里采用的是第二种方式,<config_object>即为上述中的cfg文件,对该文件的修改使用replSetInitiate命令。
3)访问测试在主节点上添加数据(192.168.1.132):rs0:PRIMARY> use student_db
switched to db student_db
rs0:PRIMARY> for (i=1;i<=100000;i++) db.students.insert({name:"student"+i,age:(i%120),address:"china_nb"});
WriteResult({ "nInserted" : 1 })此时在从节点上访问数据会报如下错误:rs0:SECONDARY> use student_db
switched to db student_db
rs0:SECONDARY> db.students.findOne()
2015-09-04T19:28:10.730-0400 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131执行rs.slaveOk()后,数据才可读。rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.student.findOne()
null
rs0:SECONDARY> db.students.findOne()
{
    "_id" : ObjectId("55ea287ce476f31ac766a383"),
    "name" : "student1",
    "age" : 1,
    "address" : "china_nb"
} 当主节点故障时,从节点会重新投票选举出主节点,继续提供服务,避免单点故障。主节点上关闭服务:[root@mongo1 ~]# service mongod stop
Stopping mongod:                                          [  OK  ]从节点上查看状态信息:rs0:SECONDARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2015-09-04T23:31:49Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.1.132:27017",
            "health" : 0,                      #主节点已经下线
            "state" : 8,
            "stateStr" : "(not reachable/healthy)",
                        ................
        },
        {
            "_id" : 1,
            "name" : "192.168.1.139:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",              #新选出的主节点
            ............
        },
        {
            "_id" : 2,
            "name" : "192.168.1.140:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            .........
        }
    ],
    "ok" : 1
}可以看到原来的主节点已经下线(health为0),重新选举的主节点为192.168.1.139。可以通过rs.isMaster()查看当前节点是否为主节点。4)添加一个从节点数据库运行一段时间后,可能需要再次添加节点来分散压力。通过rs.add命令添加从节点。添加完成后,该节点需要和主节点同步数据,同步过程有3个步骤:  1、初始同步(initial sync)  2、回滚后追赶(post-rollback catch-up)  3、切分块迁移(sharding chunk migrations)添加从节点(在主节点上):rs0:PRIMARY> rs.add("192.168.1.138")
{ "ok" : 1 }查看状态:{
    "_id" : 2,
    "name" : "192.168.1.127:27017",
    "health" : 1,
        .....................
    "lastHeartbeatMessage" : "still initializing"        #正在初始化
}
#######################
{
    "_id" : 1,
    "name" : "192.168.1.138:27017",
    "health" : 1,
        ........
    "lastHeartbeatMessage" : "initial sync need a member to be primary or secondary to do our initial sync"    #同步数据
}
#######################
{
    "_id" : 1,
    "name" : "192.168.1.138:27017",
    "health" : 1,
        ........
    "syncingTo" : "node1.xiaoxiao.com:27017"                #同步完成
}执行rs.slaveOk()后,即可实现访问。--------------------------------------分割线 --------------------------------------更多MongoDB相关内容可以看看以下的有用链接: MongoDB 3.0 正式版发布下载  http://www.linuxidc.com/Linux/2015-03/114414.htmCentOS编译安装MongoDB http://www.linuxidc.com/Linux/2012-02/53834.htmCentOS 编译安装 MongoDB与mongoDB的php扩展 http://www.linuxidc.com/Linux/2012-02/53833.htmCentOS 6 使用 yum 安装MongoDB及服务器端配置 http://www.linuxidc.com/Linux/2012-08/68196.htmUbuntu 13.04下安装MongoDB2.4.3 http://www.linuxidc.com/Linux/2013-05/84227.htmMongoDB入门必读(概念与实战并重) http://www.linuxidc.com/Linux/2013-07/87105.htmUbunu 14.04下MongoDB的安装指南 http://www.linuxidc.com/Linux/2014-08/105364.htm《MongoDB 权威指南》(MongoDB: The Definitive Guide)英文文字版[PDF] http://www.linuxidc.com/Linux/2012-07/66735.htmNagios监控MongoDB分片集群服务实战 http://www.linuxidc.com/Linux/2014-10/107826.htm基于CentOS 6.5操作系统搭建MongoDB服务 http://www.linuxidc.com/Linux/2014-11/108900.htm--------------------------------------分割线 --------------------------------------5)更改某个节点的优先级若某个从节点的硬件配置不错,可以对应的调高其优先级,使其在选举过程中能够优先被选举为主节点。例如设置第3个节点的优先级为2(默认均为1),过程如下:rs0:PRIMARY> cfg=rs.conf()
rs0:PRIMARY> cfg.members[2].priority=2        #节点的标识符为2
rs0:PRIMARY> rs.reconfig(cfg)                #更新配置
################
rs0:SECONDARY> rs.config() 
{
                ................
        {
            "_id" : 2,
            "host" : "192.168.1.140:27017",
            "priority" : 2        #对应优先级
        }
    ]
}此时会立刻进行选举,优先级最高的为主节点,如下图所示:更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2015-09/123320p2.htm
  • 1
  • 2
  • 下一页
Linux 下编译安装 Redis使用MySQL命令行备份及恢复数据库相关资讯      MongoDB副本集  MongoDB数据切片 
  • MongoDB 搭建副本集(Replica Set  (今 07:51)
  • MongoDB的副本集节点角色介绍及选  (06月13日)
  • MongoDB集群上副本集(replica set  (04月10日)
  • MongoDB副本集实现及读写分离  (06月13日)
  • MongoDB 复制(副本集)  (04月14日)
  • MongoDB 副本集+分片 架构部署  (04月10日)
本文评论 查看全部评论 (0)
表情: 姓名: 字数


评论声明
    版权所有©石家庄振强科技有限公司2024 冀ICP备08103738号-5 网站地图