Distributed unique ID increment (snow algorithm)

Snowflake (Snowflake) algorithm.

 


By default 41bit timestamps may support use of the algorithm to 2082 of years, 10bit working machine id can
support 1024 machine, SEQ ID NO support 1 millisecond generating 4096 one of the ad increasing sequence id. SnowFlake advantage is that the entire
upper body in a time increment sort, and do not generate the entire distributed system ID collisions ( the data center ID and the machine ID
for distinction ) , and high efficiency, tested, Snowflake can be generated per 26 is million ID around

public  class SnowflakeIdWorker {
     / ** start time cut (2015-01-01) * / 
    Private  Final  Long twepoch = 1489111610226L ; 
 
    / ** number of bits occupied by the machine id * / 
    Private  Final  Long workerIdBits = 5L ; 
 
    / ** data identifying digit id share * / 
    Private  Final  Long dataCenterIdBits = 5L ; 
 
    / ** the maximum supported machine id, the result is 31 (this shift algorithm can quickly calculate the maximum number of decimal several binary number can represent) * / 
    Private  Final  Long maxWorkerId -1L = ^ (-1L << workerIdBits); 
 
    / ** the maximum data identification id, the result is 31 * /
    Private  Final  Long maxDataCenterId -1L = ^ (-1L << dataCenterIdBits); 
 
    / ** sequence representing the median id * / 
    Private  Final  Long sequenceBits = 12L ; 
 
    / ** machine ID 12 to the left * / 
    Private  Final  Long workerIdShift = sequenceBits; 
 
    / ** data identifying id to the left by 17 (12 + 5) * / 
    Private  Final  Long dataCenterIdShift + = sequenceBits workerIdBits; 
 
    / ** time to cut the left 22 (5 + 5 + 12) * / 
    Private  Final  Long timestampLeftShift workerIdBits + + = sequenceBitsdataCenterIdBits; 
 
    / ** generating mask sequences, here 4095 (0b111111111111 = 0xFFF = 4095) * / 
    Private  Final  Long sequenceMask -1L = ^ (-1L << sequenceBits); 
 
    / ** Work machine ID (0 ~ 31) * / 
    Private  Long workerId; 
 
    / ** data center ID (~ 31 is 0) * / 
    Private  Long dataCenterId; 
 
    / ** milliseconds sequence (0 ~ 4095) * / 
    Private  Long sequence = 0L ; 
 
    / ** last ID is generated cut-off time * / 
    Private  Long LastTimestamp = -1L ; 
 
    Private  static SnowflakeIdWorker idWorker;
 
    static {
        idWorker = new SnowflakeIdWorker(getWorkId(),getDataCenterId());
    }
 
    //==============================Constructors=====================================
    /**
     * 构造函数
     * @param workerId 工作ID (0~31)
     * @param dataCenterId 数据中心ID (0~31)
     */
    public SnowflakeIdWorker(long workerId, long dataCenterId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("workerId can't be greater than %d or less than 0", maxWorkerId));
        }
        if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
            throw new IllegalArgumentException(String.format("dataCenterId can't be greater than %d or less than 0", maxDataCenterId));
        }
        this.workerId = workerId;
        this.dataCenterId = dataCenterId;
    }
 
    /**
     * 获得下一个ID (该方法是线程安全的)
     * @return SnowflakeId
     */
    public synchronized longnextId () {
         Long timestamp = TIMEGEN (); 
 
        // if the current time is less than the timestamp of the last generation ID, indicating the system clock backoff time should be thrown through the 
        IF (timestamp < LastTimestamp) {
             the throw  new new a RuntimeException ( 
                    String. the format ( "Clock Moved Backwards ID for refusing to generate% D milliseconds.", LastTimestamp - timestamp)); 
        } 
 
        // if it is generated at the same time, the sequence is performed within milliseconds 
        IF (LastTimestamp == timestamp) { 
            sequence = (sequence . 1 +) & sequenceMask;
             // millisecond sequence overflow 
            IF (sequence == 0 ) {
                // blocking the next millisecond, obtain a new timestamp 
                timestamp = tilNextMillis (LastTimestamp); 
            } 
        } 
        // timestamp changes milliseconds reset sequence 
        the else { 
            Sequence = 0L ; 
        } 
 
        // last time the generated ID sectional 
        LastTimestamp = timestamp; 
 
        // shift to the fight and ORed together form a 64-bit ID 
        return ((timestamp - twepoch) << timestampLeftShift)
                 | (dataCenterId << dataCenterIdShift)
                 | (workerId << workerIdShift)
                 | Sequence; 
    } 
 
    / * * 
     * blocking a millisecond to the next, until a new timestamp
     * @Param LastTimestamp time cut previously generated ID 
     * @return current timestamp
      * / 
    protected  Long tilNextMillis ( Long LastTimestamp) {
         Long timestamp = TIMEGEN ();
         the while (timestamp <= LastTimestamp) { 
            timestamp = TIMEGEN (); 
        } 
        return timestamp; 
    } 
 
    / ** 
     * returns the current time in milliseconds 
     * @return current time (ms)
      * / 
    protected  Long TIMEGEN () {
         return System.currentTimeMillis ();
    } 
 
    Private  static Long getWorkId () {
         the try { 
            String HostAddress = Inet4Address.getLocalHost () getHostAddress ();.
             Int [] = INTS StringUtils.toCodePoints (HostAddress);
             int sums = 0 ;
             for ( int B: INTS) { 
                sums + = B; 
            } 
            return ( Long ) (32% sums ); 
        } the catch (UnknownHostException E) {
             // If the acquisition has failed, the backup using a random number 
            return RandomUtils.nextLong (0,31 ); 
        }
    }
 
    private static Long getDataCenterId(){
        int[] ints = StringUtils.toCodePoints(SystemUtils.getHostName());
        int sums = 0;
        for (int i: ints) {
            sums += i;
        }
        return (long)(sums % 32);
    }
 
 
    /**
     * 静态工具类
     *
     * @return
     */
    public static Long generateId(){
        long id = idWorker.nextId();
        return id;
    }
 
    //==============================Test=============================================
    /** 测试 */
    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        long startTime = System.nanoTime();
        for (int i = 0; i < 50000; i++) {
            long id = SnowflakeIdWorker.generateId();
            System.out.println(id);
        }
        System.out.println((System.nanoTime()-startTime)/1000000+"ms");
    }
}

 

 

Guess you like

Origin www.cnblogs.com/oldzhang1222/p/11078514.html