🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 一 复制集概念 ### A 复制集概述 Mongodb复制集(replica set)由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary通过oplog来同步Primary的数据,保证主从节点数据的一致性; 复制集在完成主从复制的基础上,通过心跳机制,一旦Primary节点出现宕机,则触发选举一个新的主节点,剩下的secondary节点指向新的Primary,时间应该在10-30s内完成感知Primary节点故障,实现高可用数据库集群 **特点:** * Primary节点是唯一的,但不是固定的 * 由大多数据原则保证数据的一致性 * Secondary节点无法写入(默认情况下,不使用驱动连接时,也是不能查询的) * 相对于传统的主从结构,复制集可以自动容灾 ### B 复制集原理 **角色(按是否存储数据划分):** * Primary 主节点,由选举产生,负责客户端的写操作,产生oplog日志文件 * Secondary 从节点,负责客户端的读操作,提供数据的备份和故障的切换 * Arbiter 仲裁节点,只参与选举的投票,不会成为primary,也不向Primary同步数据 >若部署了一个2个节点的复制集,1个Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加一个Arbiter节点,即使有节点宕机,仍能选出Primary **角色(按类型区分):** * Standard(标准) 这种是常规节点,它存储一份完整的数据副本,参与投票选举,有可能成为主节点 * Passive(被动) 存储完整的数据副本,参与投票,不能成为活跃节点 * Arbiter(投票) 仲裁节点只参与投票,不接收复制的数据,也不能成为活跃节点 >每个参与节点(非仲裁者)有个优先权(0-1000),优先权(priority)为0则是被动的,不能成为活跃节点; 优先权不为0的,按照由大到小选出活跃节点,优先值一样的则看谁的数据比较新 Mongodb 3.0里,复制集成员最多50个,参与Primary选举投票的成员最多7个 ### C 选举 每个节点通过优先级定义出节点的类型(标准、被动、投票) 标准节点通过对比自身数据进行选举出primary节点或者secondary节点 **影响选举的因素:** 1. 心跳检测 复制集内成员每隔两秒向其他成员发送心跳检测信息,若10秒内无响应,则标记其为不可用 2. 节点数量 在多个节点中,最少保证两个节点为活跃状态,如果集群中共三个节点,挂掉两个节点,那么剩余的节点无论状态是primary还是处于选举过程中,都会直接被降权为secondary **触发选举的情况:** 1. 初始化状态 2. 从节点们无法与主节点进行通信 3. 主节点辞职 **主节点辞职的情况:** * 在接收到replSetStepDown命令后 * 在现有的环境中,其他secondary节点的数据落后于本身10s内,且拥有更高优先级 * 当主节点无法与群集中多数节点通信 >当主节点辞职后,主节点将关闭自身所有的连接,避免出现客户端在从节点进行写入操作 ## 二 复制集搭建 ### A 配置文件准备 **创建目录** ```sh mkdir -p /opt/mongodb/2802{0,1,2,3}/{conf,data,log} ``` **创建单个配置文件** ```sh [mongo@noah ~]$ vim /opt/mongodb/28020/conf/mongod.conf systemLog: destination: file path: /opt/mongodb/28020/log/mongodb.log logAppend: true storage: journal: enabled: true dbPath: /opt/mongodb/28020/data directoryPerDB: true wiredTiger: engineConfig: cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true processManagement: fork: true net: port: 28020 replication: oplogSizeMB: 2048 replSetName: my_repl ``` **复制配置文件为多份** ```sh cp /opt/mongodb/2802{0,1}/conf/mongod.conf cp /opt/mongodb/2802{0,2}/conf/mongod.conf cp /opt/mongodb/2802{0,3}/conf/mongod.conf ``` **修改配置文件端口** ```sh sed -i 's#28020#28021#g' /opt/mongodb/28021/conf/mongod.conf sed -i 's#28020#28022#g' /opt/mongodb/28022/conf/mongod.conf sed -i 's#28020#28023#g' /opt/mongodb/28023/conf/mongod.conf ``` ### B 配置复制集群 **启动多个mongodb** ```sh mongod -f /opt/mongodb/28020/conf/mongod.conf mongod -f /opt/mongodb/28021/conf/mongod.conf mongod -f /opt/mongodb/28022/conf/mongod.conf mongod -f /opt/mongodb/28023/conf/mongod.conf ``` **创建复制集群** ```sh mongo --port 28020 config = {_id: 'my_repl', members: [ {_id: 0, host: '192.168.3.241:28020'}, {_id: 1, host: '192.168.3.241:28021'}, {_id: 2, host: '192.168.3.241:28022'}] } rs.initiate(config) ``` **查看复制集状态:** ```SH rs.status(); //查看整体复制集状态 rs.isMaster(); // 查看当前是否是主节点 rs.conf(); //查看复制集配置情况 ``` ### C 复制集群修改 **添加删除节点** ```sh rs.remove("ip:port"); // 删除一个节点 rs.add("ip:port"); // 新增从节点 rs.addArb("ip:port"); // 新增仲裁节点 ``` **重新配置集群** ```sh config = {_id: 'my_repl', members: [ {_id: 0, host: '192.168.3.241:28020'}, {_id: 1, host: '192.168.3.241:28021'}, {_id: 2, host: '192.168.3.241:28022',"arbiterOnly":true}] } rs.reconfig(config) ``` ## 三 复制集特殊节点 ### A 特殊节点: * arbiter节点 主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务 * hidden节点 隐藏节点,不参与选主,也不对外提供服务。 * delay节点 延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏) 一般情况下会将delay+hidden一起配合使用 **添加特殊节点的方法** 1. 可以在搭建过程中设置特殊节点 2. 可以通过修改配置的方式将普通从节点设置为特殊节点 需要找到需要改为延迟性同步的数组号,然后修改数据数据 ### B 配置延时节点 查看所有节点的配置 ```sh > rs.conf() "members" : [ { "_id" : 0, --->成员号 "host" : "10.0.0.51:28017", --->节点信息 "arbiterOnly" : false, --->是否为仲裁节点 "buildIndexes" : true, "hidden" : false, --->是否为隐藏节点 "priority" : 1, ---->选主权重 "tags" : { }, "slaveDelay" : NumberLong(0), --->延时的时间 "votes" : 1 } ``` 在线修改配置: ```sh #将所有配置信息定义到一个变量cfg 中 cfg=rs.conf() #从[成员号]对应的成员配置信息,调取某项配置进行修改 cfg.members[3].priority=0 cfg.members[3].hidden=true cfg.members[3].slaveDelay=120 #重新加载配置 rs.reconfig(cfg) ``` 取消以上配置 ```sh cfg=rs.conf() cfg.members[3].priority=1 cfg.members[3].hidden=false cfg.members[3].slaveDelay=0 rs.reconfig(cfg) ``` >注意:如果所有节点,没有0号节点时,members[号码],不再是_id值了,要手工数一下成员的位置号(从0开始数) 配置成功后,通过以下命令查询配置后的属性 ```sh rs.conf(); ``` ## 四 集群读写分离 对于MongoDB来说,主节点一般用于写数据,从节点用于读数据,且主节点也并不是固定的(当主节点宕机后会选举出一个新的主节点),所以在生产环境时客户端不能直连主节点,要**配置集群节点**: ~~~ <mongo:mongo-client replica-set="ip1:port1,ip2:port2,ip3:port3"> <mongo:client-options read-preference="SECONDARY_PREFERRED"/> </mongo:mongo-client> ~~~ 通过**read-preference**参数控制读写分离方式,其类型有以下几种: * PRIMARY(默认) 读操作都在主节点,若主节点不可用则报错。 * PRIMARY\_PREFERRED 首选主节点,若主节点不可用则转移到其它从节点。 * SECONDARY 读从节点,不可用则报错。 * SECONDARY\_PREFERRED(推荐) 首选从节点,若是特殊情况则在主节点读(但主节点架构)。 * NEAREST 最邻近主节点。 ## 五 副本集其他操作命令: 1. 查看副本集的配置信息 ```sh admin> rs.config() 或者 admin> rs.conf() ``` 2. 查看副本集各成员的状态 ```sh admin> rs.status() ``` 3. 副本集角色切换(不要人为随便操作) ```sh admin> rs.stepDown() 注: admin> rs.freeze(300) //锁定从,使其不会转变成主库 freeze()和stepDown单位都是秒。 ``` 4. 设置副本节点可读:在副本节点执行 ```sh admin> rs.slaveOk() ``` 5. 查看副本节点(监控主从延时) ```sh admin> rs.printSlaveReplicationInfo() source: 192.168.1.22:27017 syncedTo: Thu May 26 2016 10:28:56 GMT+0800 (CST) 0 secs (0 hrs) behind the primary ```