设为首页 收藏本站
查看: 1294|回复: 0

[经验分享] MongoDB 副本集和C#交互,简单测试

[复制链接]

尚未签到

发表于 2017-12-16 09:35:44 | 显示全部楼层 |阅读模式
  MongoDB 副本集和C#交互,简单测试
  primary节点宕机:
  模拟primary节点宕机的情况,这时查看监控:
DSC0000.png

  可以看到37018已经成了primary节点。主界面宕机导致了整个集群发生一次election,实现了failover。等37017恢复了会自动成为secondary节点:
DSC0001.png

  所有secondary节点宕机
  当所有secondary宕机,或者副本集中只剩下一台机器的时候,那么剩下的机器只能成为secondary节点,也就意味着整个集群智能进行读操作而不能进行写操作
DSC0002.png

  当集群从故障中恢复过来后,仍然的primary节点仍然是primary节点。
  注意:当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。
  因此官方推荐的最小的副本集也应该具备一个primary节点和两个secondary节点。两个节点的副本集不具备真正的故障转移能力。

应用程序访问副本集
  副本集搭建好了,基本的故障转移能力也验证过了,那么应用程序如何访问呢?下面分别介绍下C#和Java驱动如何访问mongodb副本集。
  C#:
  C#驱动下载地址http://driver-downloads.mongodb.org/dotnet/index.html,我使用的最新版本1.8.2。
  下面是访问副本集基本的代码:

DSC0003.gif
引用命名空间: MongoDB.Driver.dll
MongoDB.Bson.dll  

MongoClientSettings set = new MongoClientSettings();  
List<MongoServerAddress> servers = new List<MongoServerAddress>();
  
servers.Add(new MongoServerAddress("192.168.129.129", 37017));
  
servers.Add(new MongoServerAddress("192.168.129.129", 37018));
  
servers.Add(new MongoServerAddress("192.168.129.129", 37019));
  
set.Servers = servers;
  

  
//设置副本集名称
  
set.ReplicaSetName = "rs0";
  
//设置超时时间为3秒
  
set.ConnectTimeout = new TimeSpan(0, 0, 0, 3, 0);
  

  

  
MongoClient client = new MongoClient(set);
  
MongoServer server = client.GetServer();
  
MongoDatabase db = server.GetDatabase("test");
  
MongoCollection coll = db.GetCollection("test");
  

  
//插入
  
BsonDocument bd = new BsonDocument();
  
bd.Add("name", "zhanjindong");
  
bd.Add("age", 23);
  
bd.Add("sex", "男D");
  

  
coll.Insert(bd);
  

  
//读取
  
QueryDocument qd = new QueryDocument();
  
qd.Add("name", "zhanjindong");
  
qd.Add("age", 23);
  
qd.Add("sex", "男D");
  

  
BsonDocument rd = coll.FindOneAs<BsonDocument>(qd);
  

  
Console.WriteLine(rd.ToString());
  


  当kill掉一个节点(secondary或primary)的时候,读取和写入的操作都是正常的,说明副本集的failover起作用了。但kill模拟两个节点宕机的时候,发现上面的代码在读取的时候会报下面的错误:
DSC0004.png

  这是因为默认的C#驱动的ReadPreference是Primary,也就是说读写操作都是在主节点上的,那么当集群中只剩下一个节点的时候,按照前面所说该节点一定是secondary节点,这样读取操作也是没法进行的(通过mongo shell当然是可以的)。解决方法就是设置驱动的ReadPreferenceMode:
  

set.ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred);  

  将ReadPreferenceMode设置成Secondary或SecondaryPreferred。后面读写分离一节对ReadPreference会有详细的说明。
  ReadPreferenceMode参数:
  primary:默认,只从主节点上进行读取操作;
  primaryPreferred:在绝大部分的情形都是从主节点上读取数据的,只有当主节点不可用的时候,比如在进行failover的10秒或更长的时间内会从secondary节点读取数据。
  警告:2.2版本之前的MongoDB对Read Preference支持的还不完全,如果客户端驱动采用primaryPreferred实际上读取操作都会被路由到secondary节点。
  secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。
  secondaryPreferred:优先从secondary节点进行读取操作;
  nearest:既有可能从primary,也有可能从secondary节点读取,这个决策是通过一个叫member selection过程处理的。
  Java:
  Java驱动下载地址:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/
  我用的是最新版本mongo-java-driver-2.11.2.jar。
  下面是Java访问MongoDB副本集的基本代码:

  

List<ServerAddress> addresses = new ArrayList<ServerAddress>();  
ServerAddress address1 = new ServerAddress("192.168.129.129", 37017);
  
ServerAddress address2 = new ServerAddress("192.168.129.129", 37018);
  
ServerAddress address3 = new ServerAddress("192.168.129.129", 37018);
  
addresses.add(address1);
  
addresses.add(address2);
  
addresses.add(address3);
  

  
MongoClient client = new MongoClient(addresses);
  
DB db = client.getDB("test");
  
DBCollection coll = db.getCollection("test");
  

  
// 插入
  
BasicDBObject object = new BasicDBObject();
  
object.append("name", "zhanjindong");
  
object.append("age", 23);
  
object.append("sex", "男");
  

  
coll.insert(object);
  

  
BasicDBObject qobj = new BasicDBObject();
  
qobj.append("name", "zhanjindong");
  
qobj.append("age", 23);
  
qobj.append("sex", "男");
  

  
DBObject robj = coll.findOne(qobj);
  

  
System.out.println(robj.toString());
  


  和C#一样如果想从secondary节点进行读取操作也是需要设置ReadPreference:
  

ReadPreference preference = ReadPreference.secondary();  
DBObject robj = coll.findOne(qobj, qobj, preference);
  

  不同的是Java驱动发现副本集中某个成员连接不了会发出警告信息:
DSC0005.png

  而且发现如果读取不到的话Java驱动会进行不停的重试。
  :设置驱动的ReadReference也可以通过MongoDB连接字符串配置:mongodb://example1.com,example2.com,example3.com/?readPreference=secondary。通过连接字符串指定的read preference是针对整个连接。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424618-1-1.html 上篇帖子: MongoDB数据库初探 下篇帖子: mongodb mapredReduce 多个条件分组(group by)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表