您的位置:首页 > 数据库 > Redis

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

2015-11-20 00:00 429 查看
摘要: 这是系统实际运行中碰到的一个问题,设计到接近一千万的数据处理,性能要求较高,所以使用了多线程生产消费模式。

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

一、问题原因

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、程序流程图:



3、运行结果:

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

4、问题原因:

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

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

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

四、优化后方案

1、优化点:

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

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

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

2、程序流程图:



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

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

五、优化总结

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

1、 SQL优化:

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

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

2、 设计模式:

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

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

3、 线程回收:

在使用多线程的时候,必须具备完善的线程回收机制。例如在无数据时回收线程,或者在一个时间段之后回收,以保证CPU不被过多的占用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: