twitter ID生成算法
2017-08-29 17:56
267 查看
分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。
为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。
为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。
public class IdSeqGenerator { private final static long twepoch = 1463108596098L; //日期起始点 private final long workerId; private long sequence = 0L; private long lastTimestamp = -1L; private final static long workerIdBits = 10L; //机器ID占用10bits private final static long sequenceBits = 12L; //序列占用12bits public final static long maxWorkerId = -1L ^ -1L << workerIdBits; //机器ID 最大值 private final static long timestampLeftShift = sequenceBits + workerIdBits;//时间偏移位 private final static long workerIdShift = sequenceBits; //机器ID偏移位 public final static long sequenceMask = -1L ^ -1L << sequenceBits; //序列掩码 public IdSeqGenerator(final long workerId) { super(); if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } LogKit.log().info(String.format("worker Id : greater than %d or less than 0", maxWorkerId)); this.workerId = workerId; } //生成ID public synchronized long nextId() { long timestamp = this.timeGen(); //如果是同一时间生成的,则自增 if (this.lastTimestamp == timestamp) { this.sequence = (this.sequence + 1) & sequenceMask; if (this.sequence == 0) { //生成下一个毫秒级的序列 timestamp = this.tilNextMillis(this.lastTimestamp); } } else { //如果发现是下一个时间单位,则自增序列回0,重新自增 this.sequence = 0; } if (timestamp < this.lastTimestamp) { try { throw new Exception(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", this.lastTimestamp - timestamp)); } catch (Exception e) { e.printStackTrace(); } } this.lastTimestamp = timestamp; long nextId = ((timestamp - twepoch << timestampLeftShift)) | (this.workerId << workerIdShift) | (this.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(); } public static void main(String[] args) { Map<Long, Long> store = new ConcurrentHashMap<>(); final int MAX_POOL_SIZE = 4; ExecutorService service = Executors.newFixedThreadPool(MAX_POOL_SIZE); for (int i = 0; i < MAX_POOL_SIZE; i++) { final int x = i; service.execute(() -> { IdSeqGenerator seqKit = new IdSeqGenerator(x); for (int j = 0; j < 100; j++) { long id = seqKit.nextId(); if (store.containsKey(id)) { System.out.println("dublicate:" + id); } else { store.put(id, id); System.out.println(id); } } System.out.println("thread" + x + " end."); }); } service.shutdown(); } }
相关文章推荐
- 全局唯一ID生成常见的几种方式和twitter/snowflake(雪花算法)解析
- twitter ID生成算法
- twitter ID生成算法
- 基于Twitter的snowflake算法生成ID
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- Twitter全局唯一ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter ID生成算法
- twitter id生成算法snowflake详解
- twitter ID生成算法
- twitter ID生成算法
- 基于twitter的雪花算法生成不重复id