flink以增量+全量的方式更新广播状态
背景
flink在实现本地内存和db同步配置表信息时,想要做到类似于增量(保证实时性) + 全量(保证和DB数据一致)的效果,那么我们如何通过flink的广播状态+外部定时器定时全量同步的方式来实现呢?
实现增量+全量的效果
package wikiedits.schedule;import java.util.List;
import java.util.Map;import org.apache.commons.lang3.StringUtils;
import org.apache.flink.api.common.state.BroadcastState;
import org.apache.flink.api.common.state.MapState;
import org.apache.flink.api.common.state.MapStateDescriptor;
import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
import org.apache.flink.api.java.typeutils.ListTypeInfo;
import org.apache.flink.streaming.api.functions.co.KeyedBroadcastProcessFunction;
import org.apache.flink.util.Collector;//处理函数
public class BroadcastStatePlusSchedulerFunction extends KeyedBroadcastProcessFunction<String, String, String, String> {// 键值分区状态private final MapStateDescriptor<String, List<String>> mapStateDesc =new MapStateDescriptor<>("items", BasicTypeInfo.STRING_TYPE_INFO, new ListTypeInfo<>(String.class));// 广播状态private final MapStateDescriptor<String, String> ruleStateDescriptor = new MapStateDescriptor<>("RulesBroadcastState", BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);@Overridepublic void processBroadcastElement(String value, Context ctx, Collector<String> out) throws Exception {// 1.增量消息更新广播状态BroadcastState<String, String> broadcastState = ctx.getBroadcastState(ruleStateDescriptor);broadcastState.put(value, value);// 2.全量更新,判断广播状态和DB配置表在本地缓存的配置项是否一致,比如如果广播状态记录少了,使用本地缓存中的记录来更新下广播状态for (Map.Entry<String, String> entry : StaticLoadUtil.getConfigCache().asMap().entrySet()) {String broadcastValue = broadcastState.get(entry.getKey());if(!StringUtils.equals(entry.getValue(), broadcastValue)){//如果不相等,那么以DB缓存中的为准}}// 3.自此,广播状态和DB配置表的状态几乎一致,不过由于他们的比较只发生于收到广播元素,所以我们可以在凌晨的时候故意从db中找出几条记录发送kafka消息到这个广播状态来进行触发比较,当然这里也可以当收到某个元素时覆盖掉flink的广播状态}@Overridepublic void processElement(String value, ReadOnlyContext ctx, Collector<String> out) throws Exception {// 键值分区状态final MapState<String, List<String>> state = getRuntimeContext().getMapState(mapStateDesc);// 广播状态for (Map.Entry<String, String> entry : ctx.getBroadcastState(ruleStateDescriptor).immutableEntries()) {}}}// 外部定时器实现
package wikiedits.schedule;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;/*** 静态类定时加载DB配置表到本地内存中*/
public class StaticLoadUtil {// 定时任务执行器private static transient ScheduledExecutorService scheduledExecutorService;public static final Cache<String, String> configCache =CacheBuilder.newBuilder().initialCapacity(50).maximumSize(500).build();// 通过定时执行器定时同步本地缓存和DB配置表static {scheduledExecutorService = Executors.newScheduledThreadPool(10);scheduledExecutorService.scheduleWithFixedDelay(() -> {// 2.1 定时任务更新本地内存配置项// List<ConfigEntity> configList = DBManager.SELECTSQL.getConfigs();// for(ConfigEntity entity : configList){configCache.put("key", "value");// }// 2.2 更新本地变量threshold的值// threshold = DBManager.SELECTSQL.getConfig("threshold");}, 0, 100, TimeUnit.SECONDS);}/*** 获取本地缓存*/public static Cache<String, String> getConfigCache() {return configCache;}}
总结:
1.在处理广播元素的时候,除了更新广播状态之外,还要对比下广播状态和DB配置表在flink的本地缓存的数据,如果不一致,需要打印告警日志或者采取更新等措施
2.由于全量广播状态和DB配置表在flink的本地缓存的数据对比是在接收到某个广播元素的时候才进行,所以我们可以多余多发送一些相同的广播元素来触发对比
3.通过这种方式,广播状态就可以实现增量(实时性) + 全量(准确性) 的结果
相关文章:
flink以增量+全量的方式更新广播状态
背景 flink在实现本地内存和db同步配置表信息时,想要做到类似于增量(保证实时性) 全量(保证和DB数据一致)的效果,那么我们如何通过flink的广播状态外部定时器定时全量同步的方式来实现呢? 实现增量全量的效果 package wikiedits.schedule…...
Java:org.apache.commons.io包的工具类:IOUtils、FileUtils、FilenameUtils
文档 https://commons.apache.org/proper/commons-io/https://central.sonatype.com/artifact/commons-io/commons-io/2.14.0/jar 工具类 IOUtils io工具类FileUtils 文件操作工具类FilenameUtils 文件名工具类 依赖 <dependency><groupId>commons-io</gro…...

【JavaEE】文件操作
文章目录 前言什么是文件树型结构组织和目录文件路径文件类型文件权限Java中的文件操作File 类的常见属性File 类常见构造方法File 类常用方法 前言 文件是我们日常生活中使用非常广泛的,我们使用任何一个程序都离不开文件操作,这个文件不仅仅指平时可以…...

高精度电流源的应用领域有哪些
高精度电流源是一种能够提供稳定、准确、可控的电流输出的仪器设备,广泛应用于多个领域。以下是一些高精度电流源的应用领域。 科学研究:在物理学、化学、材料科学等领域中,需要进行精确的电流实验和测试。高精度电流源可以提供稳定的电流输出…...

多线程 - 线程池
线程池 相关的背景知识 线程池存在的意义: 使用进程来实现并发编程,效率太低了,任务太重了,为了提高效率,此时就引入了线程,线程也叫做“轻量级进程”,创建线程比创建进程更高效;销毁线程比销毁进程更高效;调度线程比调度进程更高效…此时,使用多线程就可以在很多时候代替进程…...
vue3 setup中defineEmits与defineProps的使用案例
目录 一、defineEmits的使用 二、 defineProps的使用 总结 一、defineEmits的使用 使用说明 1、在子组件中调用defineEmits并定义要发射给父组件的方法 const emits defineEmits([foldChange]) 2、使用defineEmits会返回一个方法,使用一个变量emits(变量名随意…...

Vs - Qt - 下拉窗口示例
下列代码定义了一个窗口,窗口采用竖直布局:一个按钮及一个label。按下按钮时候,窗口扩张,显示label控件。再次按下按钮时,窗口收缩,隐藏label控件。 详细代码如下: #include <QApplication&g…...
深圳自贸区的形成与发展
深圳自贸区的形成与发展源于中国政府推出的自贸试验区政策。自贸试验区是指在特定区域内,允许实行特殊的行政管理措施和贸易政策,以促进贸易自由化、投资便利化和经济转型升级。 深圳自贸区成立于2015年4月以来,主要着眼于优化区域布局、提高…...

机器人中的数值优化(二十一)—— 伴随灵敏度分析、线性方程组求解器的分类和特点、优化软件
本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考,主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等,本系列文章篇数较多,不定期更新,上半部分介绍无约束优化,…...
BACnet /IP转MQTT网关
在工业自动化和楼宇自动化领域中,Modbus、MQTT和BACnet/IP是三种常用的通信协议。Modbus是一种串行通信协议,常用于连接工业电子设备;MQTT是一种基于发布/订阅模式的轻量级通信协议,适用于远程监测和控制系统;BACnet/I…...

Web API 基础 (Web Workers API)
Web Workers API 1、指南 1.1 使用Web Workers Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外,它们还可以使用XMLHttpRequest(尽管responseXML和channel属性总是为空)或fetch(没有此类限制)执…...
如何看待程序员不写注释?
程序员对代码注释可以说是又爱又恨又双标……你是怎么看待程序员不写注释这一事件的呢? 对于程序员来说,注释是一种非常重要的实践,可以帮助他们自己和其他人更好地理解和维护代码。以下是一些关于注释的观点: 维护代码的重要性&a…...

2.6 方法
思维导图: 2.6.1 什么是方法 ### 2.6.1 什么是方法 **定义**: - 方法就是一段可以重复调用的代码,使得程序的可读性、可维护性都得以提高。 **示例**: - 假设有一个游戏中需要反复发射炮弹。而发射炮弹的代码有100行。为了避免在程序中多次写下这100…...

【排序算法】插入排序
文章目录 一:基本概念1.1 介绍1.2 原理1.3 插入排序法思想 二:代码实现2.1 源码2.2 执行结果2.3 测试八万条数据 三:算法分析3.1 时间复杂度3.2 空间复杂度3.3 稳定性 一:基本概念 1.1 介绍 插入式排序属于内部排序法࿰…...

Gnuradio+AM解调
1. https://wiki.gnuradio.org/index.php/PLL_Carrier_Tracking 2. https://wiki.gnuradio.org/index.php?titleComplex_to_Mag#Example_Flowgraph...
解决java.io.IOException: Broken pipe的报错
问题说明: 订单服务,查询预售但是出现Broken pipe; 测试版是正常的,正式版报错 解决方案 1、延长客户端超时时间 // 查询预售单列表 export function listPreOrder(query) {return request({url: /order/presale/list,method:…...

微信小程序--》从模块小程序项目案例23.10.09
配置导航栏 导航栏是小程序的门户,用户进来第一眼看到的便是导航栏,其起着对当前小程序主题的概括。而我们 新建的小程序 时,第一步变开始配置导航栏。如下: 配置tabBar 因为配置tabBar需要借助字体图标,我这里平常喜…...

爱尔眼科角膜塑形镜验配超百万,全力做好“角塑镜把关人”
你知道吗?过去的2022年,我国儿童青少年总体近视率为53.6%,其中6岁儿童为14.5%,小学生为36%,初中生为71.6%,高中生为81%①。儿童青少年眼健康问题俨然成为全社会关心的热点与痛点,牵动着每一个人的神经。 好…...
机器学习DAYX:线性回归与逻辑回归
线性回归 多重线性回归 逻辑回归...

【网络安全】网络安全的最后一道防线——“密码”
网络安全的最后一道防线——“密码” 前言超星学习通泄露1.7亿条信息事件武汉市地震监测中心遭境外网络攻击事件 一、密码起源1、 古代密码2、近代密码3、现代密码4、量子密码 二、商密专栏推荐三、如何利用密码保护账号安全?1、账号安全的三大危险?&…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...

Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
HTML中各种标签的作用
一、HTML文件主要标签结构及说明 1. <!DOCTYPE html> 作用:声明文档类型,告知浏览器这是 HTML5 文档。 必须:是。 2. <html lang“zh”>. </html> 作用:包裹整个网页内容,lang"z…...
python读取SQLite表个并生成pdf文件
代码用于创建含50列的SQLite数据库并插入500行随机浮点数据,随后读取数据,通过ReportLab生成横向PDF表格,包含格式化(两位小数)及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...