基于redis的多线程生产消费模式

订单新旧客状态处理方案优化

一、问题原因

     1、线上发现一个数据问题,在2015年1月12号到2月4号,有一部分订单出现“新旧客”标识与“佣金比例”不匹配。

     2、分析发现问题原因是2月5号上线了新的版本,更改了订单新旧客的判断标准;上线后的代码通过25天同步任务,修改了部分之前25天的“新旧客”状态,但是并没有修改相应的佣金比例。

二、处理需求

     1、由于佣金比例经过了方案修改,无法通过SQL精确查出所有的异常订单,所以需要通过程序遍历所有订单,找出订单之前的新旧客状态,并且进行修改。

     2、订单时间段:1月12号-2月4号

     3、订单量:700W订单

     4、问题订单预估:1W

三、初步方案

      1、处理方案:

         1)首先分页取出当前CPS数据库的所有订单

         2)使用订单号通过order-api按照以前的逻辑,进行判断所有订单的新旧客状态

         3)将上一步判断的新旧客状态与现有数据库里面的状态进行对比,如果有差异,则将差异信息写入redis

         4)将redis里的差异订单,更新到数据库中

      2、程序流程图:

      114615_n9P1_2485991.png


3、运行结果:

程序运行后,可以正确更新订单的新旧客状态。但是程序性能出现问题,生产者线程存在阻塞,运行非常缓慢。更新一天的数据需要5个小时,而且越往后越慢。


4、问题原因:

   1)查询CPS库中订单方法有问题,直接对25天的订单进行分页,造成了查询速度缓慢,严重影响了数据库性能。

   2)查询SQL的排序方式有问题,增加了额外的数据库开销。

   3)生产者线程中,采用串行的方式进行查库、两次查询order-api、比较数据等操作,影响了生产的速度。

四、优化后方案

1、优化点:

   1)查询条件切片,将查询条件切分为2个小时一段,提升SQL查询速度

   2)排序方式按照数据库里现有的顺序,采用顺序排序,使得无需增加额外开销

   3)将生产者进行拆分,按照流水线模式,切分为多个生产者,进行并行数据生产。


 2、程序流程图:

114634_UCwA_2485991.png 

      


3、运行结果:能正确处理所有异常订单,并且效率超高。处理速度达到了4分钟一天,700万订单花费一个半小时。

     

 4 、缺陷:由于采用多个线程池进行并行处理,效率高的同时造成了CPS占用飙升,使用率达到了100%,监控中心告警。

五、优化总结

   在以上的两个方案中,可以总结出几个程序优化的方法:

   

1、  SQL优化:

1)  做查询时,要考虑到总体的数据量。对查询条件进行切分,再进行分页查询。同时查询条件一定要走索引。

2)  排序尽量顺序排序,减少数据库的性能消耗


2、  设计模式:

1)  对性能要求较高时,可以采用多线程的方式进行程序处理。

2)  更进一步,使用生产消费模式。将业务逻辑拆分成一个个处理单元,进行多线程池的并行处理。这样可以极大的提升程序性能;但同时能带来大量的系统资源消耗,要根据机器性能谨慎使用。


3、  线程回收:

在使用多线程的时候,必须具备完善的线程回收机制。例如在无数据时回收线程,或者在一个时间段之后回收,以保证CPU不被过多的占用。



转载于:https://my.oschina.net/u/2485991/blog/533140

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值