### 背景

应用实例部署在多个机房,不同机房的应用实例使用同一个 DB ,但是受 xxx 风险规则,不同机房不能够使用同一个 Redis:


[![4871727195768_.pic.jpg]( https://s1.locimg.com/2024/09/25/5f1f0d2133d1e.jpg)]( https://s1.locimg.com/2024/09/25/5f1f0d2133d1e.jpg)

然而应用中有一个定时任务会按时扫描 DB 中的某个表的记录执行相应的动作 Action ,并将结果回写到这条记录中。

一个非常直觉的想法是,使用分布式锁实现某个记录只有一个应用实例在操作。但受限于上述规则而无法实现。

因此,想问下该怎么实现才能保证一个记录不会被多个实例同时操作呢?

### 思考

目前几个非常直觉的想法是:

1.应用在扫表后会得到一批记录,每次在执行动作 Action 之前,给这个记录加个行锁?理论上是可行的,但不知道这种加锁的方式是否合适以及代价/风险。

2.每次只让一个机房的应用实例扫表,这样子同机房就可以使用 Redis

3.给 DB 加个字段让每个机房只搞自己的,当某个机房发生故障的时候手动改配置,让另外一个健康机房可以扫故障机房的单子。

感觉方法都有点野蛮... 另外这需求其实用消息队列应该是比较优质的解法,但目前规模不大,都不太想用到 Q...
举报· 135 次点击
登录 注册 站外分享
19 条回复  
mooyo 小成 2024-9-25 00:54:45
我感觉怎么设计都会有问题,一个最核心的问题是 你的 action 是可以重放的吗。如果不是的话,即使有 redis 分布式锁,你怎么解决如果扫到一个 action ,执行了一半挂了的情况呢。
zdking08135 初学 2024-9-25 01:09:05
尽量设计成一个实例操作一部分数据,没必要用锁竞争。
做好监控的话,实例挂了的情况其实很少见,直接处理就行了。
Maboroshii 小成 2024-9-25 01:16:32
使用 db 实现分布式锁是一样的啊,乐观锁 update
GeekGao 小成 2024-9-25 05:53:58
同意楼上观点
Aruforce 初学 2024-9-25 08:41:33
@Maboroshii 这个挺好的
Goooooos 初学 2024-9-25 08:42:45
db 建一个 lock 表,里面只有一个主键和一个 fersion ,就能实现乐观锁
yangtianming 小成 2024-9-25 08:46:26
楼主想要实现的就是分布式锁,感觉学的有点死了,分布式锁可以通过 redis 实现,当然也可以通过 mysql 实现
dddd1919 初学 2024-9-25 08:52:49
既然是数据库,那直接行锁啊😂,如果没有大量并发,用 redis 加锁也属实倒反天罡
sagaxu 初学 2024-9-25 09:03:38
1. 行锁可能会跟其它业务逻辑中的行锁打架,锁时间长了影响业务,加多了还容易死锁,
2. 如果扫表负载不高,直接指定某个机房负责扫表也行,不用分配也不用轮流
3. 不用加字段,直接按 ID 分配机房就行,出问题了手动切

2 或 3 都行,把切机房的开关做方便点
12下一页
返回顶部