posts - 206,  comments - 26,  views - 17万
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

  一、分布式ID简介


  如何在分布式环境下,进行分布式文件ID的生成,需要保证当前ID的全局唯一性。
  为什么要进行分布式ID的生成,为什么要保证全局的唯一ID?


  在互联网类型的项目中,需要存储的数据量非常庞大,如果单表数据量非常庞大,会造成数据库瓶颈问题,会导致当前数据库的运行速度非常慢。因此 在生产环境下,对于这个问题的解决,我们会采用分库分表以及数据库多实例部署方案。

  当采用了分库分表方案后,如果说每张表的ID还 是采用主键自增的这种方案的话,就会造成重复ID的出现。比如:只有一张订单表,采用自增ID没有任何问题,如果采用了分库分表之后,将原有的一张订单表拆分成了多张订单表,并且进行了数据库多实例部署之后,还采用主键自增的话,就会出现不同订单,ID重复的问题。

  当采用了分库分表后,原始的ID自增方案就不能用了,需要来考虑分布式ID的生成,以及全局ID的唯一性。现在需要基于分布式环境下进行分布式ID的生成,并且对于当前分布式ID生成了之后,还需要保证全局ID的唯一性,避免重复ID的出现。

 

  二 、分布式ID生成解决方案
  分布式ID生成解决方案:

  2.1 UUID
  常见的方式。UUID大家比较熟悉,我们之前都是用过,我们可以通过UUID去生成一个随机的32位长度的字符串。一般来说全球唯一。

  优点:

  1)操作简单,代码方便。

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

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

  缺点:

  1)没有排序,无法保证趋势递增。

  2)UUID往往是使用字符串存储,查询的效率比较低。

  3)存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。

  4)传输数据量大

  5)不可读。

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

  优点:

  1)使用灵活,性能好,不依赖于数据库,且性能优于数据库。

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

  缺点:

  1)如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。

  2)需要编码和配置的工作量比较大。

  3)网络传输造成性能下降。

  2.3 开源算法snowflake
  snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。snowflake本身是一个算法,通过它可以得到一个long类型的值,可以对它进行排序。它不像redis是由第三方生成的,snowflake(雪花算法)本身只是一个算法而已,谁都可以基于这个算法在本机进行id的生成,所以不会造成网络性能的消耗。雪花算法内部如何进行ID值得生成:

  其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0

 

 

  本系统中采用的就是开源算法snowflake

  三、 snowflake快速入门


3.1 快速入门
(1)新建工程,将工具类IdWorker.java拷贝到工程中。

(2)编写代码

        IdWorker idWorker=new IdWorker(1,1);
​
        for(int i=0;i<10000;i++){
            long id = idWorker.nextId();
            System.out.println(id);
        }

 



3.2 配置分布式ID生成器
(1)IdWorker.java拷贝到shangcheng_common工程com.shangcheng.util包中

(2)shangcheng_service_goods的application.yml添加配置

workerId: 0
datacenterId: 0

 


(3)修改GoodsApplication,增加代码

复制代码
    @Value("${workerId}")//配置文件获取
    private Integer workerId;
​
    @Value("${datacenterId}")//配置文件获取
    private Integer datacenterId;
​
    @Bean
    public IdWorker idWorker(){
        return new IdWorker(workerId,datacenterId);
    }
复制代码

 

posted on   努力--坚持  阅读(17)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签
历史上的今天:
2018-12-23 .Net中的反射作用
点击右上角即可分享
微信分享提示