分布式ID的简单实现

来源:互联网 发布:合同档案管理系统软件 编辑:程序博客网 时间:2024/06/04 17:45

在上一篇博文(JDK自带UUID的性能问题)中我提到的一个满足我们需求,并能代替UUID的分布式ID的方案。在这里我做了简单的实现。

实现如下:
8位用作机器名
50位用作timestamp
6位用作标识符
 

用8位表示机器,可以表示256台机器。
50位表示的timestamp(毫秒),一年31536000000毫秒,可以表示35702年。
6位标识符,标识符只有在同一时间点上有两次ID的请求时会用到,用来区别这两个ID.6位表示64,也就是说只要你请求ID的TPS<64000,就不会有问题。

经过我简单的测试,这个实现在单线程下性能要比JDK自带UUID好一个数量级。在多线程下就更不用说了,因为我这个实现没有用同步。不过这两个本身也没有可比性。

import java.util.concurrent.atomic.AtomicLong;/** * This class is used for generating unique id in a distributed environment.  * It require a server identifier. Server identifier is a 0-255 integer. * DistributedID(64 bits) = ServerID(8) + Time(50) + clk_seq(6) * @author "Peter Lu" */public class DistributedID {    /**     * The last time value. Used to remove duplicate IDs.     */    private final static AtomicLong lastTime = new AtomicLong(Long.MIN_VALUE);        /**     * generate distributed ID.      *      * @param serverIdentifier support 256 servers. 0-255     * @return     */    public static String getDistributedID(int serverIdentifier) {        long dentifier = (long)serverIdentifier << 56;        long distributedID = dentifier | genTimeBasedID();        String id = Long.toHexString(distributedID);        while(id.length()<16) {    id = "0" + id;    }        return id;    }    /**     * Generates a new time field. Each time field is unique and larger than the     * previously generated time field.  * @return */private static long genTimeBasedID() {return genTimeBasedID(System.currentTimeMillis());}    /**     * generate a new time field from the given timestamp. Note that even identical     * values of <code>time</code> will produce different time fields. * @param time * @return */private static long genTimeBasedID(long time) {// 6 bits for clk_seqtime = time << 6;// try again if compareAndSet failedwhile(true) {long tempTime = lastTime.get();if(time>tempTime) {if(lastTime.compareAndSet(tempTime, time)) {break;}} else {// +1 to make sure the timestamp field is different                                 //even the time is identical.if(lastTime.compareAndSet(tempTime, ++tempTime)) {time = tempTime;break;}}}return time;}}



原创粉丝点击