在分库之后, 数据遍布在不同服务器上的数据库,数据库的自增主键已经没办法满足生成的主键唯一了
个人理解:分布式系统下,在分库分表之后唯一识别ID
从以下三个维度去分析
CREATE TABLE `sequence_id` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`stub` char(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
实现起来比较简单、ID 有序递增、存储消耗空间小
支持的并发量不大、存在数据库单点问题(使用主从模式来提高可用性)
批量获取,然后存在在内存里面,需要用到的时候,直接从内存里面拿就可以了
号:ID号,段:一段一段的取
CREATE TABLE `sequence_id_generator` (
`id` int(10) NOT NULL,
`current_max_id` bigint(20) NOT NULL COMMENT '当前最大id',
`step` int(10) NOT NULL COMMENT '号段的长度',
`version` int(20) NOT NULL COMMENT '版本号',
`biz_type` int(20) NOT NULL COMMENT '业务类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
相比于数据库主键自增的方式,数据库的号段模式对于数据库的访问次数更少,数据库压力更小。另外,为了避免单点问题,你可以从使用主从模式来提高可用性。
存在数据库单点问题(使用主从模式来提高可用性)
使用incr命令保证原子性地递增ID
127.0.0.1:6379> set sequence_id_biz_type 1
OK
127.0.0.1:6379> incr sequence_id_biz_type
(integer) 2
127.0.0.1:6379> get sequence_id_biz_type
"2"
性能不错并且生成的 ID 是有序递增的
存在单点问题,所以要做成Redis集群
比如使用 UUID 作为 MySQL 数据库主键的时候就非常不合适:
生成速度比较快、简单易用
需要解决重复 ID 问题(依赖时间,当机器时间不对的情况下,可能导致会产生重复 ID)。
UidGenerator 是百度开源的一款**基于 Snowflake(雪花算法)**的唯一 ID 生成器。
Leaf 提供了 号段模式 和 Snowflake(雪花算法) 这两种模式来生成分布式 ID。
Tinyid 是滴滴开源的一款基于数据库号段模式的唯一 ID 生成器。