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

[经验分享] MongoDb Replica Set中使用的地址

[复制链接]

尚未签到

发表于 2015-7-7 09:17:04 | 显示全部楼层 |阅读模式
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中的三个实例上,分别是:



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



mongodb://192.168.122.1,192.168.122.1:27011,192.168.122.1:27012/Cart?replicaSet=rs0
  然后我到MongoDB的实例上建立了Replica Set:



yaoxing@YX-ARCH ~ $ mongo localhost
MongoDB shell version: 2.4.8
connecting to: test
>rs.initiate()
  
  然后尝试把其他两个实例添加到Replica Set中:



rs.add("localhost:27011");
rs.add("localhost:27012");
  发生了错误:



{
"errmsg" : "exception: can't use localhost in repl set member names except when using it for all members",
"code" : 13393,
"ok" : 0
}
  最容易想到的就是把localhost更换成机器名了,于是



rs.add("YX-ARCH:27011")
rs.add("YX-ARCH:27012")
  成功,一切看起来都很美好,但其实问题就已经在这里发生了。如果尝试关闭Primary,就会有另外一个实例从Secondary变为Primary,这点没有问题。但客户端始终会抛出本文开头那个异常,无法自动切换到新的Primary上。原因如下:
  如果仔细看MongoDB的文档,你会发现其实在连接字符串中写进所有的结点并不是必要的,但如果只写一个结点的话,必须要加上?replicaSet=[set name]参数(原因参考文档)。为什么可以只写一个结点?因为当Driver连接上一个结点之后会从该结点获取其他结点的信息,这样做是为了以后动态添加新结点的时候Driver可以从结点信息中自动识别,而不必每次都修改连接字符串。当然如果只写一个结点的话,坏处就是当这个结点挂了的时候Driver就不知道去哪找其他结点的信息了。
  由此我们可以发现,有几台服务器并不是从你的连接字符串中发现的,而是当Driver连接上某一台服务器后,从中获取的。所以从以上的例子中获取了什么东西?



rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 7,
"members" : [
{
"_id" : 0,
"host" : "YX-ARCH:27017",
"priority" : 20
},
{
"_id" : 1,
"host" : "YX-ARCH:27011",
"priority" : 30
},
{
"_id" : 2,
"host" : "YX-ARCH:27012",
"priority" : 20
}
]
}
  一共三个HOST



YX-ARCH
YX-ARCH:27011
YX-ARCH:27012
  明眼人应该看出来了,YX-ARCH这个东西在我的虚拟机中不存在,因此C# Driver发现连接字符串最终无法连接到成为新Primary的YX-ARCH:27011,而唯一可以连接的192.168.122.1是Secondary身份,我又没有指定readPreference,因此不可读。悲剧就这么发生了。
  当然知道了原因,解决方案也很简单:
  在replica set中和连接字符串中使用相同的HOST地址就可以完美解决问题
  希望对遇到同样问题的人有所帮助。

运维网声明 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-83994-1-1.html 上篇帖子: Mongodb For Windows 下篇帖子: 关于MongoDb Replica Set的故障转移集群——实战篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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