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

将 MySQL 8 主从复制延迟优化到极致

目录

一、网络资源不足引起的复制延迟

1. 执行监控确认延迟原因

2. 估算所需带宽

(1)基本公式

(2)实际测量方法

二、大事务或大查询引起的复制延迟

1. 主库大事务

2. 从库大查询

3. 估算所需 I/O 能力

(1)基本公式

(2)实际估算

三、高并发引起的复制延迟

1. 并发量估算

2. 数据库优化

(1)主库配置

(2)从库配置


        本篇文章详细分析了一个实际应用中对 MySQL 8 主从复制延迟进行优化的案例,MySQL 版本为 8.0.22,一主一从两个实例开启 GTID 并进行普通的异步复制,主库读写从库只读,主、从实例的基本配置如下:

binlog_format = ROW
transaction_isolation = READ-COMMITTED
bulk_insert_buffer_size = 1G
innodb_adaptive_hash_index = 0
log_slave_updates = 1
sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
max_allowed_packet = 1G
explicit_defaults_for_timestamp = 0
log_timestamps = SYSTEM
binlog_expire_logs_seconds = 259200
innodb_buffer_pool_size = 80G
max_connections = 1000
default-time-zone = '+8:00'
skip-name-resolve 
innodb_print_all_deadlocks = 1
log_output = 'table'
slow_query_log = 1
long_query_time = 1
gtid-mode = on
enforce_gtid_consistency = true
local_infile = 1
skip_symbolic_links

        下面从可能引起复制延迟的三个方面进行分析。

一、网络资源不足引起的复制延迟

        我们可以将复制的时间分为两部分:一是事件从主库到从库的传输时间,二是事件在从库上的重放执行时间。事件在主库上记录 binlog 后到传递到从库的时间理论上非常快,因为它只取决于网络速度。MySQL binlog 的 dump 线程不是通过轮询方式请求事件,而是由主库来通知从库新的事件,因为前者低效且缓慢。从主库读取一个 binlog event 是一个阻塞型网络调用,当主库记录事件后,马上就开始发送。因此可以说,只要复制的 I/O 线程被唤醒并且能够通过网络传输数据,事件就会很快到达从库。但是,如果网络很慢或者 binlog event 很大,记录 binlog 和在从库上执行的延迟可能会非常明显。

1. 执行监控确认延迟原因

        监控脚本文件 get_Gtid_totable.sh 内容如下:

#!/bin/bashsource ~/.bash_profile# 获取主库 binlog 位点
a=`mysql -uroot -p123456 -h10.10.10.1 -P3306 -e "show master status\G" 2>/dev/null | egrep 'f8e0355d-9d6e-11ee-8dcd-e43d1a47c7b7' | sed 's/,//' | awk -F: '{print $2}' | awk -F"-" '{print $2}'`# 获取从库接收和执行 binlog 位点
b=`mysql -uroot -p123456 -h10.10.10.2 -e "show slave status\G" 2>/dev/null | egrep 'f8e0355d-9d6e-11ee-8dcd-e43d1a47c7b7' | egrep -v "Master_UUID" | sed -e '1s/f8e0355d-9d6e-11ee-8dcd-e43d1a47c7b7:1-//g' | sed -e '2s/f8e0355d-9d6e-11ee-8dcd-e43d1a47c7b7:1-//g'`# 获取从库延迟秒数
c=`mysql -uroot -p123456 -h10.10.10.2 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | sed 's/Seconds_Behind_Master: //g'`
Seconds_Behind_Master=`echo $c`master_Executed_Gtid=`echo $a`
slave_Retrieved_Gtid=`echo $b | awk '{print $1}' | sed 's/.$//'`
slave_Executed_Gtid=`echo $b | awk '{print $2}' | sed 's/.$//'`# 入库
mysql -h10.10.10.3 -P3306 -uroot -p123456 -e "
insert into test.t_lag (master_Executed_Gtid, slave_Retrieved_Gtid, slave_Executed_Gtid,Seconds_Behind_Master)
values ("$master_Executed_Gtid","$slave_Retrieved_Gtid","$slave_Executed_Gtid","$Seconds_Behind_Master");"

        只监控业务高峰期,用 cron 调度执行:

* 0-3,19-23 * * * /home/mysql/get_Gtid_totable.sh

        test.t_lag 建表语句如下:

use test;
create table t_lag (ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,master_Executed_Gtid bigint(20) DEFAULT NULL,slave_Retrieved_Gtid bigint(20) DEFAULT NULL,slave_Executed_Gtid bigint(20) DEFAULT NULL,rlag int(11) DEFAULT (greatest((master_Executed_Gtid - slave_Retrieved_Gtid),0)),elag int(11) DEFAULT (greatest((slave_Retrieved_Gtid - slave_Executed_Gtid),0)),Seconds_Behind_Master int(11) DEFAULT NULL
);

        查询监控结果如下:

mysql -h172.18.16.156 -P3306 -uroot -p123456 -Dtest -e "
select ts \"时间\",rlag \"接收binlog落后事务数\",elag \"执行binlog落后事务数\",Seconds_Behind_Master \"延迟秒数\"from t_lag where date(ts)='2024-04-25'order by Seconds_Behind_Master desc limit 10;" 2>/dev/null
+---------------------+---------------------------+----------------------------+--------------+
| 时间                 | 接收binlog落后事务数        | 执行binlog落后事务数         | 延迟秒数       |
+---------------------+---------------------------+----------------------------+--------------+
| 2024-04-25 22:43:01 |                    144230 |                        112 |          119 |
| 2024-04-25 22:46:02 |                    137649 |                        981 |          118 |
| 2024-04-25 22:25:02 |                    146937 |                        186 |          115 |
| 2024-04-25 22:44:01 |                    135479 |                        898 |          114 |
| 2024-04-25 22:24:01 |                    140064 |                        258 |          112 |
| 2024-04-25 22:49:01 |                    146843 |                        228 |          111 |
| 2024-04-25 22:53:02 |                    146033 |                       2032 |          110 |
| 2024-04-25 22:26:02 |                    140634 |                          9 |          110 |
| 2024-04-25 22:23:01 |                    137269 |                        747 |          109 |
| 2024-04-25 22:40:02 |                    127012 |                        350 |          108 |
+---------------------+---------------------------+----------------------------+--------------+

        从查询结果可以看到,接收 binlog 落后事务数很大,执行 binlog 落后事务数很小,说明引起复制延迟的原因是主库 binlog 无法及时传输到从库。经过排查发生复制延迟时主从之间的网络带宽被打满,这就是瓶颈所在。

2. 估算所需带宽

(1)基本公式

        确认带宽不足后,下个要解决的问题是量化评估所需带宽。从 MySQL 主从复制的原理可知,网络上传输的就是 binlog 文件,因此可以基于 binlog 大小计算基本复制流量:

所需带宽 ≈ (每日 binlog 生成量 * 复制因子) / 86400 秒

        其中“复制因子”指的是需要接收复制数据的从库实例的(Slave)数量。

(2)实际测量方法

        确认 binlog 所在目录和文件大小:

mysql> show variables like 'innodb_log_group_home_dir';
+---------------------------+------------------+
| Variable_name             | Value            |
+---------------------------+------------------+
| innodb_log_group_home_dir | /data/3306/dblog |
+---------------------------+------------------+
1 row in set (0.01 sec)mysql> show variables like 'innodb_log_file_size';
+----------------------+------------+
| Variable_name        | Value      |
+----------------------+------------+
| innodb_log_file_size | 1073741824 |
+----------------------+------------+
1 row in set (0.01 sec)

        计算一天的 binlog 大小,例如 4 月 21 日的 binlog 文件总大小:

ls -l /data/18251/dblog/* | grep "Apr 21" | wc -l
108

        每个文件大小 1GB,一天生成 108 个文件,总大小为 108GB。本案例是一主一从,因此:

平均每秒数据量 ≈ 108 * 1024 MB / 86400 秒 ≈ 1.28 MB/秒

        转换为带宽(Mbps):

1 Byte = 8 bits
1.28 MB/秒 = 1.28 * 8 = 10.24 Mbps

        因此,理论最小带宽需求为 10.24 Mbps(匀速传输)。MySQL 的写入通常有波动(如业务高峰时 binlog 生成更快),建议预留 2-5 倍 的带宽,因此实际带宽需求(考虑峰值)推荐为:

10.24 Mbps * 3 ≈ 30 Mbps

        在本例的场景中,一共有 8 对主从复制,理论上需要 240 Mbps 的带宽,但实际上每个实例的业务量并不平均。上面的计算是基于业务量最大的一个实例(也正是日常有复制延迟的实例),其它的实例所产生的 binlog 小得多。经过不断尝试,当带宽增加到 100 Mbps 时,复制延迟的次数和延迟秒数都少了很多。

二、大事务或大查询引起的复制延迟

        如果查询需要执行很长时间而网络很快,通常可以认为重放时间占据了更多的复制时间开销,其中主库大事务或从库大查询引起的复制延迟是常见的情况。

1. 主库大事务

        主库上执行的大事务会通过 binlog 传输到从库重放。在从库上执行 show slave status\G 命令,如果在输出中看到:

  • Retrieved_Gtid_Set 不断增长
  • Executed_Gtid_Set 长时间不增长
  • Seconds_Behind_Master 持续增加
  • Slave_SQL_Running_State 长时间为 System lock

        可以依此判断出从库仍在不断接收主库发送的 binlog,但因为正在重放一个大事务,在这个大事务提交前,从库的 GTID 不变,所以造成了复制延迟。

2. 从库大查询

        为了保证主从数据一致性,通常将从库设置为只读(read_only、super_read_only),这意味着不会有在从库发起的事务,但从库上可以执行查询。如果在从库上执行一个大查询,可能将 I/O 资源占满,产生 I/O 等待,从而产生复制延迟。执行类似 iostat -dmx 2 100 的操作系统命令,其输出中的 %util 列接近或达到 100% 就是这种情况。

3. 估算所需 I/O 能力

        无论是主库大事务,还是从库大查询,都会产生大量的磁盘 I/O,以至于 binlog 因为 I/O 等待无法及时重放,使得复制延迟。如果只是偶发情况,只要耐心等待大事务或大查询执行完成,之后通常从库的复制能尽快追上主库,不用人为干涉。如果是日常情况,就需要考虑增加 I/O 子系统的能力了。

(1)基本公式

        以下是估算 I/O 能力的基本公式:

从库所需 IOPS ≈ 主库写入 IOPS * (1 + 安全系数)

        通常安全系数建议为 0.2-0.5(20%-50%)。

(2)实际估算

        还是从 binlog 入手进行估算,前面已经得到:

平均每秒数据量 ≈ 108 * 1024 MB / 86400 秒 ≈ 1.28 MB/秒

        假设平均 I/O 大小为 8KB,这是一个经验值。

  1. InnoDB 的默认页(Page)大小为 16KB,这是磁盘 I/O 的最小单位。但实际 I/O 操作可能涉及:部分页写入(如只修改了页的一部分,但通常仍以页为单位写入);随机 I/O(如索引查询可能只读取部分数据)。因此,实际平均 I/O 大小通常小于 16KB,8KB 是一个常见的折中值。
  2. 文件系统(如 ext4、XFS)和磁盘控制器可能会合并 I/O 请求。但随机读写场景下,I/O 可能无法完全合并,因此 8KB 能更好地反映实际负载。
  3. MySQL 的 binlog 和 InnoDB 的 redo log(事务日志)通常是顺序写入,但每次写入的大小取决于事务量:小事务(如单行更新)可能产生 几百字节~几KB 的日志;大事务(如批量插入)可能触发更大的 I/O(16KB 或更多)。8KB 是对这种混合负载的合理估算。
主库写入 IOPS = 1.28MB/s / 8KB ≈ 164 IOPS
从库所需IOPS ≈ 164 * 1.3 ≈ 213 IOPS

        另外,如果从库还处理读请求,需要额外 I/O 能力。通常 HDD 只能提供 100-200 IOPS,而 SSD/NVMe 通常可提供数千至数十万 IOPS,因此使用 SSD/NVMe 存储。本案例中存储使用的是 SSD,除了偶尔的大事务或大查询会把 I/O 跑满,其它大多数情况下,I/O 能力都是充足的。

三、高并发引起的复制延迟

        在带宽没跑满,I/O 使用率很低的情况下,实际还有长时间复制延迟,其原因就是主库高并发的小事务。解决这个问题的思路就是采取各种手段提高 MySQL 主从两端的并行度,到这就该进行数据库层面的优化了。

1. 并发量估算

        因为 binlog 中只会记录与行更新有关的操作,所以与复制相关的并发量应该基于主库的每秒事务数,即 TPS 进行估算。具体的计算方法有两种,一是定期(如每分钟)执行状态采集,例如:

# 每 10 秒采样一次,显示相对值(差值)
mysqladmin -uroot -p123456 -h10.10.10.1 extended-status -r -i 10 | egrep 'Com_insert|Com_update|Com_delete'

        然后按下面的公式计算一次采样的 TPS:

TPS = (Com_delete + Com_delete_multi + Com_insert + Com_insert_select + Com_update + Com_update_multi) / 10

        这里有几点需要注意:

  • 在业务峰值时间段采样。
  • 忽略第一个采样值,因为第一次没有相对值。
  • 因为采集的就是差值,所以直接相加返回的状态值。
  • 多次采样计算 TPS 平均值。

        第二种计算方法更直接:基于 GTID 数计算。例如利用前面 test.t_lag 表的 master_Executed_Gtid 字段,执行下面的查询即可得出 TPS:

select ts, master_executed_gtid_diff / time_diff_sec as tpsfrom (select ts, master_executed_gtid,master_executed_gtid - lag(master_executed_gtid) over (order by ts) as master_executed_gtid_diff,timestampdiff(second, lag(ts) over (order by ts), ts) as time_diff_secfrom test.t_lag) as diffswhere master_executed_gtid_diff is not null and time_diff_sec > 0order by ts;

2. 数据库优化

(1)主库配置

# 二进制日志组提交优化(极限值为 5000、100)
binlog_group_commit_sync_delay = 2000         # 2 毫秒延迟(最大建议值)
binlog_group_commit_sync_no_delay_count = 50  # 50 个事务强制提交

        对于超高频系统(>10万TPS),可调整为:
binlog_group_commit_sync_delay = 1000    # 1ms
binlog_group_commit_sync_no_delay_count = 100

        对于普通高并发(1-5万TPS)保持当前值即可。

# 配套参数优化
sync_binlog = 1000                            # 每 1000 次写入同步一次
innodb_flush_log_at_trx_commit = 2            # 每秒刷新日志(牺牲部分持久性)
binlog_order_commits = OFF                    # 提高并行度

        风险提示:

  • innodb_flush_log_at_trx_commit = 2 可能导致最多 1 秒的数据丢失。我们是互联网业务,没有那么强的数据安全性要求。如果是金融级应用必须设为 1。
  • sync_binlog = 1000 在崩溃时可能丢失最多 999 个未同步的 binlog 事件。折中方案可以设置为 100。
# 事务日志优化
innodb_log_file_size = 1G                     # 大事务日志文件
innodb_log_buffer_size = 64M                  # 大日志缓冲区# 刷盘方法优化
innodb_flush_method = O_DIRECT                # InnoDB 直接写盘,避免双重缓存

        最佳实践:

  • 对于 Linux + SSD/NVMe 环境保持 O_DIRECT。
  • Windows 环境使用 async_unbuffered
  • 传统硬盘可测试 O_DSYNC

        innodb_flush_method 为只读参数,需要重启 MySQL 实例才能生效。

# 基于 WRITESET 的复制优化
binlog_transaction_dependency_tracking = WRITESET        # 基于事务修改的数据行判断依赖
transaction_write_set_extraction = XXHASH64              # 使用 64 位 XXHASH 算法

        当这两个参数配合使用时:

  • 主库为每个事务计算其修改行的 XXHASH64 哈希值。
  • 将这些哈希值(称为 writeset)记录到 binlog。
  • 从库通过比较不同事务的 writeset 判断是否可以并行执行。

(2)从库配置

slave_pending_jobs_size_max = 2G          # 大内存缓冲
slave_compressed_protocol = ON            # 启用压缩传输
sync_binlog = 0                           # 刷新 binlog 完全依赖操作系统
innodb_flush_log_at_trx_commit = 0        # 刷新日志完全依赖操作系统
innodb_flush_method=O_DIRECT              # InnoDB 直接写盘,避免双重缓存
log_slave_updates=0                       # 关闭从库更新 binlog

        sync_binlog 与 innodb_flush_log_at_trx_commit 双 0 组合使用的效果:

  • 最高性能模式,最低安全性。
  • 完全禁用持久性保证,崩溃可能导致数据丢失。
  • 仅适用于可容忍数据丢失的非关键从库。
  • 比安全配置(sync_binlog、innodb_flush_log_at_trx_commit 双 1)吞吐量高 5-10 倍。
slave_parallel_type = LOGICAL_CLOCK       # 从库并行复制的依赖检测方式
slave_parallel_workers = 32               # 32 线程并行复制
slave_preserve_commit_order = 0           # 不保持事务的原始提交顺序

        建议调整:

  • slave_parallel_type = LOGICAL_CLOCK 使用主库 binlog 中的逻辑时间戳判断事务依赖关系,需要主库启用 binlog_group_commit_sync_delay 才能产生足够的并行机会。相比 DATABASE 并行度更高。
  • 对于高并发从库,slave_parallel_workers 设为 CPU 核心数的 50-75%。
  • slave_preserve_commit_order 设置为 0 延迟更低,并行度更高,但可能暂时性与主库数据不一致。关键业务设为 1 保持顺序;非关键业务/分析从库可设为 0 以提高性能;级联复制的中间从库可设为 0,末端从库设为 1。
# 从库只读
read_only
super_read_only

        这里每个配置参数只做了简明扼要的说明,因为要讲透需要很多知识点和篇幅,有兴趣的请自行脑补。本案例采用以上主从配置,解决了高负载 MySQL 实例的复制延迟问题。

        注意:这个案例中的从库是一个用于大数据分析的从库,数据安全性和一致性要求并不高,所以以上配置是以消除复制延迟为最高优先级考虑的,牺牲了一定的数据一致性和数据安全性,是否适用于特定应用场景还要具体问题具体分析。

相关文章:

将 MySQL 8 主从复制延迟优化到极致

目录 一、网络资源不足引起的复制延迟 1. 执行监控确认延迟原因 2. 估算所需带宽 (1)基本公式 (2)实际测量方法 二、大事务或大查询引起的复制延迟 1. 主库大事务 2. 从库大查询 3. 估算所需 I/O 能力 (1&am…...

路由与OSPF学习

【路由是跨网段通讯的必要条件】 路由指的是在网络中,数据包从源主机传输到目的主机的路径选择过程。 路由通常涉及以下几个关键元素: 1.路由器:是一种网络设备,负责将数据包从一个网络传输到另一个网络。路由器根据路由表来决定…...

Spring Security:企业级安全架构的设计哲学与工程实践

一、核心架构与设计理念 Spring Security作为Spring生态中的安全基石,其架构设计遵循**“分层过滤"与"组件化扩展”**两大原则。整个安全框架本质上是一个由多个过滤器构成的链式处理模型(Filter Chain),每个过滤器负责…...

NLP高频面试题(五十二)——BERT 变体详解

在现代自然语言处理领域,BERT 系列模型不断演进,衍生出多种变体,它们通过改进预训练任务、模型结构和训练策略,在不同应用场景下取得了更优表现。本文首先概览主要 BERT 变体(如 ALBERT、RoBERTa、ELECTRA、SpanBERT、Transformer-XL 等),随后针对以下几个关键问题逐一展…...

C++Primer 编程练习 第二章

最近想重新看一下CPrimer&#xff0c;顺便敲一下他的编程练习题&#xff0c;虽然很简单&#xff0c;但是就当是锻炼一下vim的熟练度和手感 由于按照章节顺序来说是初学者&#xff0c;不会对输入内容做过多的判断&#xff0c;只对问题作出基本实现 第二章 1 #include <ios…...

Vue.js 新手小白指南:从起源到实战

&#x1f31f; Vue 的来源 Vue.js 由**尤雨溪&#xff08;Evan You&#xff09;**在2014年创建&#xff0c;最初是作为个人项目开发&#xff0c;灵感来源于他在 Google 使用 AngularJS 的经验。Vue 的设计目标是提供一个更轻量级、更易上手的前端框架。 如今&#xff0c;Vue …...

策略模式:动态切换算法的设计智慧

策略模式&#xff1a;动态切换算法的设计智慧 一、模式核心&#xff1a;定义一系列算法并可相互替换 在软件开发中&#xff0c;常常会遇到需要根据不同情况选择不同算法的场景。例如&#xff0c;在电商系统中&#xff0c;根据不同的促销活动&#xff08;如满减、折扣、赠品&a…...

Vm免安装直接使用虚拟机win7系统

教程 一、下载并解压资料里面的vmx压缩包 二、使用Vm软件打开刚刚解压的vmx文件即可使用虚拟机的win7系统 资料下载 点击下载...

LSTM-GAN生成数据技术

1. 项目概述 本项目利用生成对抗网络&#xff08;GAN&#xff09;技术来填补时间序列数据中的缺失值。项目实现了两种不同的GAN模型&#xff1a;基于LSTM的GAN&#xff08;LSTM-GAN&#xff09;和基于多层感知机的GAN&#xff08;MLP-GAN&#xff09;&#xff0c;并对两种模型…...

26、C# 中是否可以继承String类?为什么?

在 C# 中&#xff0c;不能直接继承 String 类&#xff08;System.String&#xff09;。这是由于以下几个原因&#xff1a; 1、String 类是 sealed 的 String 类在 .NET 中被标记为 sealed&#xff0c;这意味着它是一个密封类&#xff0c;不能被继承。 sealed 关键字的作用是防…...

gem5教程第五章 了解gem5默认配置脚本

在本章中,我们将探讨如何使用gem5附带的默认配置脚本。 gem5附带了许多配置脚本,使您能够非常快速地使用gem5。 然而,一个常见的陷阱是在不完全理解所模拟内容的情况下使用这些脚本。在使用gem5进行计算机架构研究时,充分了解您正在模拟的系统非常重要。本章将引导您了解默…...

什么是鸿蒙南向开发?什么是北向开发?

文章目录 鸿蒙南向开发 vs 北向开发&#xff1a;底层与生态的双向赋能一、鸿蒙南向开发&#xff1a;连接硬件的底层基石二、鸿蒙北向开发&#xff1a;构建全场景应用生态三、南向与北向&#xff1a;互补与协同四、如何选择开发方向?结语 鸿蒙南向开发 vs 北向开发&#xff1a;…...

蓝桥杯 19. 最大比例

最大比例 原题目链接 题目描述 X 星球的某个大奖赛设了 M 级奖励。每个级别的奖金是一个正整数。 并且&#xff0c;相邻两个级别间的比例是一个固定值&#xff0c;也就是说&#xff1a;所有级别的奖金构成一个等比数列。 例如&#xff1a; 奖金数列为 16, 24, 36, 54&…...

制造业数字化转型标杆解析:从冀凯机电到君乐宝的启示

1. 执行摘要 数字化转型已成为现代制造业提升竞争力、实现高质量发展的核心驱动力。本文旨在通过深入剖析冀凯装备制造股份有限公司&#xff08;冀凯机电&#xff09;和君乐宝乳业集团&#xff08;君乐宝&#xff09;两家不同行业背景企业的数字化转型实践&#xff0c;提炼可供…...

【OSCP-vulnhub】Raven-2

目录 端口扫描 本地/etc/hosts文件解析 目录扫描&#xff1a; 第一个flag 利用msf下载exp flag2 flag3 Mysql登录 查看mysql的运行权限 MySql提权&#xff1a;UDF 查看数据库写入条件 查看插件目录 查看是否可以远程登录 gcc编译.o文件 创建so文件 创建临时监听…...

配置MambaIRv2: Attentive State Space Restoration的环境

github上代码的地址&#xff1a; csguoh/MambaIR: [ECCV2024, CVPR2025] MambaIR and MambaIRv2! 一开始直接输入命令 conda env create -f environment.yaml 安装了半天爆出来好几个错误&#xff0c;其中一个是没有nvcc 输入以下命令&#xff1a; module avail 发现没有…...

4.23晚间工作总结

主要工作&#xff1a;将ClassicDetail界面拆分成utils,apis,stores,css,vue多个文件&#xff0c;方便后续重用 具体代码截图&#xff1a;...

Maven 项目中引入本地 JAR 包

在日常开发过程中&#xff0c;我们有时会遇到一些未上传到 Maven 中央仓库或公司私有仓库的 JAR 包&#xff0c;比如第三方提供的 SDK 或自己编译的库。这时候&#xff0c;我们就需要将这些 JAR 包手动引入到 Maven 项目中。本文将介绍两种常见方式&#xff1a;将 JAR 安装到本…...

SpringBoot整合SSE,基于okhttp

一、引入依赖 <dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.10.0</version> </dependency> <dependency><groupId>com.squareup.okhttp3</groupId><…...

从云端到边缘:云原生后端架构在边缘计算中的演进与实践

📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:为何云原生后端正在走向边缘? 随着物联网(IoT)、5G 和实时应用的快速发展,越来越多的数据在终端产生并需要即时处理。传统云计算虽强大,但将所有数据上送云端再处理,带来高延迟与带宽压力。…...

pytest心得体会

一、如何单独运行某条用例 在参数化测试中总有些用例失败&#xff0c;由于前后置数据的关系需要单独运行那条用例如何运行呢 方法一&#xff1a;直接查看控制台运行用例 确定是[2-case_data8] pytest.main(["-sv","testcase/违规告警/test_违规告警_非合同车…...

《Cesium 中两点绘制线的实现:实线、虚线、动态线、流动线详解》

摘要 在 Cesium 三维地球可视化开发中,两点之间绘制线是常见的需求。本文详细介绍如何在 Cesium 中实现两点间绘制实线、虚线、动态线和流动线,并提供完整的代码示例,方便开发者快速上手,满足不同场景下的可视化需求。 一、环境与依赖 本文代码基于 Cesium 库进行开发,…...

【EasyPan】MySQL FIELD() 函数实现自定义排序

【EasyPan】项目常见问题解答&#xff08;自用&持续更新中…&#xff09;汇总版 MySQL FIELD() 函数解析 一、FIELD() 函数技术解析 /* 基础语法 */ FIELD(column_name, value1, value2, ..., valueN)核心特性 特性说明返回值机制返回字段值在参数列表中的索引位置&…...

搭建TypeScript单元测试环境

我们在学习TypeScript的时候如果能够搭建一个单元测试的环境&#xff0c;那写些demo会很简单&#xff0c;下面我们使用jest来搭建一个单元测试环境 Jest 是一个由 Facebook 开发并开源的 JavaScript 测试框架&#xff0c;被广泛应用于前端和 Node.js 项目的单元测试。以下是关…...

Vue3父子组件数据同步方法

在 Vue 3 中&#xff0c;当子组件需要修改父组件传递的数据副本并同步更新时&#xff0c;可以通过以下步骤实现&#xff1a; 方法 1&#xff1a;使用 v-model 和计算属性&#xff08;实时同步&#xff09; 父组件&#xff1a; vue <template><ChildComponent v-mo…...

免费且开源的企业级监控解决方案:Zabbix

一、Zabbix 简介 Zabbix 是一款功能强大的企业级开源监控解决方案。它可以监控各种 IT 基础设施组件&#xff0c;包括网络设备、服务器、虚拟机、云服务、应用程序和数据库等。Zabbix 提供实时的监控、告警、报表和可视化功能&#xff0c;帮助用户及时发现和解决 IT 系统中的问…...

高并发系统的通用设计方法是什么?

背景 高并发系统的通用设计方法是解决系统在面对大量用户访问时的性能瓶颈问题。当系统遇到性能瓶颈时&#xff0c;通常是因为某个单点资源&#xff08;如数据库、后端云服务器、网络带宽等&#xff09;达到了极限。 为了提升整个系统的容量&#xff0c;需要找到这个瓶颈资源…...

ubuntu系统下部署使用git教程

在ubuntu系统下部署并使用git教程 1.下载并安装 sudo apt update sudo apt install git2.检验安装是否成功 git --version若输出git版本号即为成功。 3.配置参数 git config --global user.name "你的名字" git config --global user.email "你的邮箱&quo…...

redis client.ttl(key)

对应 Redis 的 TTL 命令&#xff1a; bash 复制 下载 TTL key 使用示例 1. 基本用法 java 复制 下载 try (Jedis jedis jedisPool.getResource()) {long ttl jedis.ttl("user:1001:session");if (ttl > 0) {System.out.println("键将在 " t…...

基于ACL方式手动建立站点间 IPSec 隧道

换句话说 不使用 IKE 自动协商&#xff0c;而是静态配置密钥和 SPI&#xff08;安全参数索引&#xff09;来配置隧道规则 环境基础 还是使用eNSP软件进行模拟&#xff0c;等后面再更新实际通信中的环境 没有框架&#xff0c;就没有基本思路 还是使用前面文章GRE VPN的拓扑&…...

电池大脑的基准测试及AI拓展

从为我们的智能手机供电到驱动电动汽车&#xff0c;我们的日常生活都离不开锂离子电池&#xff08;LIB&#xff09;。但是&#xff0c;理解其复杂的内部运作并预测其性能需要精密的工具。由此引入了多孔电极理论&#xff08;PET&#xff09;模型&#xff0c;我们可以将其视为模…...

数据通信学习笔记之OSPF的基础术语

Router ID RouterID 用于在自治系统中唯一标识一省运行 OSPF 的路由器&#xff0c;它是一个 32 位的无符号整数 配置完成后&#xff0c;如果需要修改 Router ID 的话&#xff0c;需要重启进程才能上生效 ​<Huawei>reset ospf 1 process​ // 重启 ospf 进程 1 Route…...

Android Cordova 开发 - Cordova 快速入门(Cordova 环境配置、Cordova 第一个应用程序)

一、Cordova 1、Cordova 概述 Cordova 是使用 HTML&#xff0c;CSS 和 JavaScript 构建混合移动应用程序的平台 2、Cordova 特征 &#xff08;1&#xff09;命令行界面&#xff08;Cordova CLI&#xff09; 这是可用于启动项目&#xff0c;构建不同平台的进程&#xff0c;…...

AndroidAutomotive模块介绍(四)VehicleHal介绍

前言 前面的文章中&#xff0c;描述了 Android Automotive 的框架中应用、Framework 层服务等知识&#xff0c;本篇文章将会继续按照 Android Automotive 框架介绍 Vehicle Hal 层服务的内容。 上一篇&#xff1a;AndroidAutomotive模块介绍&#xff08;三&#xff09;CarSer…...

Pingora vs. Nginx vs. 其他主流代理服务器性能对比

Pingora vs. Nginx vs. 其他主流代理服务器性能对比 核心对比概览 特性Pingora (Cloudflare)NginxEnvoyHAProxyCaddyTraefik开发公司CloudflareNginx, Inc/F5Lyft/CNCFHAProxy TechApache 2.0社区Containous核心语言RustCCCGoGo并发模型异步/多线程事件驱动事件驱动事件驱动协…...

4月23日作业

需求&#xff1a; 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址&#xff1b; R5与其他所有直连设备间均使用公有IP&#xff1b;环回地址为100.1.1.1/32 2&#xff0c;R4设备为企业出口路由器 3&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4&…...

5.学习笔记-SpringMVC(P53-P60)

1.响应 &#xff08;1&#xff09;响应页面 &#xff08;2&#xff09;响应数据&#xff08;异步提交&#xff09;&#xff1a;文本数据、json数据 2.REST风格 (1)REST:表现形式状态转换。 (2)传统风格资源描述形式 3.Restful入门案例 5.基于RESTful页面数据…...

安卓14默认赋予应用权限

安卓14上赋予应用默认权限的方式跟之前的不太一样了 需要修改两个地方&#xff0c;一个是frameworks\base\services\core\java\com\android\server\pm\permission\Permission.java public boolean isNormal() {//eturn (mPermissionInfo.protectionLevel & PermissionInfo…...

数据的加载与保存

加载数据的方法 选项参数&#xff1a;可以通过选项参数传入URL地址、用户名、密码和数据表名称等。 路径参数&#xff1a;可以传入加载数据的路径。 MySQL语句&#xff1a;可以直接导入MySQL语句来加载数据。 保存数据的方法通用方法&#xff1a;使用df.write方法保存数据。…...

网络编程——通信三要素

一、概述 &#xff08;一&#xff09;网络编程 可以让设备中的程序与网络上的其他设备中的程序进行数据交互&#xff0c;实现网络通信 Java.net包下提供了网络编程的解决方案。 &#xff08;二&#xff09;通信的基本架构 1. CS架构&#xff08;Client客户端/Server服务端…...

es-存储与搜索优化

字段选型优化 链接&#xff1a;es-字段类型详解与优化建议 存储优化 es的底层使用Lucene,Lucene的存储的核心文件包括&#xff1a; 原始数据存储&#xff08;Store&#xff09;、倒排索引&#xff08;Inverted Index&#xff09;、列式存储&#xff08;DocValues&#xff09…...

Hadoop 集群扩容新增节点操作文档

Hadoop 集群扩容新增节点操作文档 一、前期准备 1. 环境检查&#xff08;所有新节点&#xff09; 确保 JDK 安装&#xff1a; java -version确保 Hadoop 安装&#xff1a; hadoop version添加主机名映射&#xff08;所有节点&#xff09;&#xff1a; cat >> /etc/h…...

高光谱相机在工业检测中的应用:LED屏检、PCB板缺陷检测

随着工业检测精度要求的不断提升&#xff0c;传统机器视觉技术逐渐暴露出对非可见光物质特性识别不足、复杂缺陷检出率低等局限性。高光谱相机凭借其独特的光谱分析能力&#xff0c;为工业检测提供了革命性的解决方案。以下结合中达瑞和VIX系列推扫式高光谱相机的技术特点与实际…...

07-IDEA企业开发工具-开发入门程序

1. IDEA创建Java项目的代码结构 项目结构: IDEA中的Java项目包含四种主要结构&#xff1a;工程(Project)、模块(Module)、包(Package)、类(Class)。 工程(Project): 代表整个项目&#xff0c;通常是一个磁盘目录或文件夹。模块(Module): 工程下的子单元&#xff0c;用于划分项…...

即插即用模块(3) -LSK 特征提取

paper&#xff1a;LSKNet: A Foundation Lightweight Backbone for Remote Sensing Code&#xff1a;https://github.com/zcablii/LSKNet 大型选择性内核块 (LSK Block) 功能 通过动态调整感受野&#xff0c;自适应提取遥感图像中目标的上下文信息&#xff0c;增强目标与环境关…...

彩虹表攻击与Nest密码存储

文章目录 前言&#x1f9e8; 什么是彩虹表攻击&#xff1f;&#x1f4f7; 图中解析左侧是彩虹表&#xff1a;右侧是用户数据库中的数据&#xff1a; &#x1f510; 如何防御彩虹表攻击&#xff1f;✅ 1. **使用 Salt 加密&#xff08;推荐&#xff09;**✅ 2. **使用强哈希函数…...

vue keep-alive标签的运用

keep-alive&#xff0c;想必大家都不会很陌生&#xff0c;在一些选项卡中会使用到。其实&#xff0c;它的作用大概就是把组件的数据给缓存起来。 比如果我有一个选项卡&#xff0c;标签一&#xff0c;标签二&#xff0c;标签三。现在&#xff0c;我需要实现&#xff0c;当我在标…...

python编写一段爱心代码

代码编写 1. 导入模块和常量定义 python import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 480 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CANVAS_CENTER_Y CANVAS_HEIGH…...

Python流程控制

目录 一&#xff0c;条件判断&#xff1a;if语句 1.基本语法与示例 2.多重条件判断&#xff08;elif&#xff09; 3.常见错误与避坑指南 1.缩进错误 2.遗漏冒号 二&#xff0c;循环结构&#xff1a;while与for 1.while循环 2.Python的注释 3.字符串的格式化输出 4.fo…...

机器人雅克比Jacobian矩阵程序

% 定义机器人的连杆参数 L1 Link(d, 0, a, 0, alpha, pi/2); L2 Link(d, 0, a, 1, alpha, 0); L3 Link(d, 0, a, 1, alpha, 0);% 创建机器人对象 robot SerialLink([L1, L2, L3], name, MyRobot);% 设置机器人的关节角度&#xff08;弧度&#xff09; q [0, pi/4, pi/6];%…...