Question

In the following scenario:

1 Database 4 Web servers

How do the Web servers generate unique ID's for the database so that they are unique? Yes it's possible to use Auto-increment, but this is too easily crawled/guessed/etc. So auto-increment is currently not an option.

Was it helpful?

Solution

Use a UUID (http://www.ietf.org/rfc/rfc4122.txt). Collisions are unlikely, and could be dealt with when they occur by regenerating a new UUID, or they could be prevented by concatenating a unique id for each server (like the mac address): -

StringBuilder sb = new StringBuilder(UUID.randomUUID());
InetAddress address = InetAddress.getLocalHost();
String uid = sb.append(NetworkInterface.getByInetAddress(address).getHardwareAddress());

OTHER TIPS

You can use a UUID:

import java.util.UUID;        

UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());

If you are really worried about collisions, you can pre-generate your keys and store them in a database table with a unique index. Then have a periodic job that populates the table during downtime, and removes/archives used keys once in a while.

What DB system are you using? Does the app know which server is making the request? Are you letting the DB decide the key, or setting it in code?

It could be as simple as using an auto-increment with a prefix or 2nd field indicating the server that requested the key.

I'm not sure why an auto-increment or sequence is unacceptable. You want an internal ID to not be "guessable"? What, it's like this is an account number and you don't want someone to be able to guess a valid account number?

Well, okay, besides UUIDs already mentioned, two obvious possibilities come to mind.

  1. Use a sequence, then generate a random number, and create the account number from a combination of the two using an algorithm such that two different sequences numbers cannot give the same final number. For example, a simple algorithm would be: Take the next sequence number, multiply by 12345678, generate a random number from 0 to 12345678-1, and add the two together.

  2. Have a table on the database with one record, which holds the last assigned number. Each time you need a new number, lock this record, use the previous value to generate the next value, and update the record. As long as the numbers always increase, you're guaranteed to not have a duplicate.

If you have some scheme that uses an identifier of the server as part of the identifier, I'd encourage you to not have that identifier simply be a number stored in a configuration file somewhere. I'm working on a system now where someone had the bright idea to give each server a "server id" that is built in to record id's, and the server id is a small integer that is manually assigned. It's not too hard in production where there are only 3 servers. But in development and testing, where new servers are coming up and down all the time and test configuration files are constantly being tossed around, it's a pain to administer. I'd avoid using a server id period, but if you're going to use one, make it automatically assigned by some central server, or derive it from the IP, or something safe.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top