首页 文章

MongoDB Azure Android:com.mongodb.WriteConcernException错误:“不是主”代码:“10058”

提问于
浏览
1

Background

嗨,我在Azure上运行MongoDB副本集,并在Android应用程序中远程连接到它 . 我已经从所有实例中获得了很好的读取功能(更新:因为它们可以在主节点和辅助节点上读取) . 但是,对数据库的写入仍然存在间歇性错误,并出现以下错误,因为写入必须仅在主节点上完成 .

此外,如果您可以提供任何更具体的资源来处理此问题,那么这也将非常有用 . 我已经浏览了大部分文档并对此错误进行了大量搜索 .

Question

如何防止此错误并允许100%的时间写入?

E/AndroidRuntime(): com.mongodb.WriteConcernException: {
        "serverUsed" : "/<my-remote-ip>:27017" , "err" : "not master" , 
        "code" : 10058 , "n" : 0 , "lastOp" : { "$ts" : 0 , "$inc" : 0} , 
        "connectionId" : 1918 , "ok" : 1.0}

Stack trace

E/AndroidRuntime(13731): FATAL EXCEPTION: Thread-7629
E/AndroidRuntime(13731): Process: com.myapplication.examplemongodb, PID: 13731
E/AndroidRuntime(13731): com.mongodb.WriteConcernException: { "serverUsed" : "/<my-remote-ip>:27017" , "err" : "not master" , "code" : 10058 , "n" : 0 , "lastOp" : { "$ts" : 0 , "$inc" : 0} , "connectionId" : 1918 , "ok" : 1.0}
E/AndroidRuntime(13731):    at com.mongodb.CommandResult.getException(CommandResult.java:77)
E/AndroidRuntime(13731):    at com.mongodb.CommandResult.throwOnError(CommandResult.java:110)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)
E/AndroidRuntime(13731):    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)
E/AndroidRuntime(13731):    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:76)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:60)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:105)
E/AndroidRuntime(13731):    at com.myapplication.examplemongodb.ActivityMain$1.run(ActivityMain.java:83)
E/AndroidRuntime(13731):    at java.lang.Thread.run(Thread.java:841)

Notes

  • 我正在使用mongo-java-driver v2.11.3 .

  • 我使用mongo-azure library来帮助创建具有两个辅助角色的MongoDB副本集 .

  • (如果您有更多资源,那么我已经阅读了GitHub自述文件,thisthis以及其他一些与MongoDB / Azure无关的内容 . 但是,这些资源没有更新,也没有详细说明 . )

Possible solutions

  • 我认为与副本集有关 .

  • 我不确定这是否正在发生,因为我只有两个实例副本集(一个主副本和一个副本),并且他们正在与想要成为主要人员的人进行斗争(阅读:投票) . 或许,需要仲裁者?但是,我目前不知道该怎么做 .

Update

  • 感谢@David Makogon的帮助,我'm pretty sure the issue lies with how I have set up the connection to Azure, and how I access the worker roles. So, here' s关于如何配置系统的更新说明:

  • 两个工作者角色(MongoDB.WindowsAzure.MongoDBRole),我从Android应用程序直接连接到 TCP Input Endpoint 端口27017 . 正如@David所说,我目前无法控制连接哪个实例 .

  • 一个Web角色(MongoDB.WindowsAzure.Manager),我没有做任何事情,在端口80上有一个 HTTP Input Endpoint . 这只是默认使用我上面提到的mongo-azure库 . 我不确定我是否应该采取任何措施 .

1 回答

  • 1

    如果实例都位于单个负载 balancer 的 endpoints (例如27017)后面,则每次客户端计算机连接到 endpoints 时,它都将连接到复制集群中可能不同的节点(并且您无法控制你去过哪个实例) . 这可能解释了为什么有时会尝试写入非master并获得错误,但所有读取都有效(因为您可能设置了MongoDB集群以允许在辅助节点上读取) .

    工作者角色还支持 InstanceInput endpoints ,允许您设置面向外部的端口范围(例如,27017-27019),映射到工作器实例本身的单个端口(例如27017) . 如果您这样做,您的客户端应用程序现在可以直接连接到所有三个实例(27017,27018,27019) . 许多驱动程序支持replicaset连接,因此它可以确定哪个节点是主节点,将所有写入指向它 . 我在Android上使用't know if the driver you'支持replicasets . 如果驱动程序没有想要考虑 Build 一个API层,然后进行与数据库的所有通信(一般来说这是一个很好的做法,你可以通过Azure的移动服务快速实现这一点) . .

    因此......如果您的replicaset集群的 endpoints 配置为 Input ,这可能会解释您所看到的问题,应该通过将 endpoints 类型切换为 InstanceInput 来解决该问题 .

相关问题