记一次性能优化的艰苦历程

场景:系统A 每天会不定期往系统B 通过文件的形式输送大概200到300万的数据,B 系统需要首先解析文件拿到这些数据并存储到系统B 中,同时系统B 的定时任务还需要根据这批数据生成一批数据,并把数据在通过RocketMQ 推送到系统C 当中,当然生成数据和推送是分两个定时任务执行的,
遇到问题:首先开始需求没有说明白这个接口需要承接百万数据量,所以导致采用的普通的处理方式,效率极慢,压测时,百万数据长达1个小时处理,毫无疑问,直接呗测试打回,
解决方案: 准备从两个方向入手,第一线程池技术,第二数据库索引
第一 、线程池技术,
引入线程池技术,那么就需要注意线程安全问题了,此处我们不讨论线程安全,要创建一个线程池,我们此次使用的下面的线程池

    final static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 8, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(500), new ThreadPoolExecutor.CallerRunsPolicy());

首先我们要知道几个参数 ,核心线程数,总线程数,线程空闲时间,时间单位,队列初始化长度,拒绝策略
这个参数一般是根据服务器,JVM 的容量等参数经过计算出来的,不是说线程越多执行效率就越高,
我们此处设定3个核心线程数,8个总线程数,线程空闲时间 30 时间单位 秒,队列初始容量 500 ,这个值也是要经过计算的,我试过了,如果容量太大,会出现 java.util.concurrent.RejectedExecutionException
这个错误,所以大家不要随心所欲哦,当然这个错误是指你创建的线程太多的,导致队列都满了之后才会出现这样的问题。此处大家要处理了,那么创建了线程池,每个线程的数据量如何计算呢,我们此处采用的是 分页来处理,因为我们单纯的计算了一下,如果我们每个线程处理1000数据量来说,每个线程
两个容量是1000的集合,创建1000个对象,总共是3000 的容量,那么8个线程数,就是2万4 了,还有一些其属性等,2万多,我觉得还行,好接下来线程池这块就这么确定下来了,
分页处理,每批次1000,此时没有运用到索引,执行速度是54分钟,这个速度显然不合格呀,咋办呢,

第二点、数据库索引
首先给常用的字段建立组合索引,如那个会有模糊查询的字段单独建立一个索引,同时在书写sql 时,索引字段在前,非索引字段在后,模糊搜索在后,且如果模糊搜索字段和其他索引同时存在,只有模糊搜索字段的索引会起效果,此处需要注意,否则,恰当的索引可以极大的提高我们的执行效率,经过添加索引之后,加上多线程我们的执行效率有了一个质的飞越,时间来到了22分钟,因为我们对于时间要求咋30分钟内即可,所以基本算是完成了。
今天主要是把这个思路和方式方法记录下来,以后遇到了可以作为一个思路和启发吧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值