首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

5.snail-job的Map任务

  • 24-12-16 16:07
  • 3320
  • 9353
juejin.cn

前言

上一节《4.snail-job分片任务》中已经对分片任务有了大致的了解。只不过上一节讲述的是静态分片任务,在本节中要介绍的Map任务是-动态分片任务。所谓的"静态"和"动态",其本质区别在于是开始就配置好了分片还是由代码逻辑来分片。直接配置的就是“静态”;而代码分配的就是“动态“。

不管是静态分片,还是动态分片,其核心原理是将一个大任务拆分成多个小任务并发执行。本节介绍的Map任务和下一节将要介绍的MapReduce任务都属于动态分片范畴。

本节目标

这里用一个比较简单的示例,来演示Map任务。我们有200个数字,切成4个片,每个片中有50个数。子任务就是要对分配给自己的50个数字进行相加计算。OK,就这么简单。但是依然能从实现的过程中了解如下知识点:

  • 客户端采用继承类方式实现上述计算功能
  • 客户端采用注解方式实现上述计算功能
  • 服务端如何配置Map动态分片任务
  • 服务端查看分片任务的执行情况
  • 服务端配置并行数提高性能

客户端代码

开发环境

  • JDK版本:openjdk-21.0.2
  • snail-job版本:1.2.0

Maven依赖

xml
代码解读
复制代码
<dependencies>        <dependency>            <groupId>org.springframework.bootgroupId>            <artifactId>spring-boot-starter-webartifactId>        dependency>                <dependency>            <groupId>com.aizudagroupId>            <artifactId>snail-job-client-starterartifactId>            <version>1.2.0version>        dependency>                <dependency>            <groupId>com.aizudagroupId>            <artifactId>snail-job-client-retry-coreartifactId>            <version>1.2.0version>        dependency>                <dependency>            <groupId>com.aizudagroupId>            <artifactId>snail-job-client-job-coreartifactId>            <version>1.2.0version>        dependency>    dependencies>

继承类方式

scala
代码解读
复制代码
@Component public class TestMapJob extends AbstractMapExecutor {    @Override    public ExecuteResult doJobMapExecute(MapArgs mapArgs, MapHandler mapHandler) {        return switch (mapArgs.getTaskName()) {            case SystemConstants.ROOT_MAP -> {                // 生成1~200数值并分片                int partitionSize = 50;                List<List<Integer>> partition = IntStream.rangeClosed(1, 200)                       .boxed()                       .collect(Collectors.groupingBy(i -> (i - 1) / partitionSize))                       .values()                       .stream()                       .toList();                SnailJobLog.REMOTE.info("端口:{}完成分配任务", SpringUtil.getProperty("server.port"));                yield mapHandler.doMap(partition, "doCalc");           }            case "doCalc" -> {                List<Integer> sourceList = (List<Integer>) mapArgs.getMapResult();                // 遍历sourceList的每一个元素,计算出一个累加值partitionTotal                int partitionTotal = sourceList.stream().mapToInt(i -> i).sum();                // 打印日志到服务器                ThreadUtil.sleep(3, TimeUnit.SECONDS);                SnailJobLog.REMOTE.info("端口:{},partitionTotal:{}", SpringUtil.getProperty("server.port"), partitionTotal);                yield ExecuteResult.success(partitionTotal);           }            default -> ExecuteResult.failure();       };   } }

解释说明:

  • 通过继承AbstractMapExecutor类来实现动态分片
  • 通过判断任务名,来处理到底是应该分片还是对分片后的处理。在snail-job框架中,定义分片任务名是ROOT_MAP。并且仅由一台机器执行。假设在集群中有4台机器,那么这个ROOT_MAP任务,会随机从集群中抽取一个存活的机器进行执行。
  • 非ROOT_MAP名的任务,就是分片后的处理。
  • 需要对分片后的结果进行处理用mapHandler.doMap(partition, "doCalc");不需要处理就return ExecuteResult`。

注解方式

scss
代码解读
复制代码
@Component @JobExecutor(name = "testMapJobAnnotation") public class TestMapJobAnnotation { ​    @MapExecutor    public ExecuteResult doJobMapExecute(MapArgs mapArgs, MapHandler mapHandler) {        // 生成1~200数值并分片        int partitionSize = 50;        List> partition = IntStream.rangeClosed(1, 200)               .boxed()               .collect(Collectors.groupingBy(i -> (i - 1) / partitionSize))               .values()               .stream()               .toList();        SnailJobLog.REMOTE.info("端口:{}完成分配任务", SpringUtil.getProperty("server.port"));        return mapHandler.doMap(partition, "doCalc");   } ​    @MapExecutor(taskName = "doCalc")    public ExecuteResult doCalc(MapArgs mapArgs) {        List sourceList = (List) mapArgs.getMapResult();        // 遍历sourceList的每一个元素,计算出一个累加值partitionTotal        int partitionTotal = sourceList.stream().mapToInt(i -> i).sum();        // 打印日志到服务器        ThreadUtil.sleep(3, TimeUnit.SECONDS);        SnailJobLog.REMOTE.info("端口:{},partitionTotal:{}", SpringUtil.getProperty("server.port"), partitionTotal);        return ExecuteResult.success(partitionTotal);   } }

解释说明:

  • 通过@MapExecutor标识要执行的任务名称。这个注解默认的任务名称就是ROOT_MAP

    less
    代码解读
    复制代码
    @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface MapExecutor { ​    /**     * 任务名称     *     * @return     */    String taskName() default SystemConstants.ROOT_MAP; ​ }
  • 其实用法和继承类的方式是一样的。都通过任务名称来执行具体逻辑。前一个任务处理的结果,后个任务通过MapArgs参数获得,继续处理自己的逻辑。甚至还可以再把自己处理的结果,交给下一个任务名来处理。

服务端配置

继承类方式

配置项配置内容
任务名称测试动态分片-Map任务
状态禁用
任务类型Map
自定义执行器com.mayuanfei.test.TestMapJob
并行数1

说明:

  • 状态:状态设置为禁用,是想通过手动执行来触发
  • 任务类型:要选本节介绍的任务类型Map
  • 自定义执行器:继承类的方式要写全路径【复习】
  • 并行数:指客户端每台机器的线程数【复习】

注解方式

配置项配置内容
任务名称测试动态分片-Map任务-注解
状态禁用
任务类型Map
自定义执行器testMapJobAnnotation
并行数1

说明:

  • 自定义执行器 : 与注解@JobExecutor(name = "testMapJobAnnotation")名称一致【复习】

进行测试

测试前提

这里测试采用2台客户端。

web端口snail-job的客户端端口
91001900
92002900

可以参考《3.snail-job广播任务》的本机两个客户端启动章节的介绍。idea中配置如下:

ini
代码解读
复制代码
-Dserver.port=9100 -Dsnail-job.port=1900 -Dserver.port=9200 -Dsnail-job.port=2900

测试MAP任务

  • 9100Web端口

    image-20241210085944700

  • 9200Web端口

    image-20241210090118116

服务端管理页面

  • 查看Map的执行批次信息

    image-20241210090810658

  • 展开ROOT_MAP

    image-20241210091022517

  • 还可以查看结果

    点击上截图页面中结果列中的查看结果按钮

    image-20241210091330471

  • 再看看并行数修改为2后执行效率的提升

    image-20241210092008559

总结

  • 静态分片就是通过配置参数定义每个分片的范围;动态分配就是程序逻辑决定如何分片。
  • 通过程序代码的使用体验来看,注解方式似乎更直观些。
  • ROOT_MAP任务时框架定义的用于进行分片的根任务。
  • ROOT_MAP任务,会随机抽取集群中一台存活机器进行执行。
  • Map任务的核心是通过任务名称来进行的。分片动作的执行由ROOT_MAP指定,分片后的任务由你指定。
注:本文转载自juejin.cn的老马9527的文章"https://juejin.cn/post/7446362500478894106"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top