Replica set即副本集 分布式架构的一种实现
其他两种 主从模式 sharding模式 有机会再研究
Replica set 分为 主节点(Primary)副本节点(Secondary) 仲裁者(Arbiter)
主节点作为主数据库进行交互 副本节点保持于主节点数据一致 当主节点挂掉时 仲裁者会在副本节点中选举一个作为主节点
当副本节点优先级为0时不会被选举为主节点
各节点通过心跳维持联系 通过oplog传递同步数据 oplog是滚动的保存MongoDB中所有数据操作的日志
oplog数据结构:
oplog的数据结构如下所示:
{ ts : ..., op: ..., ns: ..., o: ... o2: ... }
- ts: 8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举(如master宕机时)新primary时,会选择ts最大的那个secondary作为新primary。
- op:1字节的操作类型,例如i表示insert,d表示delete。
- ns:操作所在的namespace。
- o:操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)
- o2: 在执行更新操作时的where条件,仅限于update时才有该属性
其中op有以下几个值:
- "i": insert
- "u": update
- "d": delete
- "c": db cmd
- "db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')
- "n": no op,即空操作,其会定期执行以确保时效性
搭建
1.安装mongodb
2.建立三个数据库 以及服务
其中mongodb1作为主节点 mongodb2 作为副本节点 mongodb3作为仲裁者
3.以管理员运行cmd进入mongodb/bin 运行 127.0.0.1:27017
4.执行
test= {
_id : "test",
members : [
{_id : 0, host :"127.0.0.1:27017"},
{_id : 1, host :"127.0.0.1:27018"},
{_id : 2, host :"127.0.0.1:27019", arbiterOnly: true},]
}
rs.initiate(test)
5.添加节点 rs.add('127.0.0.1:27020')
6.删除节点 rs.remove('127.0.0.1:27020')
7.查看配置信息 rs.conf()
8.将主节点将为从节点 rs.stepDown()
9.从节点可读操作 rs.slaveOk()
10.查询集群的oplog状态 db.printReplicationInfo()
11.查询数据库 db.Admin.find()
12.重新分配主节点
cfg=rs.conf()
cfg.members[1].priority = 2
rs.reconfig(cfg)
13.重新分配arbiter
主节点删除原arbiter和待转换的从节点
停止待分配的从节点服务
清空数据
开启服务
以arbiter身份加入集群
14.结果
查询 rs.status()
查询数据库
可视化工具查询 27019是仲裁节点 不能连接
C#使用数据库 读写分离
private MongoClient client { get; set; }
public MongoDBContext()
{
MongoClientSettings set = new MongoClientSettings();
List<MongoServerAddress> servers = new List<MongoServerAddress>();
servers.Add(new MongoServerAddress("127.0.0.1", 27017));
servers.Add(new MongoServerAddress("127.0.0.1", 27018));
//servers.Add(new MongoServerAddress("127.0.0.1", 27019)); 27019是仲裁节点 没有数据 也不要用它进行操作
//primary: 默认,只从主节点上进行读取操作;
//primaryPreferred: 在绝大部分的情形都是从主节点上读取数据的,只有当主节点不可用的时候,比如在进行failover的10秒或更长的时间内会从secondary节点读取数据。
//警告:2.2版本之前的MongoDB对Read Preference支持的还不完全,如果客户端驱动采用primaryPreferred实际上读取操作都会被路由到secondary节点。
//secondary: 只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
//secondaryPreferred: 优先从secondary节点进行读取操作;
//nearest: 既有可能从primary,也有可能从secondary节点读取,这个决策是通过一个叫member selection过程处理的。
set.ReadPreference = new ReadPreference(ReadPreferenceMode.SecondaryPreferred);
set.Servers = servers;
set.ReplicaSetName = "testrs";
client = new MongoClient(set);
}