多服务器对于同一批数据进行并发批处理的控制

2024-03-20  本文已影响0人  名字是乱打的

背景:我们有一批数据在数据库里,要进行到期处理并推送到mq,处理并推送小于等于当前时间的数据.
需求:
1.我们要求任务处理服务要做到高可靠性,因此需要搞成多机分布式服务,即使一个服务挂了,还有别的服务可以使用可以处理
2.保障各个服务均可以同时拿到数据进行高效处理
3.数据不能重复处理

方式一.悲观锁形式:事务+select for update

本文先提供一个没有采用的方式--采用事务加select for update的形式

这么做呢就有个非常严重的问题,---同一时刻只有一个有效服务
如果A系统拿到了数据,开始了事务但是没提交,那么B系统同样的条件也会查到同一批还没处理好提交的数据,此时B系统该查询线程就会阻塞等待A提交事务.这么看问题就来了,这里虽然保障了同一时刻只有一个服务可以拿到并处理一批数据,但是也导致了效率特别低,而且后面无论扩展多少服务应用都没啥用

方式二.预更新+lock_key方式 (无锁,我们目前采用的方式)

步骤解释:

方式三.redis zset 双写服务--强烈推荐

我这里只写了大致的方案,一些redis高可用以及数据幂等性自己考虑去.

这种方式是我觉得最好的方案了,完全保障了每个服务每次处理mysql的数据都是互不相同的数据,完全避免了竞争问题.

但是我们目前没有用这种方案,原因是...目前我们redis内存只申请到一个比较小的内存,而zset采用的跳跃表结构虽然保障了数据查询非常快速,但是也非常占用内存,预估了一下按照我们的数据量起码要存储300万数据,用到的内存量是3~4G之间,好家伙直接把我们所有内存都用了,其他服务还用个屁...而且这玩意为了保障数据安全,不进行数据淘汰起码还要留个1G空闲安全空间....那肯定就用不了了

提供一个redis官方提供的容量预估功能的工具http://www.redis.cn/redis_memory/

如果你们的服务数据量够小或者内存够大,redis又做到了高可用,高可靠,那么我还是十分推荐用这种方案,毕竟很多服务都是性能为王!

上一篇 下一篇

猜你喜欢

热点阅读