分布式ID生成策略

简介

本文基于Twitter的分布式ID生成策略,并做了一定的改动,以适应业务需要。
分布式ID生成的关键点:

  1. 全局唯一性;
  2. 生成速度;
  3. ID 所表达的含义;
功能:

分布式ID生成服务

  • nextId() 新 ID ,线程安全
源码:

接口
/**
 * 

Function: ID 生成服务.

* @author Dotions 2016年5月24日下午5:58:36 */ public interface IdGenService { public long nextId() throws Exception; }
实现类
import java.util.HashSet;
import java.util.Set;

/**
 * 

* Function: Twitter 的 ID 生成策略.
* 此实现中,简化了Twitter的生成策略。主要是取消了datacenter的标记,并将workerId值扩展到了1023。
*

* * @author Wang Yunfei 2016年5月24日下午6:00:31 */ public class TwitterIdGenServiceImpl implements IdGenService { private long workerId; // 不用datacenter Id // private long datacenterId; private long sequence = 0L; private long twepoch = 1288834974657L; // 起始标记点,作为基准 // private long workerIdBits = 5L; // private long datacenterIdBits = 5L; // 不需要datacenterId,只用workerId,扩展到10位 private long workerIdBits = 10L; // 只允许workid的范围为:0-1023 private long maxWorkerId = -1L ^ (-1L << workerIdBits); // private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); private long sequenceBits = 12L; private long workerIdShift = sequenceBits; // private long datacenterIdShift = sequenceBits + workerIdBits; // private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private long timestampLeftShift = sequenceBits + workerIdBits; private long sequenceMask = -1L ^ (-1L << sequenceBits); private long lastTimestamp = -1L; public TwitterIdGenServiceImpl(long workerId) { super(); // sanity check for workerId // 只允许workId的范围为:0-1023 if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } this.workerId = workerId; } /** * 下一个ID * */ public long synchronized nextId() throws Exception { long timestamp = timeGen(); if (timestamp < lastTimestamp) { throw new Exception(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0; } lastTimestamp = timestamp; return ((timestamp - twepoch) << timestampLeftShift) | // (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } /** * 保证返回的毫秒数在参数之后 * * @param lastTimestamp * @return */ private static long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } /** * 获得系统当前毫秒数 * * @return */ private static long timeGen() { return System.currentTimeMillis(); } }

用法:
public static void main(String[] args) {
        IdGenService idWorkder = new TwitterIdGenServiceImpl(0);
        try {
            
            Set set = new HashSet(100000);
            
            for (int i = 0; i < 10000000; i++) {
                set.add(idWorkder.nextId());
            }
            
            System.out.println(set.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

你可能感兴趣的:(分布式ID生成策略)