问题
Background:
I have MongoDB replica sets running in Azure cloud service worker + web roles, using mongo-azure library. The first time I setup my Android project to connect to MongoDB/Azure, IO (reads and writes) worked. Then, I crashed the app because of a typo in my hardcoded test JSONString, so the Mongo instance wasn't able to properly close. After fixing that JSONString problem, I received the following error (in stack trace) and wasn't able to access MongoDB/Azure. Perhaps not closing the connection properly caused the error?
Question:
What exactly does this error mean? Why wouldn't the master instance be available?
E/AndroidRuntime: com.mongodb.MongoException: not talking to master and retries used up
Full stack trace:
E/AndroidRuntime(6274): FATAL EXCEPTION: Thread-7108
E/AndroidRuntime(6274): Process: com.myproject.examplemongodb, PID: 6274
E/AndroidRuntime(6274): com.mongodb.MongoException: not talking to master and retries used up
E/AndroidRuntime(6274): at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:271)
E/AndroidRuntime(6274): at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:273)
E/AndroidRuntime(6274): at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:273)
E/AndroidRuntime(6274): at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:216)
E/AndroidRuntime(6274): at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:288)
E/AndroidRuntime(6274): at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:273)
E/AndroidRuntime(6274): at com.mongodb.DB.getCollectionNames(DB.java:400)
E/AndroidRuntime(6274): at com.myproject.examplemongodb.ActivityMain$1.run(ActivityMain.java:89)
E/AndroidRuntime(6274): at java.lang.Thread.run(Thread.java:841)
Notes:
- I am using the newest mongo-java-driver (currently 2.11.3).
- I am connecting remotely to database (non-localhost).
- Another question mentions this error, but OP is using different drivers and his solution does not work for Android/Java.
Possible solution:
- It appears that closing the connection from the app allowed the next run to work properly. But, I'm still worried about being able allow concurrent connections, which I would definitely like to do.
- Update: I have wrapped a mongodb log in and log out around each of my queries going to the server, but the error still seems to show up intermittently. So far, it seems that write work every time, but reads only work half the time. The other half of the time is the posted error.
回答1:
The reason for the intermittent errors is because of the default read preferences for the driver, mainly in regards to replica sets. The default read preference is primary. For each of the modes mentioned below, PRIMARY refers to the master database (always the most up-to-date) and SECONDARY refers to slave(s), which are basically the copies of master and are not always up-to-date.
PRIMARY: The default read mode. Read from primary only. Throw an error if
primary is unavailable. Cannot be combined with tags.
The solution to change the read preference to one of the following:
PRIMARY PREFERRED: Read from primary if available, otherwise a secondary.
SECONDARY PREFERRED: Read from a secondary if available, otherwise read from the primary.
NEAREST: Read from any member node from the set of nodes which respond the fastest.
Example code:
// Use this when doing a read if you don't care if the data is always consistent.
// Change the following with secondaryPreferred() if you have high writes, so
// that you don't interfere with them.
ReadPreference preference = ReadPreference.primaryPreferred();
DBCursor cur = new DBCursor(collection, query, null, preference);
For more info, see the source.
来源:https://stackoverflow.com/questions/20437395/mongodbazureandroid-error-com-mongodb-mongoexception-not-talking-to-master