分布式系统定义:一个硬件或软件组件分布在不同的网络计算机上,彼此之间通过消息传递进行通信和协调的系统。
一、概念
随着应用业务的复杂,用户量的增长,单机部署已经不能满足现有的需求了,随之而来的就是在数据库层分库、分表,以及分布式部署应用等。全局唯一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
 14- CREATE 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 = XXX
- Redis - incr
 
- Mongo 
| 1 | function getUniqId() { | 
- 雪花算法- Snowflake ID组成结构:正数位(1比特)+时间戳(41比特)+workId(10比特)+自增值(12比特),总共64比特组成的一个Long类型ID。
 
- Snowflake ID组成结构:
- 滴滴TinyId
- 百度UidGenerator
- 美团Leaf