Distributed global non-duplicate ID generation algorithm the global ID unique ID is often used in distributed systems to generate globally unique distinct IDs. This blog describes some of the methods that are generated.
Some of the common ways:
1. Global self-increment operation via DB
Advantages: Simple and efficient
Cons: Low performance under large concurrency and distributed conditions
Some students may say that the Sub-Library, the Sub-table strategy to reduce the bottleneck of the DB, single to do the global non-repetition needs to be in advance according to a certain area of division. For example: 1~10000, 10001~20000 and so on. But this flexibility is lower.
This can be used for some cases where concurrency is lower. However, when large concurrency is not recommended, DB can easily become a bottleneck.
2. Get the current time of nanosecond or milliseconds
This approach needs to be considered if uniqueness is guaranteed in a distributed cluster.
3. How to generate similar UUID
The resulting string ratio is large
//------------------------------------------------------------
In this case, we need a single ID that provides efficient generation in high concurrency, distributed systems, but requires less results.
Method 1:
private static long Infoid_flag = 1260000000000L;
protected static int server_id = 1;
Public synchronized long NextID () throws Exception {
if (server_id <= 0)
throw new Exception ("Server ID is error,please check config file!");
Long infoid = System.currenttimemillis ()-Infoid_flag;
Infoid= (infoid<<7) | server_id;
Thread.Sleep (1);
return infoid;
}
Description
server_id different server IDs are used for different servers, if different machines use the same server ID it is possible to generate duplicate global IDs
Simple applications that use this approach in a certain concurrency situation are sufficient, simple and efficient. However, the ID generated per second is limited because Thread.Sleep (1) can inadvertently bring some time to consume.
Method 2:
/**
* 64-bit ID (42 (MS) +5 (machine ID) +5 (business code) +12 (repeat cumulative))
* @author Polim
*/
public class Idworker {
Private final static long Twepoch = 1288834974657L;
Number of machine identification bits
Private final static long workeridbits = 5L;
Number of data center identity bits
Private final static long datacenteridbits = 5L;
Machine ID Maximum Value
Private final static Long Maxworkerid = -1l ^ ( -1l << workeridbits);
Data center ID Maximum Value
Private final static Long Maxdatacenterid = -1l ^ ( -1l << datacenteridbits);
Self-increment in milliseconds
Private final static long sequencebits = 12L;
Machine ID shifted left 12 bits
Private final static long workeridshift = Sequencebits;
Data center ID shifted left 17 bits
Private final static Long Datacenteridshift = Sequencebits + workeridbits;
Time milliseconds left 22 bits
Private final static Long Timestampleftshift = sequencebits + workeridbits + datacenteridbits;
Private final static Long Sequencemask = -1l ^ ( -1l << sequencebits);
private static long Lasttimestamp = -1l;
Private long sequence = 0L;
Private final long Workerid;
Private final long Datacenterid;
Public Idworker (Long Workerid, long Datacenterid) {
if (Workerid > Maxworkerid | | Workerid < 0) {
throw new IllegalArgumentException ("Worker Id can ' t is greater than%d or less than 0");
}
if (Datacenterid > Maxdatacenterid | | Datacenterid < 0) {
throw new IllegalArgumentException ("Datacenter Id can ' t is greater than%d or less than 0");
}
This.workerid = Workerid;
This.datacenterid = Datacenterid;
}
Public synchronized Long NextID () {
Long timestamp = Timegen ();
if (Timestamp < Lasttimestamp) {
try {
throw new Exception ("Clock moved backwards. Refusing to generate ID for "+ (Lasttimestamp-timestamp) +" milliseconds ");
} catch (Exception e) {
E.printstacktrace ();
}
}
if (Lasttimestamp = = timestamp) {
In the current millisecond, the +1
Sequence = (sequence + 1) & Sequencemask;
if (sequence = = 0) {
The count is full in the current millisecond, then wait for the next second
timestamp = Tilnextmillis (Lasttimestamp);
}
} else {
sequence = 0;
}
Lasttimestamp = timestamp;
ID offset combination generates the final ID and returns the ID
Long NextID = ((Timestamp-twepoch) << timestampleftshift)
| (Datacenterid << Datacenteridshift)
| (Workerid << Workeridshift) | Sequence
return NextID;
}
Private Long Tilnextmillis (final long Lasttimestamp) {
Long timestamp = This.timegen ();
while (timestamp <= lasttimestamp) {
timestamp = This.timegen ();
}
return timestamp;
}
Private Long Timegen () {
return System.currenttimemillis ();
}
}
This approach is a more efficient approach. It's also a way Twitter uses it.
Test class:----------------------------------------------------------
Import java.util.concurrent.BrokenBarrierException;
Import Java.util.concurrent.CountDownLatch;
Import Java.util.concurrent.CyclicBarrier;
Import Java.util.concurrent.TimeUnit;
public class Idworkertest {
public static void Main (String []args) {
Idworkertest test = new Idworkertest ();
Test.test2 ();
}
public void Test2 () {
Final Idworker w = new Idworker;
Final Cyclicbarrier CDL = new Cyclicbarrier (100);
for (int i = 0; i <; i++) {
New Thread (New Runnable () {
@Override
public void Run () {
try {
Cdl.await ();
} catch (Interruptedexception e) {
E.printstacktrace ();
} catch (Brokenbarrierexception e) {
E.printstacktrace ();
}
System.out.println (W.nextid ());}
}). Start ();
}
try {
TimeUnit.SECONDS.sleep (5);
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
Distributed global non-duplicate ID generation algorithm