6

基于雪花算法的增强版ID生成器 - 陈其苗

 1 year ago
source link: https://www.cnblogs.com/think-in-java/p/16797882.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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>
    
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

如果对qps性能要求较高,可以适当调整sequenceBits

https://github.com/mocreates/sequence


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK