Unable to connect to a member of the replica set matching the read preference Primary

今天尝试使用MongoDB Replica Set提供的自动故障恢复功能一直无法成功,总是遇到上面这个错误。好一顿整终于找到的原因,由于这里还比较有迷惑性,特此记录一下供其他人参考。

其实Google一下这个错误,在前几条结果中就有答案,但是该死的GFW屏蔽了Google Group,导致我跳过了那条结果而一直没有找到正确答案,我可以骂脏话吗?

进入正题,我们知道使用Replica Set是要在连接字符串中加入所有结点的地址(建议这么做,但并不是强制。关于连接字符串参考这里)。以我为机器为例,我的Windows在虚拟机192.168.122.100上,MongoDB运行在物理机192.168.122.1中的三个实例上,分别是:

  1. 192.168.122.1:
  2. 192.168.122.1:
  3. 192.168.122.1:

因此我的连接字符串大概会是这个样子(ReplicaSet为rs0):

  1. mongodb://192.168.122.1,192.168.122.1:27011,192.168.122.1:27012/Cart?replicaSet=rs0

然后我到MongoDB的实例上建立了Replica Set:

  1. yaoxing@YX-ARCH ~ $ mongo localhost
  2. MongoDB shell version: 2.4.
  3. connecting to: test
  4.  
  5. >rs.initiate()

然后尝试把其他两个实例添加到Replica Set中:

  1. rs.add("localhost:27011");
  2. rs.add("localhost:27012");

发生了错误:

  1. {
  2. "errmsg" : "exception: can't use localhost in repl set member names except when using it for all members",
  3. "code" : 13393,
  4. "ok" : 0
  5. }

最容易想到的就是把localhost更换成机器名了,于是

  1. rs.add("YX-ARCH:27011")
  2. rs.add("YX-ARCH:27012")

成功,一切看起来都很美好,但其实问题就已经在这里发生了。如果尝试关闭Primary,就会有另外一个实例从Secondary变为Primary,这点没有问题。但客户端始终会抛出本文开头那个异常,无法自动切换到新的Primary上。原因如下:

如果仔细看MongoDB的文档,你会发现其实在连接字符串中写进所有的结点并不是必要的,但如果只写一个结点的话,必须要加上?replicaSet=[set name]参数(原因参考文档)。为什么可以只写一个结点?因为当Driver连接上一个结点之后会从该结点获取其他结点的信息,这样做是为了以后动态添加新结点的时候Driver可以从结点信息中自动识别,而不必每次都修改连接字符串。当然如果只写一个结点的话,坏处就是当这个结点挂了的时候Driver就不知道去哪找其他结点的信息了。

由此我们可以发现,有几台服务器并不是从你的连接字符串中发现的,而是当Driver连接上某一台服务器后,从中获取的。所以从以上的例子中获取了什么东西?

  1. rs0:PRIMARY> rs.conf()
  2. {
  3. "_id" : "rs0",
  4. "version" : 7,
  5. "members" : [
  6. {
  7. "_id" : 0,
  8. "host" : "YX-ARCH:27017",
  9. "priority" : 20
  10. },
  11. {
  12. "_id" : 1,
  13. "host" : "YX-ARCH:27011",
  14. "priority" : 30
  15. },
  16. {
  17. "_id" : 2,
  18. "host" : "YX-ARCH:27012",
  19. "priority" : 20
  20. }
  21. ]
  22. }

一共三个HOST

  1. YX-ARCH
  2. YX-ARCH:27011
  3. YX-ARCH:27012

明眼人应该看出来了,YX-ARCH这个东西在我的虚拟机中不存在,因此C# Driver发现连接字符串最终无法连接到成为新Primary的YX-ARCH:27011,而唯一可以连接的192.168.122.1是Secondary身份,我又没有指定readPreference,因此不可读。悲剧就这么发生了。

当然知道了原因,解决方案也很简单:

在replica set中和连接字符串中使用相同的HOST地址就可以完美解决问题

希望对遇到同样问题的人有所帮助。

MongoDb Replica Set中使用的地址的更多相关文章

  1. MongoDB Replica Set搭建集群

    MongoDB做集群,版本3.2官网推荐的集群方式Replica Set 准备服务器3台 两个standard节点(这两个节点直接可以互切primary secondary). 一个arbiter节点 ...

  2. mongodb replica set 和 nodejs中使用mongoose连接replica

    一.mongodb replication 介绍 官网上的第一句话就是Replication is the process of synchronizing data across multiple ...

  3. MongoDB Replica Set 选举过程

    什么是选举? 选举是副本集选择某个成员成为primary的过程.primary是一个副本集中唯一能够接收写操作的成员. 下面的事件能够引发一次选举: 第一次初始化一个副本集 Primary失效.rep ...

  4. 关于MongoDb Replica Set的故障转移集群——实战篇

    如果你还不了解Replica Set的相关理论,请猛戳传送门阅读笔者的上一篇博文. 因为Replica Set已经属于MongoDb的进阶应用,下文中关于MongoDb的基础知识笔者就不再赘述了,请参 ...

  5. (转载)MongoDB C#驱动中Query几个方法

    MongoDB C#驱动中Query几个方法 Query.All("name", "a", "b");//通过多个元素来匹配数组 Query ...

  6. MongoDB 学习笔记(三) MongoDB (replica set) 集群配置

    MongoDB Replica Sets的结构类似于以集群,完全可以把他当成一个集群,因为他确实与集群实现的作用是一样的:如果其中一个节点出现故障,其他的节点会马上将业务接管过来.而无需停机操作 Mo ...

  7. MongoDB数据库设计中6条重要的经验法则

    Part 1 原文:6 Rules of Thumb for MongoDB Schema Design: Part 1 By William Zola, Lead Technical Support ...

  8. (1)解锁 MongoDB replica set核心姿势

    副本集Replica Set是一个术语,定义具有多节点的数据库集群,这些节点具有主从复制(master-slave replication) 且节点之间实现了自动故障转移. 这样的结构通常需要具有奇数 ...

  9. java正则表达式获得html字符串中<img src>的src中的url地址

    /** * 得到网页中图片的地址 */ public static Set<String> getImgStr(String htmlStr) { Set<String> pi ...

随机推荐

  1. Lua 架构 The Lua Architecture

    转载自:http://magicpanda.net/2010/10/lua%E6%9E%B6%E6%9E%84%E6%96%87%E6%A1%A3/ Lua架构文档(翻译) 十 102010 前段时间 ...

  2. Ext 4.2 RowEditing

    Follow: function () { Ext.define('Follow', { extend: 'Ext.data.Model', idProperty: 'id', fields: [ { ...

  3. CodeForces 593D【树链剖分】

    题意: 给你n个点和n-1条边组成的一棵树,按顺序给出数的每一条边. 询问m次,每次给出一个x求x除以从点a到点b所有边的权值和的乘积,还有修改,给出边的编号,修改某条边的权值. 思路: 树链剖分,用 ...

  4. Android——显示单位px和dip以及sp的区别

    dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不依赖像素.d ...

  5. H264的句法和语法总结(一)分层结构

    在H.264 中,句法元素共被组织成  序列.图像.片.宏块.子宏块五个层次.在这样的结构中,每一层的头部和它的数据部分形成管理与被管理的强依赖关系,头部的句法元素是该层数据的核心,而一旦头部丢失,数 ...

  6. The Ninth Hunan Collegiate Programming Contest (2013) Problem H

    Problem H High bridge, low bridge Q: There are one high bridge and one low bridge across the river. ...

  7. 1307: City Tour

    1307: City Tour Time Limit: 1 Sec  Memory Limit: 128 MB [Submit][Status][Web Board] Description Alic ...

  8. python学习笔记(win32print API介绍)

    最近博主在研究用python控制打印机 这里整理下win32print的API介绍,官网地址http://timgolden.me.uk/pywin32-docs/win32print.html Op ...

  9. unity两点之间抛物线,完美金手指

    学校享受的日子一去不复还了,呜呜.话说面试了几个公司,真心没准备好就上了,结果当然是小悲催.还好有容身之处,就算是搬砖,也有可能为自己盖楼,吼吼. 好,下面我来分享一道有意思的面试题,说他有意思,是因 ...

  10. Github开源编辑器Atom

    Atom是Github社区开发的一款开源编辑器,很有sublime text特色,相当于开源的sublime text. sublime text用了很长时间了,为什么会重新学习使用另外一款编辑器呢? ...