跳到正文
堆栈茶社
返回

Twitter的SnowFlake算法demo

更新于:
—次阅读
编辑此页

概述

image

41-bit的时间可以表示(1L<<41)/(1000L360024*365)=69年的时间,10-bit机器可以分别表示1024台机器。如果我们对IDC划分有需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示2^12个ID,理论上snowflake方案的QPS约为409.6w/s,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的。

算法实现

public class SnowFlakeService {

    private static final long TIMESTAMP_BIT_NUM = 41L;
    private static final long SEQUENCE_BIT_NUM = 12L;
    private static final long MACHINE_BIT_NUM = 5L;

    private static final long SEQUENCE_MAX_VALUE = -1L ^ (-1L << SEQUENCE_BIT_NUM);

    private long BEGIN_TIMESTAMP = 1262275200000L;

    private long lastTimeStamp = -1L;
    private long sequence = 0L;

    public Long getSnowFlake(Long machineId) {
        long currentTimeStamp = System.currentTimeMillis();
        if (currentTimeStamp < lastTimeStamp) {
            throw new RuntimeException("服务器时间异常!");
        }
        if (currentTimeStamp == lastTimeStamp) {
            sequence = (sequence + 1) & SEQUENCE_MAX_VALUE;
            if (sequence == 0) {
                currentTimeStamp = getNextTimeMillis();
            }
        } else {
            lastTimeStamp = currentTimeStamp;
            sequence = 0;
        }
        return (currentTimeStamp - BEGIN_TIMESTAMP) << (MACHINE_BIT_NUM + SEQUENCE_BIT_NUM)
                | machineId << SEQUENCE_BIT_NUM
                | sequence;
    }

    private long getNextTimeMillis() {
        long currentTimeMillis = 0L;
        do {
            currentTimeMillis = System.currentTimeMillis();
        } while (currentTimeMillis <= lastTimeStamp);
        return currentTimeMillis;
    }

    public static void main(String[] args) {
        long beginTime = System.currentTimeMillis();
        SnowFlakeService snowFlakeService = new SnowFlakeService();
        int count = 0;
        while ((System.currentTimeMillis() - beginTime) <= 1000) {
            Long snowFlake = snowFlakeService.getSnowFlake(1L);
            System.out.println(snowFlake);
            count++;
        }
        System.out.println("产生个数" + count);
    }
}

编辑此页
分享这篇文章:

上一篇
斐讯K2 刷机资料
下一篇
Spring学习笔记 - Spring FactoryBean