当前位置: 首页 > news >正文

Debezium Engine监听binlog实现缓存更新与业务解耦

飞书文档

解决缓存与数据源数据不一致的方案有很多, 各有优缺点;
1.0、旁路缓存策略, 直接同步更新
读取流程:

  1. 查询缓存。如果缓存命中,则直接返回结果。
  2. 如果缓存未命中,则查询数据库。
  3. 将数据库查询到的数据写入缓存,并设置一个过期时间。
    写入流程:
  4. 更新数据库中的数据。
  5. 删除缓存中的数据缓存。
    缺点:
  • 缓存穿透 (高并发情况下如果缓存未命中,需要查询数据库并回写缓存,这可能在高并发下场景增加数据库的负载)

  • 高并发环境下可能导致数据不一致,因为在删除Redis时,如果有其他请求线程已经读取了MySQL旧数据,然后缓存进去, 就会出现脏数据问题。
    伪代码:
    vodi updateData(id, newData) {
    // 更新MySQL
    mysql.update(“UPDATE table SET data = ? WHERE id = ?”, newData, id);

    // 更新Redis
    redis.del(“data:” + id);
    }
    2.0、延迟双删策略
    读取流程:

  1. 查询缓存。如果缓存命中,则直接返回结果。
  2. 如果缓存未命中,则查询数据库。
  3. 将数据库查询到的数据写入缓存,并设置一个过期时间。
    写入流程:
  4. 删除缓存中的数据缓存。
  5. 更新数据库中的数据。
  6. 延迟1~3S再删除缓存中的数据缓存。
    缺点:
  • 短时间的数据不一致, 但最终实现的效果是最终数据一致性, 不适合对实时性要求极高的场景。

  • 延迟删除不保证成功 (如需保证测需要重试策略)
    伪代码:
    void updateData(id, newData) {
    // 删除Redis缓存
    redis.delete(“data:” + id);

    // 更新MySQL
    mysql.update(“UPDATE table SET data = ? WHERE id = ?”, newData, id);

    // 延时任务,延时后再次删除Redis缓存
    scheduleTask(() => {
    redis.delete(“data:” + id);
    }, delayTime); // delayTime为延迟时间,例如1000毫秒
    }
    3.0、定时+增量更新策略
    读取流程:

  1. 查询缓存。如果缓存命中,则直接返回结果。
  2. 如果缓存未命中,则查询数据库。
  3. 将数据库查询到的数据写入缓存,并设置一个过期时间。
    缓存写入流程:
  4. 固定时间去拉取增量数据, 比如比标记时间大的数据。
  5. 更新进缓存里
    优点:
  • 减少负载:相比实时同步,定时+增量更新可以减少对数据库和缓存的压力,因为它不会在每次数据变更时立即进行同步。

  • 灵活性高:可以根据业务需求调整定时任务的频率和增量更新的策略。
    缺点:

  • 根据配置定时时间长短造成时间的数据不一致, 但最终实现的效果是最终数据一致性, 不适合对实时性要求极高的场景。

  • 需要针对不同的业务实现一套不同的定时+增量更新策略
    伪代码:
    void syncCache() {
    // 获取上次同步的时间戳
    Timestamp lastSyncTime = getLastSyncTime();

    // 查询自上次同步以来有变更的数据
    List updatedData = mysql.query(
    “SELECT * FROM table WHERE update_time > ?”, lastSyncTime);

    // 更新缓存
    for (Data data : updatedData) {
    redis.set(“data:” + data.id, data);
    }

    // 更新最后同步时间
    updateLastSyncTime(currentTime());
    }
    4.0、锁机制更新策略
    读取流程:

  1. 查询缓存。如果缓存命中,则直接返回结果。
  2. 如果缓存未命中, 向Redis上读锁。
  3. 查询数据库。
  4. 将数据库查询到的数据写入缓存,并设置一个过期时间 & 释放读锁。
    写入流程:
  5. 向Redis上写锁。
  6. 更新数据库中的数据。
  7. 删除缓存中的数据缓存。
  8. 释放写锁
    优点:
  • 数据强一致性。
    缺点:

  • 性能比其他方式差。
    伪代码:
    void save() {
    // 获取写锁
    RedissonClient client = RedissonClientUtil.getClient(“”);
    RReadWriteLock readWriteLock = client.getReadWriteLock(“myLock”);
    RLock writeLock = readWriteLock.writeLock();
    // 加锁
    writeLock.lock();
    // 查询自上次同步以来有变更的数据
    List updatedData = mysql.query(
    “SELECT * FROM table WHERE update_time > ?”, lastSyncTime);
    // 删除缓存
    redis.del(“data:” + data.id);

    // 最后释放锁
    writeLock.unlock();
    }
    5.0、异步更新策略
    Binlog 订阅方式, 这种策略已经和业务解耦开;
    读取流程:

  1. 查询缓存。如果缓存命中,则直接返回结果。
  2. 缓存未命中查询数据库。
  3. 将数据库查询到的数据写入缓存,并设置一个过期时间
    数据源写入流程:
  4. 更新数据库中的数据。
    缓存处理中间件:
    接收Binlog 订阅发送过来的数据;
    进行缓存的处理 (可以更新也可以删除)
    优点:
  • 数据最终一致性。
  • 和业务解耦, 业务代码不用再考虑数据源数据更新后缓存怎么更新。
    缺点:
  • 有延迟情况;
  • 实现成本与维护成本大
    大概流程如下图
    [图片]
    但是基础组件并不满足于公司复杂多变的业务场景, 需要基于基础组件实现定制化的异步更新策略;
    基于异步更新策略的架构设计方案
    CDC (Change data capture)
    [图片]
    不想引入mq?试试debezium小型项目当中,没有引入消息中间件,也不想引入,但需要解耦异步,那怎么办呢?CDC组件是 - 掘金
    从选项来看, Flink CDC 太重量级; sqoop,kettle,datax之类的工具,属于前大数据时代的产物,地位类似于web领域的structs2。而且,它们基于查询而非binlog日志,其实不属于CDC。首先排除, canal只能对MYSQL进行CDC监控。有很大的局限性。
    综上所述 debezium 较为合适;
    Debezium 介绍
    Debezium 构建在Apache Kafka的基础之上,并提供了一套与Kafka Connect兼容的连接器。每个连接器都与特定的数据库管理系统(DBMS)协同工作。连接器通过检测发生的变化来记录 DBMS 中数据变化的历史,并将每个变化事件的记录流式传输到 Kafka 主题。然后,消费应用程序可以从 Kafka 主题中读取由此产生的事件记录;
    通过利用 Kafka 可靠的流平台,Debezium 使应用程序能够正确、完整地消费数据库中发生的变化。即使应用程序意外停止或失去连接,也不会错过中断期间发生的事件。应用程序重新启动后,会从中断的位置继续读取主题。
    使用 Debezium 需要三个独立的服务:ZooKeeper、Kafka 和 Debezium 连接器服务,
    但是同时Debezium也支持并非每个应用程序都需要这种级别的容错性和可靠性,它们可能不希望依赖外部的 Kafka 代理集群和 Kafka 连接服务。相反,有些应用程序更愿意将 Debezium 连接器直接嵌入应用程序空间。它们仍然需要相同的数据变更事件,但更希望连接器能直接将其发送到应用程序,而不是在 Kafka 内持久化
    对应文档说明: Debezium Engine
    下面采用轻量级方式集成
    Debezium 连接器直接嵌入应用程序空间
    1.0、依赖关系
    Springboot 2.7.5, jdk8版本
    [图片]
    [图片]
    从上图看 debezium从1.6版本开始就需要 >= jdk11了; 那么我们只能使用1.5版本

[图片]
使用 1.5.4.Final jdk8支持的最新版本
<version.debezium>1.5.4.Final</version.debezium>

io.debezium debezium-api ${version.debezium} io.debezium debezium-embedded ${version.debezium} io.debezium debezium-connector-mysql ${version.debezium} 2.0 简单demo 暂时无法在飞书文档外展示此内容 在MySQL5.6与MySQL5.7版本上运行是正常的 3.0、架构设计图 暂时无法在飞书文档外展示此内容 3.1、整个架构分为 四 部分 1. Debezium Engine连接器管理应用 2. Debezium Engine连接器应用 3. Debezium 消息重试应用 4. Debezium Engine连接器消费应用 3.2、Debezium Engine连接器管理应用 (web页面可以先不做) 主体功能: 对外web服务, 用于管理连接器, 将连接器数据可视化等; > 和Debezium Engine连接器应用交互 管理连接器: (新增并启动连接器、删除并停止连接器(也会删除连接器相关offset文件)) 可视化的数据: (连接器相关信息、连接器运行状态 连接器已处理事件数量、失败数量、待重试数量、等) 3.3、Debezium Engine连接器应用 主体功能分为: 1. 连接器的启动/运行/停止 (分为项目启动时候 / 接收管理应用请求的的时候) 2. 事件的数据解析/发送下游 3. 监控指标收集 4. 异常事件重试&记录&告警 CREATE DATABASE debezium_config_manage; 相关的表: debezium_connect CREATE TABLE `debezium_connect_base_info` ( `id` bigint(20) unsigned NOT NULL COMMENT '不用自增(使用顺序雪花)', `business_describe` varchar(255) NOT NULL DEFAULT '' COMMENT '连接器业务描述', `connect_db_type` varchar(30) NOT NULL DEFAULT '' COMMENT '连接DB类型(MySQL数据库:MySQL)', `connect_name` varchar(255) NOT NULL DEFAULT '' COMMENT '连接器名称', `connect_status` varchar(20) NOT NULL DEFAULT 'wait' COMMENT '连接器状态(run:运行中、wait:待运行、stop:停止)', `current_finish_num` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '当前完成数 (非实时)', `total_finish_num` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '总完成数 (非实时)', `wait_finish_retry_num` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '待完成重试数 (实时)', `total_finish_retry_num` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '总完成重试数 (实时)', `is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除状态(1:删除,0:未删除)', `last_operator_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '最后操作人ID', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `version` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '版本号', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', PRIMARY KEY (`id`), CONSTRAINT UNIQUE KEY `idx_connect_name_connect_db_type` (`connect_name`,`connect_db_type`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='连接器基础信息表'; debezium_connect_param CREATE TABLE `debezium_connect_param` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `connect_base_info_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '连接器基础表ID', `database_table_list` text COMMENT '监控的多个的数据库和表 (account.user)格式 , 逗号分隔', `database_history_file_filename` varchar(100) NOT NULL DEFAULT '' COMMENT 'dbhistory文件名称 (唯一值), 不包含路径(x.txt)', `offset_storage_file_filename` varchar(100) NOT NULL DEFAULT '' COMMENT 'offset文件名称 (唯一值), 不包含路径(x.dat)', `database_server_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '连接Debezium 服务的 id(唯一值)', `connect_param_json` text COMMENT '剩余连接器JSON参数', `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除状态(1:删除0:未删除)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', PRIMARY KEY (`id`), UNIQUE KEY `idx_database_history_file_filename` (`database_history_file_filename`), UNIQUE KEY `idx_database_server_id` (`database_server_id`), UNIQUE KEY `idx_offset_storage_file_filename` (`offset_storage_file_filename`), KEY `idx_connect_base_info_id` (`connect_base_info_id`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='连接器参数表'; debezium_message_invoke CREATE TABLE `debezium_message_invoke` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `connect_base_info_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '连接器基础表ID', `invoke_type` varchar(50) NOT NULL DEFAULT '' COMMENT '调用方式 (http、MQ)', `http_invoke_address` varchar(255) NOT NULL DEFAULT '' COMMENT 'http的调用地址', `mq_invoke_address` varchar(255) NOT NULL DEFAULT '' COMMENT 'mq的调用route、topic (JSON方式)', `invoke_extra_mark` varchar(255) NOT NULL DEFAULT '' COMMENT '调用额外带上的标识', `message_max_retry` int(20) unsigned NOT NULL DEFAULT 0 COMMENT '消息最大重试次数', `message_retry_interval` int(20) unsigned NOT NULL DEFAULT 0 COMMENT '消息重试间隔(单位分钟)', `is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除状态(1:删除0:未删除)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', CONSTRAINT PRIMARY KEY (`id`), KEY `idx_connect_base_info_id` (`connect_base_info_id`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='连接器消息调用方式'; debezium_connect_operation_record CREATE TABLE `debezium_connect_operation_record` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `connect_base_info_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '连接器基础表ID', `operator_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '操作人ID', `operator_type` varchar(50) NOT NULL DEFAULT '' COMMENT '操作人类型 (user:用户, system:系统)', `operation_type` varchar(50) NOT NULL DEFAULT '' COMMENT '操作类型 (add:添加连接器, update:修改连接器、del:删除连接器, updateCount:更新统计信息)', `operation_content` TINYTEXT COMMENT '操作JSON参数', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', CONSTRAINT PRIMARY KEY (`id`), KEY `idx_connect_base_info_id` (`connect_base_info_id`), KEY `idx_operator_id_operator_type` (`operator_id`,`operator_type`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='连接器操作记录表'; debezium_connect_message_retry CREATE TABLE `debezium_connect_message_retry` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `connect_base_info_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '连接器基础表ID', `operator_content` TINYTEXT COMMENT '需重试的JSON参数', `next_retry_time` datetime NOT NULL COMMENT '下一次重试时间', `message_current_retry` int(20) unsigned NOT NULL DEFAULT 0 COMMENT '消息当前重试次数', `message_status` varchar(255) NOT NULL DEFAULT 'wait' COMMENT '消息状态(wait:待执行, run:执行中, finish:执行完成)' `message_retry_status` varchar(255) NOT NULL DEFAULT '' COMMENT '消息重试状态(success:成功, fail:失败)' `is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除状态(1:删除0:未删除)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注' CONSTRAINT PRIMARY KEY (`id`), KEY `idx_connect_base_info_id` (`connect_base_info_id`), KEY `idx_next_retry_time` (`next_retry_time`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='连接器消息重试表'; 无人为介入流程是: 项目启动 > 从数据库拉取所有未删除的连接器 > 进行启动 > 并启动一个间隔一分钟统计一次数据的监控指标线程 监控binlog信息 > 解析成为可读的请求消息 > 根据连接器调用方式进行调用下游 当消息调用失败, 则进行简单重试 3次 > 继续失败后 > 构建重试对象插入到重试表 (让重试服务进行拉取重试) 项目停止 > 停止所有的连接器 从Debezium Engine连接器管理应用来的请求流程大概是: 接收请求 > 校验请求合法性 > 校验请求参数合法性 > 根据类型做启动/停止对应连接器; PS: 在上面的各个重点操作节点 (都会进行机器人告警/日志打印) 日志级别是可动态调整的; [图片] 3.4、Debezium 消息重试应用 该应用主体功能就是 做多次失败的消息的重试; 项目启动之后, 启动一个线程池 + 一个线程组, 不断间隔定时循环 > 拉取debezium_connect_message_retry 表中未删除的数据, 进行关联查询相关信息, 进行消息重试; [图片] 3.5、Debezium Engine连接器消费应用 主要功能是: 接收连接器上游的调用, 解析统一的调用参数; 然后做自己的业务, 比如说是 做Redis的缓存更新, 如果进行Redis的处理失败了则进行简单的重试; 比如接收下面图片的参数 [图片] [图片] [图片] [图片] 4.0、剩余待解决的问题 (会议上记录) 4.1、Debezium Engine连接器高可用 (无需考虑高可用) 如果要实现连接器高可用情况, 多节点部署, 就需要考虑解决消息只消费一次的情况与性能情况; 4.2、多个 Debezium Engine连接器 对数据库的性能影响 (无影响) Debezium does not impact source database performance [图片] Debezium 官方不推荐对同一个数据源使用多个连接器,建议通过调整连接器配置来满足需求; 但是存在如果声音一个engine的情况, 监听延迟会变长; 4.2、 (会议上补充) 做成2个应用 [图片] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~end~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4.3、(会议上补充) 消费应用增加 表 与 Redis keys的 映射关系 CREATE TABLE `auto_handle_redis_mapping` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `handle_table` varchar(255) NOT NULL DEFAULT '' COMMENT '处理的表名称', `handle_key` varchar(2555) NOT NULL DEFAULT '' COMMENT '处理的Redis_key集, 逗号分隔(例如:device_cache_id_{#deviceId})', `extra_groovy_script_file_path` TINYTEXT COMMENT '额外groovy脚本执行文件', `is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除状态(1:删除0:未删除)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注' CONSTRAINT PRIMARY KEY (`id`), KEY `idx_message_handle_table` (`handle_table`,`handle_key`), KEY `idx_create_time` (`create_time`), KEY `idx_update_time` (`update_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='自动处理Redis删除逻辑表与keys映射'; 4.4、(会议上补充) 消费服务增加延迟双删除 4.5、 (会议上补充) 业务的缓存处理 5.0、Redis容量估算 集成demo遇到的错误: 启动失败 [图片] 检索后和尝试发现是MySQL连接版本不对, 默认的版本是 8.0.31 降级为8.0.27还是不行, 最终降级为8.0.21正常! io.debezium debezium-connector-mysql ${version.debezium} mysql mysql-connector-java mysql mysql-connector-java 8.0.21 Interrupted while emitting initial DROP TABLE events [图片] 原因被主线程关闭了, 解决方法开启新线程 debezium # offset 文件不生成 参考的Spring boot 整合demo https://juejin.cn/post/7348003004122939429 原因有个坑, GitHub源码没有调用该方法, 少了下图标记调用的方法, offset文件就不会生成! [图片]

应用到生产的源码:
(加密)
暂时无法在飞书文档外展示此内容
暂时无法在飞书文档外展示此内容
采用kafka方式 (暂不研究):
ZooKeeper服务, 目前我们已经在使用, 如果要独立出来, 可以单独配置一台 (生产 : 1核心1GB内存配置)
Kafka服务 (生产集群, 配置4核心8G内存配置, 硬盘SSD)
Debezium连接器服务 (生产集群, 配置4核心8G内存配置, 硬盘SSD)
测试环境 (可以将 三个服务部署在同一台机子, 只需要2核心4G)
运行启动步骤:
MySQL启用binlog
1、启动ZK
2、启动kafka
3、启动Debezium连接器

1

相关文章:

Debezium Engine监听binlog实现缓存更新与业务解耦

飞书文档 解决缓存与数据源数据不一致的方案有很多, 各有优缺点; 1.0、旁路缓存策略, 直接同步更新 读取流程&#xff1a; 查询缓存。如果缓存命中&#xff0c;则直接返回结果。如果缓存未命中&#xff0c;则查询数据库。将数据库查询到的数据写入缓存&#xff0c;并设置一个…...

mysql_题库详解

1、如何创建和删除数据库&#xff1f; 1&#xff09;创建数据库 CREATE DATABASE 数据库名; 2&#xff09;删除数据库 drop database 数据库名; 2、MyISAM与InnoDB的区别&#xff1f; 1&#xff09;事务&#xff1a;MyISAM 不支持事务 InnoDB 支持 2&#xff09;行锁/表锁&a…...

docker查询是否运行

您可以通过运行以下命令来检查Docker是否正在运行&#xff1a; docker info 或者&#xff1a; docker ps 如果Docker正在运行&#xff0c;docker info将显示Docker的详细信息&#xff0c;而docker ps将列出当前运行的容器。如果Docker没有运行&#xff0c;这些命令将会返回错误…...

【AI日记】24.11.29 kaggle 比赛 Titanic-2 | 鼓励自己

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 内容&#xff1a;学习 kaggle 入门比赛 Titanic - Machine Learning from Disaster&#xff0c;学习机器学习课程备注&#xff1a;入门比赛有很多 notebook 适合我这种新手学习&#xff0c;尤其是那…...

SVG无功补偿装置MATLAB仿真模型

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 SVG&#xff08;又称ASVG 或STATCOM&#xff09;是Static Var Generator 的缩写&#xff0c;叫做静止无功发生器。也是做无功补偿的&#xff0c;比SVC 更加先进。其基本原理是将自换相桥式电路通过电抗器或…...

2039:【例5.6】冒泡排序

【题目描述】 编程输入n(1≤n≤20)个小于1000非负整数&#xff0c;然后自动按从大到小的顺序输出。&#xff08;冒泡排序&#xff09; 【输入】 第一行&#xff0c;数的个数n; 第二行&#xff0c;n个非负整数。 【输出】 由大到小的n个非负整数&#xff0c;每个数占一行。 【输…...

yum源问题的解决方案

linux课堂作业 问题描述 yum 直接安装tree的问题截图 这个错误表明你的系统没有正确注册到 Red Hat Subscription Management&#xff08;这个问题不用管&#xff09;&#xff0c;也没有配置有效的 YUM 软件仓库&#xff0c;因此无法安装或更新软件包。 解决方案&#xff08…...

一文解析Kettle开源ETL工具!

ETL&#xff08;Extract, Transform, Load&#xff09;工具是用于数据抽取、转换和加载的软件工具&#xff0c;用于支持数据仓库和数据集成过程。Kettle作为传统的ETL工具备受用户推崇。本文就来详细说下Kettle。 一、Kettle是什么&#xff1f; Kettle 是一款开源的 ETL&#x…...

微积分复习笔记 Calculus Volume 2 - 3.1

The first 2 chapters of volume 2 are the same as those in volume 1. Started with Chapter 3. 3.1 Integration by Parts - Calculus Volume 2 | OpenStax...

linux环境搭建

1、**连接外网** ssh在192.168.4.x上运行sudo ip link set ens160 down ssh切换到192.168.3.x(外网ip)&#xff0c;运行sudo ip route add default via 192.168.2.1 dev ens192 onlink //连接外网 使用完外网后 ssh在192.168.3.x上运行sudo ip link set ens160 up ssh在1…...

黑马程序员Java笔记整理(day05)

1.面向对象编程 2.用法 3.对象是什么 4.对象在计算机中是啥 5.无参与有参构造器 小结: 6.this的作用 7.小结 8.封装 9.小结 10.实体类 11.小结 12.static 13.小结 14.static修饰方法 15.static应用前景 16.几个注意事项 17.java中可以直接用类的名字创建数组&#xff0c;如: M…...

DM达梦管理工具拖出空白区块,无法关闭

1. 出现问题&#xff1a;DM达梦管理工具拖出空白区块&#xff0c;无法关闭。 2. 解决方法 新建查询页&#xff0c;把查询页拖到空白区块里&#xff0c;完全覆盖空白区块。之后空白区块会变成查询页&#xff0c;右上角会出现叉号&#xff0c;点击叉号关闭就行。 3. 后记 达梦…...

Linux系统 异常控制流

文章目录 前言异常1. **中断&#xff08;interrupt&#xff09;**2. **陷阱和系统调用&#xff08;trap&#xff09;**3. **故障&#xff08;fault&#xff09;**4. **终止&#xff08;abort&#xff09;** 进程与信号非本地跳转 前言 下面内容大部分来自《深入理解计算机系统…...

Linux环境下配置neo4j图数据库

1.下载安装包 openjdk-11.0.1_linux-x64_bin.tar.gz neo4j-community-4.2.19-unix.tar.gz 2.之前配置好的配置文件 neo4j.conf 3.安装 3.1-jdk11的安装&#xff08;jdk1.8不够用&#xff09; 解压缩 tar -zxvf openjdk-11.0.1_linux-x64_bin.tar.gz修改系统环境变量 打开pro…...

python打包深度学习虚拟环境

今天师兄让我把环境打包发给他&#xff0c;我才知道可以直接打包深度学习虚拟环境&#xff0c;这样另一个人就不用辛辛苦苦的去装环境了&#xff0c;我们都知道有些论文他需要的环境很难装上。比如装Apex&#xff0c;装 DCN&#xff0c;mmcv-full 我现在把3090机子上的ppft虚拟…...

关于IDE的相关知识之一【使用技巧】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于ide使用技巧的相关内容&#xff01; 关于…...

Redis开发03:常见的Redis命令

1.输入以下命令&#xff0c;启动redis。 sudo service redis-server start 如果你是直接安装在WSL的&#xff0c;搜索栏搜索Ubuntu或者点击左下角Windows图表找到U那一栏&#xff0c;直接打开Ubentu&#xff0c;输入账密后&#xff0c;输入“sudo service redis-server start”…...

[OS] A4-前菜介绍

从你的描述来看&#xff0c;这段话是给你的一些 预备知识 和 mkfs工具的使用 提示&#xff0c;帮助你了解如何构建和管理文件系统&#xff0c;特别是关于 xv6 文件系统的一些基本操作。 我会通过比喻和通俗化的方式逐步解释&#xff1a; 预备知识&#xff1a;xv6 文件系统的基…...

2024农历年余下的数模比赛名单已出炉!

数学建模比赛季又来了&#xff01;作为一名资深的数学建模辅导老师&#xff0c;我想对你们说&#xff1a;这不仅是挑战智商的时候&#xff0c;也是展现团队合作力、数据分析能力和逻辑思维的最佳舞台&#xff01;&#x1f4a1; 如果你是建模新手&#xff0c;或者想让自己的比赛…...

在开发环境中,前端(手机端),后端(电脑端),那么应该如何设置iisExpress

首先&#xff0c;要想手机端应用能成功请求后端&#xff0c;两个设备至少需在同一个局域网内&#xff0c;且IP地址互通&#xff1b; 因为ajax是http(s)://IP地址端口号的方式请求&#xff0c;但是iisExpress默认是localhost如何解决&#xff0c;并没有IP地址&#xff0c;所以手…...

2.安装docker、docker compose

1. 安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm22. 设置阿里云docker-ce镜像源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3. docker-ce 安装 yum install -y docker-ce4. docker-compo…...

windows中idea选择bash作为控制台指令集,但是系统环境变量未在其中生效处理

1. 引言 在windows系统中安装node 以及npm时配置其环境&#xff0c;使用window环境变量的配置方式在系统环境变量设置的地方设置了环境变量如下图1-1&#xff0c;设置后在idea中的控制台通过 echo $PATH 查看环境变量发先跟系统中配置的不一致&#xff0c;而且node -v npm -v指…...

如何通过 ADB 安装 xapk

Android开发这么久,今天发现还能这么操作!😂 记录通过ADB安装xapk、apks的两种方式: 1.ADB命令安装使用APK-Splits技术分包的应用程序 这位大佬的方式步骤较为繁琐,不过兼容性应该较好,亲测成功安装。 2.How to install xapk, apks, or multiple-apks via adb? 这个…...

Docker使用教程

Docker 是一个开源的容器化平台&#xff0c;用于开发、打包和分发应用程序。它允许将应用及其依赖环境打包成容器&#xff0c;从而实现跨平台的便捷部署。下面是一个简单的 Docker 使用教程&#xff0c;涵盖从安装到基本命令的使用。 1. 安装 Docker Windows / MacOS 访问 D…...

我的创作纪念日

一、机缘 成为创作者的初衷是从学习C/C语法与数据结构过程中获得的灵感。在日常学习和项目实践中&#xff0c;我发现这些知识既丰富又复杂&#xff0c;对初学者而言尤为困难。因此&#xff0c;我决定通过博客记录自己的学习过程、解决思路以及代码实现&#xff0c;帮助更多人在…...

软件质量保证——单元测试之白盒技术

笔记内容及图片整理自XJTUSE “软件质量保证” 课程ppt&#xff0c;仅供学习交流使用&#xff0c;谢谢。 程序图 程序图定义 程序图P&#xff08;V,E&#xff09;&#xff0c;V是节点的集合&#xff08;节点是程序中的语句或语句片段&#xff09;&#xff0c;E是有向边的集合…...

redis中的哨兵

redis中的哨兵 一、哨兵机制的概念二、redis哨兵的部署2.1 docker的安装2.2 编排redis主从节点2.3 配置哨兵节点 三、redis哨兵的选举机制3.1 redis-master宕机之后的情况3.2 重启redis-master后的情况 四、redis哨兵机制的原理4.1主观下线4.2客观下线4.3选举leader节点4.4选出…...

开源对象存储新选择:在Docker上部署MinIO并实现远程管理

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…...

15分钟做完一个小程序,腾讯这个工具有点东西

我记得很久之前&#xff0c;我们都在讲什么低代码/无代码平台&#xff0c;这个概念很久了&#xff0c;但是&#xff0c;一直没有很好的落地&#xff0c;整体的效果也不算好。 自从去年 ChatGPT 这类大模型大火以来&#xff0c;各大科技公司也都推出了很多 AI 代码助手&#xff…...

houdini肌肉刷pin点的方法

目标&#xff1a;产生gluetoanimation这个属性 主要节点&#xff1a;attribute paint(或者muscle paint) 步骤1&#xff1a; 导入肌肉资产 导入的是rest shape的肌肉 在有侧边栏可以打开display group and attribute list&#xff0c;方便查看group。不同的肌肉块按照muscl…...

Ubuntu20.04安装NVIDIA显卡驱动

Ubuntu20.04安装NVIDIA显卡驱动 参考资料&#xff1a;https://blog.csdn.net/weixin_39244242/article/details/136282614?fromshareblogdetail&sharetypeblogdetail&sharerId136282614&sharereferPC&sharesourceqq_37397652&sharefromfrom_link 成功配置…...

k8s删除网络组件错误

k8s集群删除calico网络组件重新部署flannel网络组件&#xff0c;再部署pod后出现报错不能分配ip地址 plugin type"calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized 出现该问题是因为删除网络组件后&#xff0c;网…...

民锋视角:多元化策略实现资产稳健增长

在全球化经济的推动下&#xff0c;市场呈现出高度的复杂性与多样性。面对不同经济周期和市场动态&#xff0c;民锋以多元化投资策略为核心&#xff0c;帮助投资者在不确定性中实现资产的稳健增长。 一、多元化策略的核心价值 降低单一市场风险 单一资产或市场的表现可能因不可…...

[已解决]Visual Studio 2022中如何同时打开多个项目多个独立窗口

同时运行两个VS2022程序&#xff0c;即点击运行Visual Studio 2022.exe后&#xff0c;再点击运行一次运行Visual Studio 2022.exe&#xff0c;效果如图...

11、PyTorch中如何进行向量微分、矩阵微分与计算雅克比行列式

文章目录 1. Jacobian matrix2. python 代码 1. Jacobian matrix 计算 f ( x ) [ f 1 x 1 2 2 x 2 f 2 3 x 1 4 x 2 2 ] , J [ ∂ f 1 ∂ x 1 ∂ f 1 ∂ x 2 ∂ f 2 ∂ x 1 ∂ f 2 ∂ x 2 ] [ 2 x 1 2 3 8 x 2 ] \begin{equation} f(x)\begin{bmatrix} f_1x_1^22x_2\\…...

51c自动驾驶~合集35

我自己的原文哦~ https://blog.51cto.com/whaosoft/12206500 #纯视觉方案的智驾在大雾天还能用吗&#xff1f; 碰上大雾天气&#xff0c;纯视觉方案是如何识别车辆和障碍物的呢&#xff1f; 如果真的是纯纯的&#xff0c;特头铁的那种纯视觉方案的话。 可以简单粗暴的理解为…...

位图和布隆过滤器

目录 一.位图 1.位图的概念 2.位图的实现 3.位图的应用 二.布隆过滤器 1.布隆过滤器的概念 2.布隆过滤器的实现 3.布隆过滤器的优缺点 三.整体代码 1.bitset.h 2.BloomFilter 3.Hash.cpp 一.位图 1.位图的概念 1.面试题 给40亿个不重复的无符号整数&#xff0c;没…...

Java—I/O流

Java的I/O流&#xff08;输入/输出流&#xff09;是用于在程序和外部资源&#xff08;如文件、网络连接等&#xff09;之间进行数据交换的机制。通过I/O流&#xff0c;可以实现从外部资源读取数据&#xff08;输入流&#xff09;或将数据写入外部资源&#xff08;输出流&#x…...

CSS样式

第一章&#xff1a;CSS类型 1、行内样式 <div style"color:red;font-size:30px;font-weight: 900;font-style: italic;">ABCD</div>注意&#xff1a;行内样式&#xff0c;作用力优先级最高&#xff0c;但是不利于html与css的书写以及修改&#xff0c;会…...

idea_卸载与安装

卸载与安装 卸载1、设置 -> 应用2、查找到应用&#xff0c;点击卸载3、把删除记录和设置都勾选上4、删除其它几个位置的残留 安装1、下载安装包2、欢迎安装 -> Next3、选择安装目录 -> Next4、创建快捷图标和添加到环境变量5、确认文件夹的名称 -> Install6、完成安…...

大数据-237 离线数仓 - 广告业务 需求分析 ODS DWD UDF JSON 串解析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…...

视觉语言模型(VLM)学习笔记

目录 应用场景举例 VLM 的总体架构包括&#xff1a; 深度解析&#xff1a;图像编码器的实现 图像编码器&#xff1a;视觉 Transformer 注意力机制 视觉-语言投影器 综合实现 训练及注意事项 总结 应用场景举例 基于文本的图像生成或编辑&#xff1a;你输入 “生成一张…...

Spring 自调用事务失效分析及解决办法

前言 博主在写公司需求的时候&#xff0c;有一个操作涉及到多次对数据库数据的修改。当时就想着要加 Transactional注解来声名事务。并且由于一个方法中有太多行了&#xff0c;于是就想着修改数据库的操作单独提取出来抽象成一个方法。但这个时候&#xff0c;IDEA 提示我自调用…...

【ROS2】Ubuntu22.04安装ROS humble

一. ROS简介 1.1 什么是ROS ROS 是一个适用于机器人的开源的元操作系统。它提供了操作系统应有的服务&#xff0c;包括硬件抽象&#xff0c;底层设备控制&#xff0c;常用函数的实现&#xff0c;进程间消息传递&#xff0c;以及包管理。ROS的核心思想就是将机器人的软件功能做…...

免费开源的微信开发框架

请求参数 Header 参数 export interface ApifoxModel {"X-GEWE-TOKEN": string;[property: string]: any; } Body 参数application/json export interface ApifoxModel {/*** 设备ID*/appId: string;/*** 是否允许*/enabled: boolean;[property: string]: any; }…...

【第二讲】Spring Boot 3.4.0 新特性详解:新的依赖管理功能

Spring Boot 3.4.0 版本引入了一些显著的改进&#xff0c;其中之一就是新的依赖管理功能。这些改进不仅提升了依赖管理的便利性和一致性&#xff0c;还增强了项目的可维护性和可扩展性。本文将详细介绍 Spring Boot 3.4.0 中新的依赖管理功能&#xff0c;提供具体的使用示例和场…...

CSAPP Cache Lab(缓存模拟器)

前言 理解高速缓存对 C 程序性能的影响&#xff0c;通过两部分实验达成&#xff1a;编写高速缓存模拟器&#xff1b;优化矩阵转置函数以减少高速缓存未命中次数。Part A一开始根本不知道要做什么&#xff0c;慢慢看官方文档&#xff0c;以及一些博客&#xff0c;和B站视频&…...

Vue项目通过Nginx部署多个

1.将Vue项目部署到Nginx根 1.1 修改vue.config.js&#xff0c;默认可以不设置 module.exports {publicPath: / } 1.2 修改index.js&#xff0c;默认可以不设置 export default new Router({...base: "/"... }) 1.3 修改nginx.conf location / {root /usr/shar…...

【React】全局状态管理(Context, Reducer)

以下为知行小课学习笔记。 概述 Context 跨组件共享状态 在 Next 项目&#xff0c;封装 useContext。 AppContext.tsx "use client";import React, {createContext, Dispatch, ReactNode, SetStateAction, useContext, useMemo, useState} from react;type State …...

Docker容器ping不通外网问题排查及解决

Docker容器ping不通外网问题排查及解决 解决方案在最下面&#xff0c;不看过程的可直接拉到最下面。 一台虚拟机里突然遇到docker容器一直访问外网失败&#xff0c;网上看到这个解决方案&#xff0c;这边记录一下。 首先需要明确docker的网桥模式&#xff0c;网桥工作在二层…...