题目:集群高并发情况下如何保证分布式唯一全局id生成?
文章目录
- 一、问题
- 二、一般通用方案
- 三、snowflake(雪花算法)
- 四、其它补充
一、问题
1 问题
1.1 为什么需要分布式全局唯一id以及分布式id的业务需求
1、在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识
2、如在美团点评的金融、支付、餐饮、酒店;猫眼电影等产品的系统中数据日渐增长,对数据分库分表后需要有一个唯一id来标识一条数据或消息;
3、特别一点的如订单、骑手、优惠券也都需要有唯一id做标识;
4、此时一个能够生成全局唯一id的系统是非常必要的。
1.2 id生成规则部分硬性要求
1.全局唯一:不能出现重复的id号,既然是唯一标识,这是最基本的要求;
2.趋势递增:在MySQL的InnoDB引擎中使用的是聚集索引,由于多数RDBBMS使用Btree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能
3.单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求
4.信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,需要ID无规则不规则,让竞争对手不好猜。
5.含时间戳:这样就能够在开发中快速了解这个分布式id的生成时间
1.3 ID号生成系统的可用性要求
1、高可用:发一个获取分布式ID的请求,服务器就要保证99.999%的情况下给我创建一个唯一分布式ID;
2、低延迟:发一个获取分布式ID的请求,服务器就要快,极速;
3、高QPS:假如并发一口气10万个创建分布式ID请求同时杀过来,服务器要顶得住且一下子成功创建10万个分布式ID;
二、一般通用方案
1、UUID
1.1 是什么
(如果只是考虑唯一性,OK)
1.2 But
2、数据库自增主键
2.1 单机
2.2 集群分布式
3、基于Redis生成全局id策略
3.1 因为redis是单线的天生保证原子性,可以使用原子操作INCR和INCRBY来实现
3.2 集群分布式
三种方案优缺点:
uuid:只有唯一性,趋势递增
mysql:唯一性,递增
redis:虽然五个算法思想满足,但是维护麻烦,如果整个系统不需要redis技术,但是为了生成id而使用redis来搭建,有点不划算(维护哨兵模式。。。)
三、snowflake(雪花算法)
Twitter的分布式自增ID算法snowflake
1、概述
2、结构
3、源码
github上有,是Scale语言写的,现在有人参考写出了java版本
4、工程落地经验
4.1 糊涂工具包
4.2 springboot整合雪花算法
4.2.1 pom
4.2.2 核心代码IdGeneratorSnowflake
@Slf4j
@Component
public class IdGeneratorSnowflake{
private long workerId = 0;
private long datacenterId = 1;
private Snowflake snowflake = IdUtil.createSnowflake(workerId,datacenterId);
@PostConstruct
public void init(){
try{
workerId = NetUtil.ipv4Tolong(NetUtil.getLocalhostStr());
log.info(“当前机器的workerId:{}”,workerId);
}catch(Exception e){
e.printStackTrace();
log.warn(“当前机器的worker获取失败”,e);
workerId = NetUtil.getLocalhostStr().hastCode();
}
}
public synchronized long snowflakeId(){
return snowflake.nextId();
}
public synchronized long snowflakeId(long workerId,long datacenterId){
Snowflake snowflake = IdUtil.createSnowflake(workerId,datacenterId);
return snowflake.nextId();
}
public static void main(String[] args){
System.out.println(new IdGeneratorSnowflake().snowflakeId());
}
}
5、优缺点
四、其它补充
ps:如果实在考虑到雪花算法的时钟回拨问题,业内有以下两种解决方案。
1、百度开源的分布式唯一Id生成器UidGenerator
2、Leaf – 美团点评分布式ID生成系统