基於雪花演演算法的增強版ID生成器

2022-10-17 09:00:20

sequence

基於雪花演演算法的增強版ID生成器

  • 解決了時間回撥的問題
  • 無需手動指定workId, 微服務環境自適應
  • 可設定化

快速開始

  1. 依賴引入
    <dependency>
        <groupId>io.github.mocreates</groupId>
        <artifactId>uid-generator</artifactId>
        <version>2.0-RELEASE</version>
    </dependency>
    
  2. 設定序列器 Sequence
    @Bean
    public Sequence sequence() {
        SequenceConfig sequenceConfig = new SimpleSequenceConfig();
        return new Sequence(sequenceConfig);
    }
  1. 使用序列器生成ID
    @Autowired
    private Sequence sequence;
    
    public long generateId() {
        return sequence.nextId();
    }

設定解析

目前提供兩個設定類

  • io.github.mocreates.config.DefaultSequenceConfig
  • io.github.mocreates.config.SimpleSequenceConfig

前者需要顯式地指定 workerId、datacenterId,可以結合資料庫來使用,後者是利用網路卡資訊進行自適應

詳情

欄位名 釋義 預設值
twepoch 可以被設定為最接近專案啟用前的某個時間點(unix 時間戳) 1665817757000L
workerIdBits 機器位所佔的bit位數 19L
datacenterIdBits 資料標識位所佔的bit位數 0L
sequenceBits 毫秒內自增位數 3L
workerId 機器位
datacenterId 資料位 0L
inetAddress 網路相關資訊

生產推薦使用方式

  1. 依賴引入
    <dependency>
        <groupId>io.github.mocreates</groupId>
        <artifactId>uid-generator</artifactId>
        <version>2.0-RELEASE</version>
    </dependency>
    
  2. 建立表
CREATE TABLE `worker_node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `node_info` varchar(512) NOT NULL,
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='DB WorkerID Assigner for UID Generator';
  1. 設定 (利用主鍵自增來分配workerId, 解決分散式環境下手動指定workerId的痛點)
    @Bean
    public Sequence sequence(WorkerNodeMapper workerNodeMapper) throws UnknownHostException {
        WorkerNode workerNode = new WorkerNode();
        InetAddress localHost = InetAddress.getLocalHost();
        workerNode.setNodeInfo(localHost.toString());
        workerNodeMapper.insertSelective(workerNode);
        DefaultSequenceConfig defaultSequenceConfig = new DefaultSequenceConfig();
        defaultSequenceConfig.setWorkerId(workerNode.getId());
        return new Sequence(defaultSequenceConfig);
    }
  1. 使用序列器生成ID
    @Autowired
    private Sequence sequence;
    
    public long generateId() {
        return sequence.nextId();
    }

JMH 效能測試

測試機硬體情況

MacBook Pro (13-inch, M1, 2020) 8C 16G

Sequence 設定引數

    private static final DefaultSequenceConfig SEQUENCE_CONFIG = new DefaultSequenceConfig();

    static {
        SEQUENCE_CONFIG.setSequenceBits(22);
        SEQUENCE_CONFIG.setWorkerIdBits(0);
        SEQUENCE_CONFIG.setDatacenterIdBits(0);
        SEQUENCE_CONFIG.setTwepoch(System.currentTimeMillis());

        SEQUENCE_CONFIG.setWorkerId(0L);
        SEQUENCE_CONFIG.setDatacenterId(0L);
    }
    private static final Sequence SEQUENCE = new Sequence(SEQUENCE_CONFIG);

JMH引數

@BenchmarkMode(Mode.Throughput)
@Threads(10)
@Warmup(iterations = 3, time = 10, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS)
@State(value = Scope.Benchmark)
@Fork(1)
@OutputTimeUnit(TimeUnit.SECONDS)

測試結果

Benchmark Mode Cnt Score Error Units
SingleNodeSequenceTest.nextIdTest thrpt 10 27825573.565 ± 962298.054 ops/s

Tip

如果對qps效能要求較高,可以適當調整sequenceBits

倉庫地址

https://github.com/mocreates/sequence