分布式系统定义:一个硬件或软件组件分布在不同的网络计算机上,彼此之间通过消息传递进行通信和协调的系统。
一、概念
随着应用业务的复杂,用户量的增长,单机部署已经不能满足现有的需求了,随之而来的就是在数据库层分库、分表,以及分布式部署应用等。全局唯一ID,其实就是在分布式应用中唯一标识某条记录的ID。生成全局唯一ID有两个基本要求:全局唯一性、趋势有序性。
ID生成系统的需求
- 全局唯一性:不能出现重复的ID,最基本的要求。
- 趋势递增:MySQL InnoDB引擎使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应尽量使用有序的主键保证写入性能。
- 单调递增:保证下一个ID一定大于上一个ID。
- 信息安全:如果ID是连续递增的,恶意用户就可以很容易的窥见订单号的规则,从而猜出下一个订单号,如果是竞争对手,就可以直接知道我们一天的订单量。所以在某些场景下,需要ID无规则。
二、常见算法
uuid
- 生成足够简单,本地生成无网络消耗,具有唯一性
- 无序的字符串,不具备趋势自增特性
- 没有具体的业务含义
数据库自增id
- 实现简单,ID单调自增,数值类型查询速度快
- DB单点存在宕机风险,无法扛住高并发场景
数据库多主模式
- 分别设置起始值和自增步长
- 可以解决DB单点问题
- 不利于后续扩容,高并发下单个数据库自身压力大
号段模式
- 从数据库批量的获取自增ID如1~1000并缓存在本地,减少数据库请求次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14CREATE TABLE id_generator (
id int(10) NOT NULL,
max_id bigint(20) NOT NULL COMMENT '当前最大id',
step int(20) NOT NULL COMMENT '号段的布长',
biz_type int(20) NOT NULL COMMENT '业务类型',
version int(20) NOT NULL COMMENT '版本号',
PRIMARY KEY (`id`)
)
biz_type:不同业务类型
max_id:当前最大的可用id
step:号段的长度
version:乐观锁
update id_generator set max_id = #{max_id+step}, version = version + 1 where version = # {version} and biz_type = XXXRedis
- incr
Mongo
1 | function getUniqId() { |
- 雪花算法
- Snowflake ID组成结构:
正数位(1比特)+时间戳(41比特)+workId(10比特)+自增值(12比特)
,总共64比特组成的一个Long类型ID。
- Snowflake ID组成结构:
- 滴滴TinyId
- 百度UidGenerator
- 美团Leaf