只会单机执行定时任务?多机执行 yyds

本文介绍了在并发编程中,如何通过多机分片执行异步任务,避免多机处理相同数据的问题。文章阐述了应用场景,如DB中的订单处理,详细解释了令牌获取和分片获取DB数据的流程,并通过实战模拟展示了如何在多机环境中并发执行任务。同时,文章也讨论了这种方法的局限性和存在的坑。
摘要由CSDN通过智能技术生成

并发编程中,通过多机分片执行异步任务的一种实现姿势,实用性非常强!

大家好,我是楼仔!往期精选汇总于此 👉🏻👉🏻👉🏻《原创精选荟萃》,便于大家查阅。

执行异步任务时,比如需要处理10W个订单,如果是PHP,我们一般会配置一个定时任务,然后该定时任务就会在单机上执行;如果是GO或者JAVA,我们也需要使用相应的策略,保证该任务只在单机上执行,比如分布式锁。可能有同学会问,我直接在多机上执行同一个任务不行么,我只想说,你胆子真大,当多机同时处理一条数据,你会死的很惨的。

那我们是否有一种方法,可以让任务在多机同时执行,然后又可以避免多机同时处理相同数据的问题呢?这里给大家介绍一种多机分片的方式,也是最近在公司Get到的新技能。

应用场景

最近在做异步任务迁移,要求对DB中的订单进行处理,因为订单的数量非常大,10W的数量级是常规状态,如果只通过一台机器去处理,执行效率非常低,所以需要通过多机并发处理。

对于上述方式,其实还有另外一种解决方案,就是单机执行任务,然后把任务放入消息队列,再新增一个接口,用于消费队列中的数据,然后进行数据处理,因为接口对应的服务是集群部署,所以执行速度很快,不过这里在设计方案时,需要考虑消息重复消费,多机可能同时处理单条消息,网络异常导致消息未得到处理等问题,具体解决方案,欢迎大家线下和我讨论哈。

多机分片

什么是多机分片呢?说的通俗一点,就是把数据分成N份,分别给每一台机器执行。比如我们有1000条数据,通过相应策略,将数据分成5份,每份数据200条,如果我们有5台机器,那么每台机器可以分别处理200条数据。

那么具体是怎么实现?

为了更好讲解,我先简单模拟一下场景:

  • DB包含20条数据,DB主键ID为0、1、2、3 ... 19;

  • 有3台机器,每台机器起一个线程跑任务,共起3个线程;

  • 需要将数据分成10份,每份数据有2条,然后分给这3个线程。

令牌获取

将数据分成10分,就有10个令牌,即number=10,分别为0、1、2 ... 9,处理逻辑如下:

  • 每个任务有任务名,以任务名为key,通过increase=redis.incr(key)计数,然后将increase值通过number取模,得到令牌token=increase%number,第一次执行的increase=1,所以token=1%10=1;

  • 构造令牌tokenKey=key+token=key1,然后通过redis对tokenKey加一个分布式锁,如果加锁成功,返回令牌值;

  • 如果加锁失败,循环执行increase=redis.incr(key),此时increase=2,token=2%10=2,拿到令牌tokenKey=key2,再执行分布式锁,成功返回,未成功,同上依次反复。

Redis Incr 命令将 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。

分片获取DB数据

机器的线程拿到令牌后,就可以去分片获取数据了,假如DB的数据结构如下,且只有20条数据:

订单号orderId 商品名productName 配送状态status
0 数据线 0
1 键盘 0
2 显示器 0
... ... ...
19 鼠标 0

下面看一下分片获取数据流程:

  • 当线程拿到的令牌为token=0,可以通过select * from tableName wwhere orderId % 10 = token and status = 0 limit pageSize;(假如pageSize=100),因为取模匹配的数据的orderId=0和10,所以该线程可以拿到0和10这两条数据,如果pageSize=1,那就只能拿到0这条数据,数据10等下次处理时再获取;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值