zoukankan      html  css  js  c++  java
  • 处理大量数据的性能优化一例【我】

    场景:

    一个需求是需要处理一个txt文件中的数据,具体要求:

    每个txt文件中数据上限是20W。

    最开始的方式:

    将txt中的记录逐条存入一个表中,然后遍历表中的记录,一条一条的处理,处理每一条记录时,大约需要查询6次数据库,插入6次数据库,更新3次数据库。

    问题:

    发现处理的速度比较慢,大概1秒中处理一条记录。

    ---------

    需求要求提高效率。

    考虑到是单线程处理,所以提速首先想到开多线程。

    --------

    改进方式1:

    开启多线程分批处理数据,每个线程处理100条左右数据。

    问题:

    测试发现,当线程数少于4个时,每条数据的响应约为200毫秒,但是当线程数增多时,每条数据响应时间开始增大,5个线程单条响应500毫秒,7个以上线程响应时间1000毫秒以上。

    所以不管开了多少线程,实际速度只增加到了5倍左右。

    通过在程序运行时监控应用服务器性能未发现问题,监控数据库(数据库采用代理的mysql分库分表),发现数据库服务监控显示数据库每个节点的写IO都达到了97%以上(写入速度每秒钟1M),感觉因为数据库写IO能力太差,造成的请求都在写等待。

     -------

    分析:数据库的写IO造成了瓶颈,因为当前20w的数据,都是逐条处理,没条处理过程中,需要查询6次数据库,插入6次数据库,更新3次数据库,缺点就是:1,逐条连接数据库频繁开启、关闭事务,影响数据库性能。2,因为数据库的写IO能力很差,而每条记录处理时都要写6次数据库,并发时,数据库写io等待,而写IO等待,又可能会影响查询数据的速度,造成后面的记录处理时间都增大。

    解决思路:在多线程处理数据的过程中,只逐条查询数据库,将所有的插入、更新操作都缓存到redis的list中,然后等所有的线程都处理完,再批量插入、更新数据库,这样就在代码中做到的了1:读写分离 2:改逐条开启事务插入数据为批量单线程插入数据。

     --------

    根据分析将代码修改后,发现问题:

    虽然数据库的写IO占用百分比下降了,但是性能并没有提升,反而即使开一个线程,每条记录响应也在1000毫秒。

     ----------

    事后分析:

    因为项目分了两个服务部署,改进后是在服务1中根据对批量数取模的方式分配待处理数据,然后开启多线程,在多线程的每一批数据中逐条调用服务2(通过dubbo的rest服务通信)处理单条记录,通过日志发现,服务1发起调用服务2的请求后,在服务2中接收到请求需要1秒以上的延时,也就是说时间全部浪费在两个服务的相互调用上(而且每次调用都需要返回大量数据,这也可能造成速度慢),根据公司大拿分析,我们的dubbo服务提供配置文件中,每个接口都是用的rest协议,而不是dubbo协议,Rest协议是基于http的短链接协议,会产生大量的http time-wait.适应于对外提供服务时使用,dubbo协议为tcp的长链接协议。对外服务,使用rest协议,对内服务,使用dubbo协议。也就是说dobbo效率更高,所以我们应该将原来基于http的rest协议改成dubbo协议。

     --------

    改进方式2:

    将dubbo服务的service.xml配置文件中原来的rest协议,改为dubbo协议;

    修改业务逻辑,将原来的在服务1中开启多线程然后逐条调用服务2改为在服务1中开启多线程,然后将每个线程中的一批数据的获取方式传递给服务2,也就是改为一批数据用一个线程交给服务2进行处理,然后在服务2中一批数据循环处理,将要插入、更新数据库的数据直接扔到redis中,然后最后在所有线程都结束后,在服务1中从redis中取数据单线程批量插入数据库。

    这样就将原来的20w数据需要两个服务直接调用20w次改为,每批1000条处理,只需要相互调用200次,大大减少了服务间的调用网络耗时,而且避免了传递大量参数。

    最终测试,可以开到10个线程,每个线程的每条记录都在200毫秒的响应,也就是效率提高到了每秒钟30条。

  • 相关阅读:
    给元素查索引
    数组的反转和排序
    本地修改文件到git
    +new Date()
    文字双层投影
    表格组件 自定义宽度 设置 span 内容 超出省略号
    iframe的使用
    分页获取列表进行索引累加
    日期时间格式化
    柱状echarts 自定义图例设置
  • 原文地址:https://www.cnblogs.com/libin6505/p/10761613.html
Copyright © 2011-2022 走看看