一、工作原理
1. MongoDB 2.6版本开始推荐使用副本集,对主从复制已经不再推荐.
2. 副本集至少需要3个, 可以3个全部做副本集, 也可以让其中一个做仲裁.
3. 副本集中只有1台主才能进行写,其余的只能读.
4. 副本集之间的复制是通过oplog日志现实的.备份节点通过查询这个集合就可以知道需要进行复制的操作.
5. oplog是节点中local库中的一个固定的集合,在默认情况下oplog初始化大小为空闲磁盘的5%.oplog是capped collection,所以当oplog的空间被占满时,会覆盖最初写入的日志.
6. 通过改变oplog文档的大小直接改变local所占磁盘空间的大小.可以在配置文件中设置oplogSize参数来指定oplog文档的大小,例如oplogSize=1024单位默认为M 每个local文档在磁盘空间的空间都为2G,设置不足2G的,初始化依然为2G大小,例如上面oplogSize=1024,但创建的local.01大小依然为2G.
7. 如果备份节点不幸挂掉,由于复制过程中是先写数据,再写oplog,这样重新启动时,可能会重复复制操作.但MongoDB在设计过程中已经考虑过这个问题.当 oplog中同一个操作执行多次的时候,只执行一次.
8. 初始化工作.
a) 备份找到一个同步的主节点,然后再到local.me中创建一个标识符.开始同步的过程中,需要清空备节点的所有数据库(版本:2.6.7).
b) 通过oplog中的操作记录,把数据复制在备份节点.
c) 完全同步时开始创建索引.
9. 如果备节点的同步速度远远跟不上主节点的oplog写入的数据,并且主节点的oplog被覆盖.这样,可能就无法同步那些被覆盖的数据(出现这种情况,暂时还无法解决,只能通过备份主节点的数据,然后再重新同步).
10. 每个成员通过心跳去查看其他节点的状态,每隔2秒钟就有一次心跳检测.
11. 当主节点宕机之后,各个节点通过选举的方式来选择下一个主节点.
二、安装方法
1. 3台机器上分别装上MongDB 服务.
192.168.10.21:27017 (备)
192.168.10.26:27017 (备)
192.168.10.27:27018 (主)
2. 设置密码认证文件.
可以使用grub-md5-crypt生成加密文件.
把生成的密文放到一个文件中.并且3台机器要有相同的密文.
这里把密文放到mongodb主目录下的mongod_key文件中.
3. 3个mongo分别设置自己admin库的登录权限.
这个具体方法可以略掉.
4. 配置mongo.conf文件.
192.168.10.27 (主)的配置文件
192.168.10.21 (备)的配置文件
192.168.10.26 (备)的配置文件
5. 关闭每台机器的防火墙
/etc/init.d/iptables stop
6. 启动每台机器上的mongodb
7. 在主机上进行初始化工作,一般在哪台机器上初始化,主就是哪台机器.但是,也可以用权重来控制哪台为主.
config_repl={_id:'alex',members:[
{_id:0,host:'192.168.10.27:27018',priority:10},
{_id:1,host:'192.168.10.26:27017',priority:9},
{_id:2,host:'192.168.10.21:27017',priority:9}]}
这里的priority越大,主就是哪一台
然后执行rs.initiate(config_repl);
这时副本集已经配置完成.
可以用rs.status() 查看各个节点状态.
以我的理解,查看备库同步到主库的什么位置,可以通过optime来看
8. 设置副本集后,备节点默认是不能读数据的,但可以设置rs.slaveOk().
但只对当前session有效.
如果用程序去连接,实现读写分离.例如JAVA有相应的方法和参数去达到这一点
9. 切换主-备. (192.168.10.26 提升为主)
rs.conf() # 查看配置
执行:
cfg=rs.conf();
cfg.members[1] = 11 # 把id为1的主机priority改为11
rs.reconfig(cfg)
10. 查看同步状态.
上面第9步操作使192.168.10.26升级成为主了.
db.printSlaveReplicationInfo();
再执行
use local
db.oplog.rs.find();
可以查看到同步的语句.
{ "ts" : Timestamp(1448257041, 1), "h" : NumberLong("-1393509695161116878"), "v" : 2, "op" : "i", "ns" : "bbbb.test1", "o" : { "_id" : ObjectId("5652a6116894d5b1bcd83dd2"), "a" : 111 } }
含义解释如下:
ts: 8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举(如master宕机时)新primary时,会选择ts最大的那个secondary作为新primary
op:1字节的操作类型
i :insert
u :update
d :delete
c :db cmd
db:声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')
n : no op,即空操作,其会定期执行以确保时效性
ns:操作所在的namespace
o :操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)
o2: 在执行更新操作时的where条件,仅限于update时才有该属性