分布式系统大数据量计算抢占式任务调度

业务背景:

XX系统为支撑电商平台的微服务系统,系统为电商平台提供搜索页、四级页、加入购物车等提供查找货源唯一四要素接口服务,通过商品主数据、上下架信息、销售范围、供应链规则、售价、库存等信息计算获取货源,并通过售价、库龄、时效等比较获得最优货源。

 

系统设计

为了支撑高并发,高访问的业务特性,系统在设计的时候考虑在每晚凌晨计算所有商品的货源信息(称为全量计算),计算完成后,如果外围系统通过MQ(消息队列)同步来的数据影响到查找货源的计算,则会将影响的商品数据异步的放入动因范围表中,JOB扫描动因范围表,重新计算受影响商品的货源(称为动因计算)。

 

对外提供的服务接口直接在已有货源的基础上进行过滤,计算。

 

系统实现(全量计算&动因计算):

由于每天计算量巨大,因此会使用多台机器进行并行计算。需要解决如何调度这些机器有条不紊的计算?

 

设计调度方案如下:

           1. 按照商品编码后三位 000-999分为1000个号段 建立任务调度表

           2. 多台机器每个机器都有各自唯一的jobID,争抢号段进行计算,如果抢到该号段,将号段设置为执行状态,锁定该号段后通过该号段查询对应商品进行计算。

           Question?  --- 多台机器争抢号段,可能发生同时update一条号段记录的情况,对数据库也存在压力,这里为了减少数据库碰撞,设计为构建一个redis的缓存list队列,将所有待处理号段初始化进去,每个机器争抢的时候从list中取出一个号段,然后update,这样减少了碰撞,保证按照顺序执行。

 

这样设计的好处是资源(机器)和调度任务解耦,并且也保证了高可用性 就算部分机器挂掉,也能保证正常计算。

详细实现:

1. 任务调度表

/*'号段争抢调度表'*/
CREATE TABLE TASK_SCHEDULE 
(
   id                   INTEGER  AUTO_INCREMENT PRIMARY KEY,
   post_num             VARCHAR(10)  NOT NULL /*'号段(000-999)'*/ ,
   handle_status        INTEGER      NOT NULL /*'处理状态 0 待处理 1 在执行 2 已完成 3 异常'*/,
   jobID                VARCHAR(10)   /*'抢到该号段的jobID'*/
) ENGINE=INNODB DEFAULT CHARSET=utf8;

2. 逻辑流程图

 

 

 3 其他

   为了保证全量计算的高效率及高可用性,设计表会有A,B两套表,每天用一套表,在全量计算的时候,清空更新时间最老的表,然后将计算结果插入,如果全部计算成功,进行切表操作,保证了高可用。

猜你喜欢

转载自wodeguozili.iteye.com/blog/2387171