欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

分布式ID生成解决方案

程序员文章站 2022-05-03 18:36:00
...

分布式ID生成解决方案

为什么要生成分布式ID?

答:如果一张表的数据过多,会影响性能,那么就会进行分表。但是分表会导致ID重复,那么以前的id就不能使用了,所以我们需要使用分布式生成ID

UUID

常见的方式。可以利用数据库也可以利用程序生成,一般来说全球唯一。

优点:

  • 简单,代码方便

  • 生成ID性能非常好,基本不会有性能问题

  • 全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对

缺点:

  • 没有排序,无法保证趋势递增
  • UUID往往是使用字符串存储,查询的效率比较低
  • 存储空间较大,如果是海量数据库,就需要考虑存储量的问题
  • 传输数据量大
  • 不可读

Redis

当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY来实现

优点:

  • 不依赖于数据库,灵活方便,且性能优于数据库

  • 数字ID天然排序,对分页或者需要排序的结果很有帮助

缺点:

  • 如果系统中没有Redis,还需要引入新的组件,增加系统复杂度
  • 需要编码和配置的工作量比较大
  • 网络传输造成性能下降

推荐开源算法snowflake(雪花算法)

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。核心思想是:使用41bit作为毫秒数时间戳,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后还有一个符号位,永远是0

分布式ID生成解决方案

snowflake(雪花算法)案例

步骤:

  1. 导入IdWorker工具类

  2. 在yml文件配置数据中心和机器ID

    workId: 0
    datacenterId: 0
    
  3. 在启动类把IdWorker载入Spring容器

        @Value("${workId}")
        private int workId;
    
        @Value("${datacenterId}")
        private int datacenterId;
    
        @Bean
        public IdWorker idWorker(){
            return new IdWorker(workId,datacenterId);
        }