在分布式集群环境下,很容易出现id重复的情况,比如说,当数据库单表条数太多时我们需要分库分表,分表之后ID不能使用自增,并且不能重复,这个时候就出现了分布式ID问题。我们需要分布式环境下的全局唯一ID。
分布式ID生成方案
UUID
UUID是指Universally Unique Identifier,翻译成中文是通用唯一识别码
产生重复UUID并且造成错误的情况非常低,是故大可不必考虑此问题。
java中得到一个UUID,可以使用java.util包提供的方法
public class MyTest{ |
缺点是:生成的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方案
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 zenshin's blog!
评论