Stephane Grenier
Stephane Grenier

Reputation: 15927

How to generate unique ID's on a cluster of web servers

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.

Upvotes: 4

Views: 10903

Answers (5)

Jay
Jay

Reputation: 27474

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.

Upvotes: 1

Jim Downing
Jim Downing

Reputation: 1491

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());

Upvotes: 15

NickSentowski
NickSentowski

Reputation: 818

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.

Upvotes: 1

D'Arcy Rittich
D'Arcy Rittich

Reputation: 171411

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.

Upvotes: 1

kgiannakakis
kgiannakakis

Reputation: 104178

You can use a UUID:

import java.util.UUID;        

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

Upvotes: 3

Related Questions