我们为什么要实现分布式计算(一)

4 篇文章 0 订阅
4 篇文章 0 订阅

先回答一下标题, 原因很简单, 踩坑.

很久很久很久之前, 有一段祖传代码, 有多久? 久到离谱... 那时候的世界很简单, 人们都玩着单机游戏....好, 回归正题, 先让看看大家看看祖传代码

        System.out.println("开始全量计算企业评价结果.updateAllXyztEvaResult");
       // PreparedStatement ps = null;
        //ResultSet rs = null;
        //Connection conn = null;

        try {
            //conn = jdbcTemplate.getDataSource().getConnection();
        	String querySql = "SELECT MASTERDATAID,ZTMC FROM " + clscode;
            List<Map<String, Object>>  list=jdbcTemplate.queryForList(querySql);
            int i = 0;
            System.out.println("开始循环计算...");
            for (Map<String, Object> map : list) {
               //省略大概500行..根据map对象获取数据和根据模型计算/还有递归...
            }
           }

别急着吐槽, 那个年代单表也就几百上千的数据, 单机循环跑挺安稳的....

随着时代的变化, 数据量的膨胀, 单表从几百上千到几万上几十万(几十万就膨胀了? 大厂都笑了)

因为咱们的业务不需要实时计算, 计算周期可以非常的长...但是为了效率, 咱们还是把多线程加了进来, 为了避免一次查询过多内容导致内存占用太大, 每查到1000个计算主体就生成一个任务, 放到线程池队列里面, 单机跑着定时任务, 核心也是那段祖传代码, 就长出了第二个版本.  .  大概是这样的:

 

 效率也还行, 在各个业务项目里面跑着也没发生什么问题..没记错的话还支撑过超200万的主体表..

然后到了最近的某个项目, 也还是这个配方, 某位不愿意透露真实姓名的同学却是一筹莫展..只要应用发布到生产环境,运行起来就会挂...日志打印看着运行速度还是很快的, 但就是过一会就内存满了, 崩了. 本地测试也都没问题, 运行正常, 整天喃喃吐槽服务器. CPU差,内存少, 磁盘慢, 人都不好了..刨去了N多与本方法无关的代码之后, 翻到了核心代码:

            int page = 0;
            boolean hasData = true;
            while (hasData) {
                int currLimit = page == 0 ? 0 : page * 1000 - 1;
                //TODO List<Map<String, Object>> pageList 是否可以使用Lucene (注意:(lucene)更新可能冲突导致查询不到数据;)
                List<Map<String, Object>> pageList = jdbcTemplate.queryForList("select columns... from " + sourceTable + " order by id limit " + currLimit + ", " + 1000);
                if (pageList.isEmpty()) {
                    hasData = false;
                } else {
                    page++;
                    //将多线程放到最小的颗粒上;
                    for (Map<String, Object> map : pageList) {
                        executor.execute(new EvaResultCalculateThreadGDVersion(redisTemplate,evaModel, itemTree, map, batchNo));
                    }
                    pageList.clear();
                }
            }

executor是初始化了10个线程... 每读取到1000行记录就生成一个计算任务对象放到线程池里跑...

你能看出来什么问题么? 坦白说我也看了很久...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

it夜猫who

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值