技术博客
分享
分布式唯一ID生成系统的设计和实现
输入“/”快速插入内容
分布式唯一ID生成系统的设计和实现
飞书用户4979
2024年3月24日修改
前言
系统能力
1.
高可用(4个9,甚至5个9)
2.
低延时(平均延迟和TP999延迟都要尽量低)
3.
高QPS
4.
支持区分不同的服务场景,不同的服务场景id独立维护,且
支持配置起始id
5.
支持
批量生成
唯一id
6.
对内部的业务服务提供生成唯一id的
grpc接口
方案对比
•
号段模式
和
雪花算法
•
部署架构。 能支持优先同IDC的发号服务的调用
概要设计
IDMaker
需求概述
•
高可用(5个9)、低延时(平均延时和TP999)、高QPS
•
对内支持批量的rpc接口
•
支持不同业务自定义起始id(号段模式支持)
•
根据不同的场景,支持不同的模式。 如非订单类的id获取,可以用号段模式(支持指定起始id), 订单类的id获取通过snowflake生成
架构设计
设计要点
号段模式
•
基于美团开源的Leaf-segment,为了支持现有的服务治理和可见性能力, 因此考虑用go-zero框架重写
•
基于Mysql存储每个业务的号段长度、当前最大ID值
•
采用号段双缓存设计,启动时加载指定长度的号段到本地,并在该消耗10%时,异步更新下一个号段
•
因为有本地的缓存,因此可以适当加大号段的长度,来实现DB短时不可用时,IDMaker仍可对外提供服务
•
每次请求时都会判断是否要异步更新下一个号段,因此偶尔的网络抖动不会影响下个号段的更新
Snowflake算法
•
由于美团的Leaf-snowflake对时钟回拨问题处理比较粗暴(超过5ms)直接返回,且引入了zk/etcd来做机器id生成,因此考虑基于百度开源的CachedUidGenerator,同样为了支持服务治理和可见性能力,需要用go-zero框架进行重写
•
唯一id所占的位数支持根据使用场景(重启频率、期望运行时间、并发生成数)来调整
•
RingBuff。双环形缓存,一个存储Uid(容量可根据吞吐量要求、系统内存,进行配),一个存储Uid的状态(可生产/可消费)。 环形的填充策略可配(包括启动填充、获取uid是判断填充、定时填充)
•
通过时间戳部分递增,以及重启都将机器id加1,解决snowflake算法的时钟回拨问题
号段模式的详细设计
号段生成流程
•
加载/更新不同业务的号段分配的配置。 启动时加载、1分钟定时更新
获取唯一ID流程