定时任务上云改造方案

news2024/11/18 17:32:23

优质博文:IT-BLOG-CN

一、Job单元化

什么Job需要单元化:所有会往单元化DB更新/删除/插入数据的Job都需要进行单元化改造。

什么是单元化DB
【1】指配置为DRC双向复制的DB
【2】单元化的DB部署在多个Zone,每个Zone内的实例都会被读写,以便达到:1)Zone故障时无需等待DB切换;2)请求的处理链路完全封闭在Zone内,低延迟;不同Zone负责不同的数据,例如按照OrderId%100进行Shard流量,ShardZone是多对一关系,以保证多个Zone间数据的双向复制不会产生冲突。

上云改造方案

【1】Job部署在所有Zone,调用所有Zone中的实例,每个ZoneJob实例只处理属于本Zone的数据,不处理其他Zone的数据。
【2】当流量切分规则发生变化时,终止当前调度,重新获取当前Job所在Zone应该处理哪些Shard并用这些Shard的进度最小值作为新的进度开始调度。同时需要保证Job逻辑的幂等性,防止跳跃性数据修改规则后重复执行。

为什么当规则发生变化时,取最小值和保证Job数据的幂等性:
举例:SH处理Shard S1S2SIN处理S0,当需要把S1SH切换至SIN时,此时SH的进度是3,SIN的进度是7。在SIN响应流量切换规则变化时,发现自己此时可以处理Shard S0S1的数据,如果按照之前的进度7来进行,就会漏掉SH未处理的5。同时,JOB逻辑需要幂等。

Job为什么要ShardingZone执行部署数据:
因为DB进行了单元化改造,读写操作都在ZoneMaster上进行,上云前的框架都是依赖一个全局唯一的DB Master进行一些互斥和可见性的操作,所以DB单元化后JOB执行的数据也需要分Zone执行。

改造后的Job

确定数据是否归属当前Zone处理: 将处理的数据orderId传给单元化组件UCS客户端API判断。

流量切分规则变化:Zone故障或者Zone之间流量比例调整时,Shard->Zone的映射关系会发生变化,每个Zone内的Job实例处理的数据也会发生变化。
【1】QSchedule JobQSchedule会通知每个ZoneJob实例终止当前调度并发起一次新的调度,Job实例通过QSchedule传递过来的上下文获取当前Job实例应该处理哪些Shard并重新开始业务处理逻辑。
【2】非QSchedule JobJob实例需要自行监听UCS客户端的策略变化,收到通知后终止当前业务处理逻辑,然后通过UCS客户端重新获取当前Job实例应该处理哪些Shard并重新开始业务处理逻辑。

代码逻辑改动

每次调度执行一次批量计算的Job

改造前

public void startQSchedule(QScheduleContext ctx) {
    // 从 Offset 存储中获取上次扫描过的 Offset
    Offset startOffset = offsetDao.queryStartOffset();

    // 根据 Offset 获取本地调度需要处理的数据
    List<SourceItem> sourceItems = sourceDao.selectBatch(startOffset, maxItemCount);

    // 业务逻辑处理
    process(sourceItems);

    // 计算并保存最新 Offset
    offsetDao.save(calcucateLatestOffset(startOffset, sourceItems));
}

改造后

public void startQSchedule(QScheduleContext ctx) {
    // #改造点#  通过 ctx 中本次调度负责的 Shards, 计算本次调度的起始 Offset (负责的Shards中最小的Offset)
    Offset startOffset = offsetDao.queryStartOffset();

    // 根据 Offset 获取本地调度需要处理的数据
    List<SourceItem> sourceItems = sourceDao.selectBatch(startOffset, maxItemCount);

    // #改造点# 使用 RouteContextBuilders 作为 UCS 路由 过滤本次调度处理的数据
    List<SourceItem> filteredItems = UCSHelper.filterCurrentZoneItems(ctx, sourceItems, RouteContextBuilders.Builder()...build());

    // 业务逻辑处理
    process(filteredItems);

    // #改造点# 计算并保本次调度完成后的最新 Offset,并映射到本次调度时单元化策略涉及到的 Shard
    UCSHelper.saveOffset(ctx, calcucateLatestOffset(startOffset, sourceItems));
}

Long-Running Job:指Job启动函数里存在无限循环,触发调度后,除非循环条件不满足,否则会一直持续运行,每次循环需要做的事情由业务逻辑自行控制,典型的Long-Running Job

改造前

public void startJob(QScheduleContext ctx) {

    // 从 Offset 存储中获取上次扫描过的 Offset
    Offset startOffset = offsetDao.queryStartOffset();

    // 这里是无限循环的条件,使用QSchedule提供的API来判断是否本次调度已被终止
    while (!ctx.isStopped()) {

        // 根据 Offset 获取本地调度需要处理的数据
        List<SourceItem> sourceItems = sourceDao.selectBatch(startOffset, maxItemCount);

        // 业务逻辑处理
        process(sourceItems, latestScanedOffset);

        // 等待一段时间
        TimeUnit.SECONDS.sleep(1);
    }
}

改造后

public void startJob(QScheduleContext ctx) {
    // #改造点# 通过ctx中本次调度应该负责的Shard,计算本次调度的起始 Offset,一般是用多个 Shard 的最小 Offset
    Offset startOffset = UCSHelper.calculateMinimumOffsetOfShards(ctx);

    // 这里是无限循环的条件,使用QSchedule提供的API来判断是否本次调度已被终止
    // 当单元化策略发生变化时,调度将会停止,等待 QSchedule Server 再次启动调度,此时会更新 ctx 中的 Shards 信息
    while (!ctx.isStopped()) {

        // 根据 Offset 获取本地调度需要处理的数据
        List<SourceItem> sourceItems = sourceDao.selectBatch(startOffset, maxItemCount);

        // #改造点# 使用 RouteContextBuilders 作为 UCS 路由 过滤本次调度处理的数据
        List<SourceItem> filteredItems = UCSHelper.filterCurrentZoneItems(ctx, sourceItems, RouteContextBuilders.Builder()...build());

        // 业务逻辑处理 
        process(filteredItems);

        // #改造点# 计算并更新本次调度完成后的最新 Offset
        startOffset = calcucateLatestOffset(startOffset, filteredItems);

        // #改造点#
        UCSHelper.saveOffset(ctx, startOffset);

        // 等待一段时间
        TimeUnit.SECONDS.sleep(1);
    }
}

正确性保证

【1】QSchedule调度上下文会封装本次调度涉及到的Shard信息。多次调度过程看到的Shard信息会随单元化策略变化而变化。一次完整的调度过程内部使用的Shard信息是一致的,不会因为单元化策略变化而变化。
【2】调度过程中,下面三个步骤使用到的Shard信息是完全相同的,保证Shard信息的原子性:一下三个步骤如果检测到单元化策略发生变化,会及时终止本次调度,等待QSchedule服务端再次调度。
  ● 根据Shard获取对应的StartOffset
  ● 根据Shard过滤扫描到的数据;
  ● 保存处理的最新Offset和上述Shard的对应变化;

二、PaaS基础组件多IDC接入

根据RegionCode确定数据所在Region,使得常用的数据查询或业务处理操作可以在单个节点上执行,以达到数据单元化处理和数据合规策略动态调整的效果,从而避免跨节点带来额外性能消耗和数据跨境合规问题。

分布式调度中心: 因为业务中大部分JOB都是通过扫表来对数据进行批量处理,所以多IDC场景下则基于存储的RegionCode将任务分散到多个IDC,数据经过单元化过滤后,进行分片处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2169350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【含文档】基于Springboot+Vue的高校失物招领平台(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

物体实例分割,机器人拾取

物体实例分割是计算机视觉领域的一个关键任务&#xff0c;它旨在从图像中分割出每个独立物体&#xff0c;并且为每个物体实例提供一个独特的标识。这一任务不仅识别出图像中的物体&#xff0c;还能区分出多个同类物体的不同实例&#xff0c;例如在一张桌子上摆放的多个相同的杯…

『功能项目』宠物的攻击巨型化【80】

本章项目成果展示 我们打开上一篇79宠物的召唤跟随的项目&#xff0c; 本章要做的事情是实现在战斗中有几率触发宠物巨型化攻击将怪物击飞的效果 首先在主角预制体中增加隐藏的宠物巨型化 制作巨型化宠物的攻击效果 将该动画控制器放置在隐藏的巨型化宠物的动画控制器上 首先查…

新160个crackme - 065-Eternal Bliss

运行分析 选择验证方式&#xff0c;破解字符串标题提示为vb程序 PE分析 VB程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 使用VB Decompiler进行分析&#xff0c;发现Command1_Click_403604为check按钮事件&#xff0c;需要使Me 1 CBool(expression) 将表达…

传输层协议 --- UDP

序言 在之前的文章 Socket 编程 中&#xff0c;我们只是简单的知道了怎么利用 UDP协议 或者是 TCP协议 来发送我们的数据&#xff0c;并且我们还知道 UDP 是不可靠的&#xff0c;TCP 是可靠的。但这是为什么呢&#xff1f;底层的构造和策略决定他们的属性&#xff01;这篇文章中…

从环境部署到开发实战:消息队列 RocketMQ

文章目录 一、消息队列简介1.1 什么是消息队列1.2 常见消息队列对比1.3 RockectMQ 核心概念1.4 RockectMQ 工作机制 &#xff08;★&#xff09; 二、RocketMQ 部署相关2.1 服务器单机部署2.2 管控台页面 三、RocketMQ 的基本使用3.1 入门案例3.2 消息发送方式3.2.1 同步消息3.…

微服务-流量染色

1. 功能目的 通过设置请求头的方式将http请求优先打到指定的服务上&#xff0c;为微服务开发调试工作提供便利 请求报文难模拟&#xff1a;可以直接在测试环境页面上操作&#xff0c;流量直接打到本地IDEA进行debug请求链路较长&#xff1a;本地开发无需启动所有服务&#xf…

前端常见算法题集

很久没练算法了&#xff0c;打算接下来一段时间每天坚持写题和写题解 这是一篇前端常用算法题集&#xff0c;题目从从简到难&#xff0c;编程语言主要为JavaScript&#xff0c;顺便练习和熟记js的各种方法... 目录 字符串类 1.字符串相加 字符串类 下图为js中常用的字符串方…

神经网络介绍及其在Python中的应用(一)

作者简介&#xff1a;热爱数据分析&#xff0c;学习Python、Stata、SPSS等统计语言的小高同学~ 个人主页&#xff1a;小高要坚强的博客 当前专栏&#xff1a;Python之机器学习 本文内容&#xff1a;神经网络介绍及其在Python中的线性回归应用 作者“三要”格言&#xff1a;要坚…

使用python爬取豆瓣网站?如何简单的爬取豆瓣网站?

1.对python爬虫的看法 首先说说我对python的看法&#xff0c;我的专业是大数据&#xff0c;我从事的工作是java开发&#xff0c;但是在工作之余&#xff0c;我对python又很感兴趣&#xff0c;因为我觉得python是一门很好的语言&#xff0c;第一&#xff1a;它可以用来爬取数据…

fmql之字符驱动设备(2)

例行的点灯来喽。 之前是寄存器读写&#xff0c;现在要学习通过设备树点灯。 dtsled.c 寄存器写在reg 把用到的寄存器写在设备树的led节点的reg属性。 其实还是对寄存器的读写。 &#xff08;不推荐&#xff09; 头文件 #include <linux/kernel.h> #include <li…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-26

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-26 1. LLMs Still Can’t Plan; Can LRMs? A Preliminary Evaluation of OpenAI’s o1 on PlanBench Authors: Karthik Valmeekam, Kaya Stechly, Subbarao Kambhampati LLMs仍然无法规划&#xff1b;LRMs可以…

【通俗易懂】FFT求解全过程,各参数详细解释

在进行FFT全过程讲解之前&#xff0c;小编先给大家解释一下&#xff0c;在FFT中出现的一些参数名词解释。 &#xff08;1&#xff09;采样频率 Fs Fs 1 / 采样间隔 根据奈奎斯特定理&#xff1a;Fs ≥ 最高频率分量的两倍&#xff0c;这样才能避免混叠 &#xff08;2&…

解决macOS安装redis以后不支持远程链接的问题

参考文档:https://blog.csdn.net/qq_37703224/article/details/142542179?spm1001.2014.3001.5501 安装的时候有个提示, 使用指定配置启动: /opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf那么我们可以尝试修改这个配置文件: code /opt/homebrew/…

傅里叶级数在机器人中的应用(动力学参数辨识)

B站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清华大学李永乐老师教你如何理解傅里叶变换&#xff0c;辨清美颜和变声原理&#xff0c;&#xff01;&#xff01;_哔哩哔哩_bilibiliB站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清…

AI 智能体 | 手捏素材选题库 Coze Bot,帮你实现无限输出

做自媒体的同学经常遇到的一个痛点就是无限输出&#xff0c;那怎么才能有源源不断的选题呢&#xff1f;那就是搭建一个选题素材库。 下面就为大家介绍一下基于 Coze Bot 快速搭建素材选题库&#xff0c;希望能让大家才思泉涌。 一、流程拆解 日常素材库积累的过程可以描述为…

eslint-plugin-react的使用中,所出现的react版本警告

记一次使用eslint-plugin-react的警告 Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration . 背景 我们在工程化项目中&#xff0c;常常会通过eslint来约束我们代码的一些统一格…

汽车总线之----J1939总线

instruction SAE J1939 是由美国汽车工程协会制定的一种总线通信协议标准&#xff0c;广泛应用于商用车&#xff0c;船舶&#xff0c;农林机械领域中&#xff0c;J1939协议是基于CAN的高层协议&#xff0c;我们来看一下两者之间的关系。在J1939 中&#xff0c;物理层和数据链路…

第13讲 实践:设计SLAM系统

设计一个视觉里程计&#xff0c;理解SLAM软件框架如何搭建&#xff0c;理解视觉里程计设计容易出现的问题以及解决方法。 目录 1、工程目标 2、工程框架 3、实现 附录 1、工程目标 实现一个精简版的双目视觉里程计。由一个光流追踪的前端和一个局部BA的后端组成。 2、工程…

asp.net mvc core 路由约束,数据标记DataTokens

》从0自己搭建MVC 》用 asp.net Core web 应用 空web 应用程序 需要配置 mvc服务 、mvc路由 新建 Controller 、Models、Views 》》》core 6 之前版本 vs2022 asp.net Core Web 应用&#xff08;模型-视图-控制器&#xff09; 不需要配置 就是mvc框架 asp.net Core web 应…