avatar

分布式ID问题

在分布式集群环境下,很容易出现id重复的情况,比如说,当数据库单表条数太多时我们需要分库分表,分表之后ID不能使用自增,并且不能重复,这个时候就出现了分布式ID问题。我们需要分布式环境下的全局唯一ID。

分布式ID生成方案

UUID

UUID是指Universally Unique Identifier,翻译成中文是通用唯一识别码
产生重复UUID并且造成错误的情况非常低,是故大可不必考虑此问题。
java中得到一个UUID,可以使用java.util包提供的方法

public class MyTest{
public static void main(String[] args){
System.out.printLn(java.util.UUID.randomUUID().toString());
}
}

缺点是:生成的id特别长同时没有什么规律可循

独立数据库的自增ID

其主要方式就是新建一个独立的数据库,并且建立一张表存放自增id和其余字段,每次业务数据库需要主键时,先从独立数据库新增一条数据,并且获取到该自增id,拿到这个id再往业务数据库存放数据。

  • 首先创建一个数据库和数据表
    DROP TABLE IF EXISTS `DISTRIBUTE_ID`;
    CREATE TABLE `DISTRIBUTE_ID` (
    id bigint(32) not null auto_increment comment '主键',
    createTime datetime DEFAULT NULL,
    primary key (`id`)
    ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
  • 当分布式集群环境下哪个应用需要获取到一个全局唯一的分布式id的时候,就可以使用代码连接这个数据库实例执行如下语句即可
    -- distribute_id 是独立数据的表
    insert into distribute_id(createTime) values(now());
    -- 获取新增的id
    select LAST_INSERT_ID();
    缺点:
  • 使用独立的mysql实例生成分布式id,虽然可行,但是性能和可靠性都不够好,因为你需要代码连接到数据库才能获取到id,性能无法保证,另外mysql数据库实例挂掉了,那么就无法获取分布式id了
  • 不建议在生产环境使用

雪花算法

雪花算法是一个算法,基于这个算法生成的ID,生成的ID是一个long型,那么在java中一个long型是8个字节,算下来是64bit,如下是使用雪花算法生成的一个ID 的二进制形式示意:

算法实现

Redis的lncr方案

文章作者: zenshin
文章链接: https://zlh.giserhub.com/2022/01/10/cl35o0mr0003fp4tg6ieq6zkk/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 zenshin's blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论