美文网首页
多机器并行处理的业务方案

多机器并行处理的业务方案

作者: 西5d | 来源:发表于2019-08-22 20:04 被阅读0次

    最近遇到的问题,可以总结是一个递进深入的过程,觉得有价值记录整理下。简单介绍下需求背景:有个定时执行的任务,每天早上执行,从数据库获取所有的分组id,给每个id发送消息。在开始设计的时候,就预料到如果是单机执行,随着上线后分组数逐渐增多,任务执行的延迟会逐渐增大。但开始限于某些原因,还是采用了单机的方案。定时器在固定时间触发任务执行,随机一个机器执行对应任务。采用的是消息通知的方式,只需要发送一条消息就可以了。下面说下后来遇到的问题和解决方案。

    功能开始上线后,分组开始为20000多个,然后以每天5000个左右的数目增长,单机多线程执行的情况下(线程10个),任务耗时逐渐增长。从开始8分钟,长到了14分钟。可以预见在往后会更加变长。当时考虑了两种方案,分别是。

    1、全量消息

    在任务触发端,即查询到所有分组id后,全部作为消息发送给任务执行端。同时执行端可以多机器在各自线程池中执行。注意这里分组都是去重的。这种方式优点是编码量非常小,只需要实现全量查询,发送和接收,处理三个功能就可以。但问题消息量级比较大,比如最后会是5-6万的消息量,而且还会继续增长。虽然不多,但限于这边用消息量作为成本计算,所以没有采用,有点迫于形势。&-&

    2、id分组

    所谓的id分组,就是在任务触发端查询到全量的分组id之后,先排序,然后按照固定的范围切割,得到一些id的分组,再把分组按照消息发送出去,这样就减少了消息量,也实现了多机器并行执行。比如id总量是50000,排序后,按照每100个一组,1-100,101-200...类似,消息量就从10^5 降2个量级,到500。在采用这个方案后,目前接近6万的量,每天不到2分钟就可以执行完成,效果还是比较明显。
    下面是分组的实现代码。

     /**
         * 分组发送id范围,闭区间
         */
        @NoArgsConstructor
        @AllArgsConstructor
        @Data
        private class IdRange {
            /**
             * 表示数据范围
             */
            private long start;
            private long end;
        }
    
        private List<IdRange> buildRangeList(List<Long> ids) {
            int rangeSize = getRangeSizeConfig();
            if (rangeSize <= 0) {
                rangeSize = DEFAULT_RANGE_SIZE;
            }
            ids = ids.stream().distinct().sorted().collect(Collectors.toList());
            List<IdRange> idRanges = Lists.newArrayList();
    
            int size = ids.size();
            int start = 0;
            int end = 0;
            while (end < size - 1) {
                end += rangeSize;
                if (end >= size) {
                    end = size - 1;
                }
                IdRange range = new IdRange(ids.get(start), ids.get(end));
                idRanges.add(range);
                start = end + 1;
            }
    
            return idRanges;
        }
    

    以上就是两种简单方案的介绍。补充说点,这里任务要求每天仅执行一次,因此开始全量方案用的日期作为标记,表示是否执行过。 在改为切割的方案后,就改为日期+范围左右区间作为key去重了。

    总结

    首先一点是,简洁高效的技术方案本该是推荐的,但有时候就是有各种情形的限制,没法采用技术上较为合理的方案。随着以后功能越来越多,估计也会经常碰到,就得考虑如何取舍了。其次,很多时候方案就是逐渐推进改造的,不同的应用场景下,就得考虑更加适当的方案来解决问题。有的人可能说,可以刚开始就采用完善的方案,但这样往往提高了整体的复杂度,不利于扩展,改造。而且谁都难以预料后期需求会发生怎样的变动,因此归纳说应该“简而高效,合理完善”

    相关文章

      网友评论

          本文标题:多机器并行处理的业务方案

          本文链接:https://www.haomeiwen.com/subject/psmosctx.html