Using DNS A-name round robin in Client Drivers

330 views
Skip to first unread message

Chris Berry

unread,
Feb 16, 2012, 7:43:01 PM2/16/12
to mongodb-user, jbou...@homeaway.com, cbe...@homeaway.com
Greetings

We would like to come up with a mongo replica dns scheme that permits
us to add and remove replica set members from time to time without
telling our various mongo client applications to update their
configuration. We were wondering if it was okay to put all of the
replica set member IPs in DNS as an "A-name round robin", eg:

$ dig mongo-replica-set a +short
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4

and then the mongo client driver could connect to whatever IP happened
to come first, and would be made aware of the replica set members and
configuration automagically.

In the Java Client, I know that we could use

public Mongo( List<ServerAddress> replicaSetSeeds , MongoOptions
options )
throws MongoException {

And I can use the following on my side to create the replicaSetSeeds

InetAddress[] addrs =
InetAddress.getAllByName("www.google.com");

And I also see that the following signature calls
InetAddress.getAllByName under the covers

public ServerAddress( String host , int port )

But I do not see that it is using this info to create a
ReplicaSetStatus later on??
I am most likely missing something??

If not, this would be a nice addition.
Finding all of the clients and changing their config strings after a
Replica Set changes is not a very clean solution.

Thanks,
-- Chris









Nat

unread,
Feb 16, 2012, 8:19:55 PM2/16/12
to mongod...@googlegroups.com
The addresses provided will be only used as seeds where it ask a connected server for the list of its members. If you don't setup replicaset on all replicaset members, your client will probably connect just to one member instead.
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Eliot Horowitz

unread,
Feb 16, 2012, 9:33:11 PM2/16/12
to mongod...@googlegroups.com
You could use a different name for this.

So in the replica set config put the real hostnames.

Then have another dns entry that just points to them.

Use that for your config, and the driver will discover the real entries.

Chris Berry

unread,
Feb 16, 2012, 11:30:04 PM2/16/12
to mongodb-user
Hi Elliot,
Thanks for your response.
I'm not sure I fully understand what you're saying.

> You could use a different name for this.
> So in the replica set config put the real hostnames.

So use the real hostnames when I config the Replica Set mongod
Servers.
Yes, that's seems a given

> Then have another dns entry that just points to them.
> Use that for your config, and the driver will discover the real entries.

And then use the round robin A-name when I config the Client
and it will discover the real entries.
Could you please elaborate.

Thanks again for your time.
Cheers,
-- Chris

Eliot Horowitz

unread,
Feb 17, 2012, 10:42:16 AM2/17/12
to mongod...@googlegroups.com
>> Then have another dns entry that just points to them.
>> Use that for your config, and the driver will discover the real entries.
>
> And then use the round robin A-name when I config the Client
> and it will discover the real entries.
> Could you please elaborate.

When you create the connection in Java, you give it a host name that
resolves to multiple ips or hosts.
The java driver will then try to connect, and the discover the real
host names for the set and use that for the duration.

Chris Berry

unread,
Feb 17, 2012, 6:28:42 PM2/17/12
to mongodb-user
Thanks Elliot.
Yes it DOES work -- as long as you are on the latest Java Client
(2.7.3 -- I was on 2.6.5 and it failed)

BUT, if you use it as simply
new Mongo( "myANAME", 23456)

It does create the connection to the first one it gets from the list.

But if you call insureIndex() and it didn't happen to pick the Primary
It throws an Exception; MongoException : not talking to master and
retries used up

[02/17/12 17:24:14:919](main) ERROR - MongodbHASessionDAO -
EXCEPTION in Mongodb processing
MongoException : not talking to master and retries used up
Error with Mongo Server (sessionv2-mongo-replset-
ustst1.wvrgroup.internal:27017/MongoReplicaSetBasicsTest/sessions2)
com.mongodb.MongoException: not talking to master and retries used up
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:246)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:248)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:248)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:305)
at com.mongodb.DBCollection.findOne(DBCollection.java:647)
at com.mongodb.DBCollection.findOne(DBCollection.java:626)
at com.mongodb.DBApiLayer$MyCollection.createIndex(DBApiLayer.java:
364)
at com.mongodb.DBCollection.createIndex(DBCollection.java:436)
at com.mongodb.DBCollection.ensureIndex(DBCollection.java:515)
at com.mongodb.DBCollection.ensureIndex(DBCollection.java:492)

I can, of course, work around this as:

List<ServerAddress> addrs = new
ArrayList<ServerAddress>();
InetAddress[] inetaddrs =
InetAddress.getAllByName(mongoServerName);
for(InetAddress addr : inetaddrs) {
addrs.add(new ServerAddress(addr, mongoServerPort));
}
return new Mongo(addrs, mongoOptions);

But I thought you'd like to know...
Thanks for all of your help.
Cheers,
-- Chris

Scott Hernandez

unread,
Feb 18, 2012, 9:01:18 AM2/18/12
to mongod...@googlegroups.com
Yes, you have to use the list/array constructor for it to treat it as
a replica set. You didn't do that in the first example, and therefor
you got a random single mongod instance (which in your case was a
secondary).

You will want to use "InetAddress.getAllByName(mongoServerName);" to
create the seed list of addresses which the driver will connect to as
you have done, in case one or more are down.

Jason R. Coombs

unread,
Feb 28, 2012, 10:58:24 AM2/28/12
to mongodb-user
So it sounds like the Java driver doesn't in fact support using a
round-robin DNS to resolve the hostnames - that the application must
do the resolution. Furthermore, it doesn't sound like Scott's
suggestion would work, because the driver won't re-resolve the name if
a reconnect is triggered (it will still have the hosts as resolved
when the driver was initialized).

In my opinion, it would be preferable if MongoDB could accept the
round-robin hostname as a parameter, but if at connect time any
hostname resolves to multiple addresses, it should treat each address
as if it had been specified as a separate seed address.

This feature would be useful to us. I'm surprised it hasn't been
proposed already as a feature request. Is there any reason I shouldn't
create one in JIRA?

Adam C

unread,
Feb 28, 2012, 11:10:07 AM2/28/12
to mongodb-user
Jason,

This wouldn't be the first proposed feature to workaround an
awkwardness in a driver implementation (see the request to have mongos
handle connections to replica sets for example). I've been burned by
the Java tendency (Tomcat, I'm looking at you) to do a lookup once and
then never re-do it (reconnect be damned).

Feel free to create the feature request in the SERVER project and it
can then be properly evaluated, both in terms of usefulness and
implementation.

Adam.
Reply all
Reply to author
Forward
0 new messages