前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >巧用CAS,一分钟实现分布式ID生成器!(第43讲)

巧用CAS,一分钟实现分布式ID生成器!(第43讲)

作者头像
架构师之路
发布2025-03-10 21:01:24
发布2025-03-10 21:01:24
3700
代码可运行
举报
文章被收录于专栏:架构师之路架构师之路
运行总次数:0
代码可运行

《架构师之路:架构设计中的100个知识点》

43.CAS应用案例

库存扣减异常怎么办?(41)》采用CAS思想,两行代码解决并发扣减异常。

redis解决库存并发扣减异常问题?(42)》采用CAS思想,借助redis解决并发扣减异常。

有童鞋留言,CAS还有其他应有场景吗?

场景很多,今天分享一个巧用CAS实现分布式全局唯一ID生成的场景。

如何快速生成全局唯一ID?

可以借助DB自增键(auto inc id),插入一条记录,生成一个ID:

图片
图片

这个方案复用了数据库的特性,其优点为:

1. 无需写额外代码;

2. 全局唯一;

3. 绝对递增;

4. 递增ID的步长确定;

业务早期“并发量小”,追求“快速实现”,这么玩没问题。

这种方案有什么缺点?

1. 数据库中记录数较多;

2. 生成ID的性能,取决于数据库插入性能;

3. 并发量大了,数据库扛不住;

可以怎么优化?

1. DB只保留max-id一条记录;

2. 增加一层服务,采用批量生成的方式降低数据库的写压力,提升整体性能;

更具体的操作如下:

步骤一,id-s服务首先拉取当前的max-id。

图片
图片
代码语言:javascript
代码运行次数:0
复制
select max_id from T;

步骤二,批量获取一批ID,放到id-s内存里,并将max-id写回数据库。

图片
图片
代码语言:javascript
代码运行次数:0
复制
update T set max_id=200;

如上图所示,id-s拿到了[100, 200]这一批ID,上游在获取ID时,不用每次都插入数据库,而是分配完100个ID后,再修改max-id的值,这样分配ID的整体性能就增加了100倍。

这种方案还有什么缺点?

服务没有做HA,无法保证高可用。需要冗余服务,做集群保证高可用。

冗余服务可能带来什么新的问题?

和高并发库存扣减出现的问题类似,冗余了服务后,多个服务在启动过程中,进行ID批量申请时,可能由于并发导致数据不一致。

图片
图片
代码语言:javascript
代码运行次数:0
复制
select max_id from T;

步骤一:两个id-s同时拿到了max-id为100

图片
图片
代码语言:javascript
代码运行次数:0
复制
update T set max_id=200;

步骤二:两个id-s同时对数据库的max-id进行写回;

写回max-id成功后,这两个id-s都以为自己拿到了[100,200]这一批ID,导致集群会生成重复的ID。

导致bug的原因在哪里?

并发写回时,没有对max-id的初始值进行比对

1. id-s1写回max-id=200成功的条件是,max-id必须等于100;

2. id-s2写回max-id=200成功的条件是,max-id也必须等于100;

而实际情况是:

1. id-s1写回时,max-id是100,理应写回成功;

2. id-s2写回时,max-id已经被改成了200,不应该写回成功;

如何巧用CAS修复?

在写回时对max-id的初始条件进行比对,就能避免数据的不一致,写回SQL由:

代码语言:javascript
代码运行次数:0
复制
update T set max_id=200;

升级为:

代码语言:javascript
代码运行次数:0
复制
update T set max_id=200
where max_id=100;

升级之后,s1和s2只会有一个成功。另一个失败之后,重新查询数据库得到新的max-id为200,再次申请[200,300]的ID,就能够成功。

CAS优化方案的优点是:

1. 能够通过水平扩展的方式,达到分布式ID生成服务的无限性能;

2. 方案简洁性;

3. 保证不会生成重复的ID;

知其然,知其所以然。

思路比结论更重要。

==全文完==

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 架构师之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档