如何生成分布式系统全局唯一Id

一、合理的全局唯一Id的一些要求

1. 全局唯一

  • 不能出现重复的id,也即唯一标识

2. 趋势递增

  • MySQL中的InnerDB存储引擎使用的是聚簇索引,多数使用Btree的数据结构来存储索引,在主键的选择上,我们尽可能选择有序的唯一id

3. 单调递增

  • 保证下一个id一定大于上一个id,例如事务版本号,排序等场景

4. 信息安全

  • 如果id连续的,恶意用户的爬取工作就会很容易做到,在一些应用场景下需要id无规则不规则

5. 含时间戳

  • 能快速排查这个id什么时候生成的

二、分布式全局唯一Id还需要哪些要求

  • 高可用:获取分布式的唯一id,服务器要保证99.999%的情况下可以生成唯一id
  • 低延时:获取一个唯一id请求,要快速生成,极快
  • 高QPS:在并发场景下,服务器可以同时创建上万个唯一id

三、常见的几种生成唯一Id方式

1. 通过java.util.UUID生成

 System.out.println(UUID.randomUUID());

  • 只需使用replace替换掉符号,即可使用,性能非常高,没有网络消耗
  • 但是,UUID生成的id为字符串,字符串作为Id占用空间大,并且由于无序,索引效率比整型低,入数据库性能差,MySQL建议使用较短的主键id,不推荐使用

2. 通过MySQL的auto-increment自增字段和replace into实现

  • 从1开始,基本可以做到连续递增,只能保证每个表唯一
  • 但是,不能保证全局唯一,无法保证信息安全,分布式系统不合适使用

3. 基于Redis生成全局id策略

  • 利用redis的原子性,通过Incr,设置步长基本可以满足
  • 但是,复杂性太高,需要严重依赖第三方服务,而且代码配置繁琐,需要引入Redis集群

4. 雪花算法

  • SnowFlake可以按照时间有序生成
  • SnowFlake生成的id结果为64bit的整数,为一个Long型
  • 分布式系统中不会产生id碰撞,由workerId和datecenter区分,效率很高

4.1 雪花算法的核心组成部分

  • 1位符号位
  • 41位时间戳位
    • 时间范围:79年,可以到2039-9-07
  • 10位工作进程位
    • 2^10 = 1024,可以部署1024个结点,5位workerId和5位datacenter
  • 12位序列号位
    • 2^12-1 = 4095,即每个时间戳可以生成4095个唯一id

4.2 如何使用

  • 引入hutool工具包
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.7</version>
</dependency>
  • 编写工具类
public class SnowFlakeService
{
    private long workerId = 1;
    private long datacenter = 1;
    private Snowflake snowflake = IdUtil.createSnowflake(workerId,datacenter);

    {
        workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
        System.out.println(workerId);
    }

    public  long getSnowflakeId(){
        return snowflake.nextId();
    }
    public  long snowflakeId(long workerId,long datacenterId){
        Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);
        return snowflake.nextId();
    }

    public static void main(String[] args) {
        SnowFlakeService snowFlakeService = new SnowFlakeService();
        System.out.println(snowFlakeService.getSnowflakeId());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值