Ceph异地数据同步之-RBD异地同步复制(上)
#作者:闫乾苓
文章目录
- 前言
- 基于快照的模式(Snapshot-based Mode)
- 工作原理
- 单向同步配置步骤
- 单向同步复制测试
- 双向同步配置步骤
- 双向同步复制测试
前言
Ceph的RBD(RADOS Block Device)支持在两个Ceph集群之间进行异步镜像复制,提供了两种主要模式:基于日志(Journal-based)和基于快照(Snapshot-based)。这两种模式各有优缺点,适用于不同的场景和需求。
根据所需的复制需求,RBD 镜像可以配置为单向或双向复制:
- 单向复制:当数据仅从主群集镜像到辅助群集时,rbd-mirror守护进程仅在辅助群集上运行。
- 双向复制:当数据从一个集群上的主映像镜像到另一个集群上的非主映像(反之亦然)时, rbd-mirror守护进程在两个集群上运行。
基于快照的模式(Snapshot-based Mode)
工作原理
- 使用定期计划或手动创建的RBD镜像快照来进行集群间的复制。
- 远程集群会比较两个快照之间的数据或元数据更新,并将差异部分复制到其本地副本。
- 利用RBD的快速差异(fast-diff)功能,可以快速确定哪些数据块发生了变化,而无需扫描整个RBD镜像。
优点:
- 低延迟写入:不需要额外的日志记录,写操作不会显著增加延迟。
- 灵活性:可以根据需要手动创建快照或设置自动快照策略,灵活适应不同的业务需求。
缺点:
- 较粗粒度:与基于日志的模式相比,快照模式不够精细,需要同步完整的差异部分,而不是逐个写操作。
- 恢复时间较长:在故障切换时,如果部分差异未完全应用,则需要回滚到上一个完整快照状态,可能会导致更长的恢复时间。
适用场景:
对写性能要求较高且能接受一定延迟的应用,如文件存储、备份等。
单向同步配置步骤
- 在两个ceph集群上登录到cephadm shell
[root@ceph01 ~]# cephadm shell
[root@ceph-a ~]# cephadm shell
- 在site-b集群中ceph-b节点部署 rbd-mirror 守护进程
[ceph: root@ceph-a /]# ceph orch apply rbd-mirror ceph-b
Scheduled rbd-mirror update...
查看守护进程是否正常启动
[ceph: root@ceph-a /]# ceph orch ls |grep rbd-mirror
rbd-mirror 1/1 5m ago 4h ceph-b
- 在源集群site-a新建1个存储池名为data,并启用 RBD 应用程序,在池data中创建1个名为image1的image
[ceph: root@ceph01 /]# ceph osd pool create data
pool 'data' created
[ceph: root@ceph01 /]# ceph osd pool application enable data rbd
enabled application 'rbd' on pool 'data'
[ceph: root@ceph01 /]# rbd create --size 1024 data/image1
- 在目标集群site-b新建1个同名存储池data,并启用 RBD 应用程序,不用创建image
[ceph: root@ceph-a /]# ceph osd pool create data
pool 'data' created
[ceph: root@ceph-a /]# ceph osd pool application enable data rbd
enabled application 'rbd' on pool 'data'
- 在site-a,site-b两个存储集群中选择 mirroring 模式为image
[ceph: root@ceph01 /]# rbd mirror pool enable data image
[ceph: root@ceph-a /]# rbd mirror pool enable data image
- 验证两个集群都已成功启用了镜像模式为pool
[ceph: root@ceph01 /]# rbd mirror pool info data
Mode: image
Site Name: 0978cb18-dc68-11ef-b0d7-000c29460ffd
Peer Sites: none
[ceph: root@ceph-a /]# rbd mirror pool info data
Mode: image
Site Name: baedc6c0-e058-11ef-a23a-000c29cf8329
Peer Sites: none
- 在site-a集群创建 Ceph 用户帐户,并将存储集群对等注册到池,将 bootstrap 令牌文件复制到site-b存储集群。
[ceph: root@ceph01 /]# rbd mirror pool peer bootstrap create --site-name site-a data > /root/bootstrap_token_site-a
- 在site-b集群中导入bootstrap令牌
[ceph: root@ceph-a /]# rbd mirror pool peer bootstrap import --site-name site-b --direction rx-only data /root/bootstrap_token_site-a
注意:对于单向 RBD 镜像功能,必须使用–direction rx-only参数,因为在引导 对等时双向镜像是默认设置。
- 在site-a集群 data池中为需要同步的image启用镜像快照同步功能
[ceph: root@ceph01 /]# rbd mirror image enable data/image1 snapshot
Mirroring enabled
- site-a集群验证镜像同步复制状态
[ceph: root@ceph01 /]# rbd mirror image status data/image1
image1:global_id: 6f6c3690-df01-49dd-9508-f7c944fbcd9asnapshots:3 .mirror.primary.6f6c3690-df01-49dd-9508-f7c944fbcd9a.3da61eb1-7512-44c2-b4e9-8d6a987e1a9c (peer_uuids:[f9128159-df9f-43eb-be57-4f798da002cc])
- site-b集群验证镜像同步复制状态
[ceph: root@ceph-a /]# rbd mirror image status data/image1
image1:global_id: 6f6c3690-df01-49dd-9508-f7c944fbcd9astate: up+replayingdescription: replaying, {"bytes_per_second":0.0,"bytes_per_snapshot":0.0,"last_snapshot_bytes":0,"last_snapshot_sync_seconds":0,"local_snapshot_timestamp":1738897439,"remote_snapshot_timestamp":1738897439,"replay_state":"idle"}service: ceph-b.tglrho on ceph-blast_update: 2025-02-07 03:06:22
如果镜像处于up+replaying状态,表示可以正常工作。up表示rbd-mirror守护进程正在运行,replaying表示此镜像是从另一个存储集群复制的目标。
单向同步复制测试
在同一个client端服务器映射及挂载2个集群的rbd image, 在源集群site-a写入测试数据,手动触发快照,查看数据是否同步到目标集群site-b的同名池。
- 准备两个集群的conf,keyring文件
将cephadm shell 所在容器中/etc/ceph/下的conf,keyring文件复制到client服务器/etc/ceph目录并修改文件名字以示区别。
[ceph: root@ceph01 /]# ls -l /etc/ceph/
-rw------- 1 ceph ceph 323 Jan 27 05:48 ceph.conf
-rw------- 1 root root 151 Feb 7 02:35 ceph.keyring[root@cilent ~]# ll /etc/ceph/
-rw-r--r--. 1 root root 92 10月 18 2023 rbdmap
-rw-r--r-- 1 root root 186 2月 5 19:14 site-a.client.admin.keyring
-rw-r--r-- 1 root root 304 2月 5 19:13 site-a.conf
-rw-r--r-- 1 root root 186 2月 5 19:20 site-a.keyring
-rw-r--r-- 1 root root 186 2月 5 19:15 site-b.client.admin.keyring
-rw-r--r-- 1 root root 337 2月 5 19:13 site-b.conf
- 使用rbd map 映射源集群site-a中data/image到client本地dev设备
[root@cilent ~]# rbd map image1 --pool data -c /etc/ceph/site-a.conf -k /etc/ceph/site-a.client.admin.keyring
/dev/rbd0[root@cilent ~]# lsblk |grep rbd0
rbd0 252:0 0 1G 0 disk
- 将rbd0格式化并mount到目录
[root@cilent mnt]# mkfs.xfs /dev/rbd0
Discarding blocks...Done.
[root@cilent mnt]# mkdir site-a site-b
[root@cilent mnt]# ll
drwxr-xr-x 2 root root 4096 2月 7 11:41 site-a
drwxr-xr-x 2 root root 4096 2月 7 11:41 site-b
[root@cilent mnt]# mount /dev/rbd0 /mnt/site-a
[root@cilent mnt]# df -h |grep site-a
/dev/rbd0 1014M 40M 975M 4% /mnt/site-a
- 在挂载点/mnt/site-a 使用dd写入2个100M大小的测试文件
[root@cilent mnt]# dd if=/dev/zero of=/mnt/site-a/100M-$(date +%F_%H%M%S) bs=1M count=100
[root@cilent mnt]# tree
.
├── site-a
│ ├── 100M-2025-02-07_114953
│ └── 100M-2025-02-07_115007
└── site-b
在没同步前查看两个集群data pool的磁盘使用信息
- 在源集群site-a中手动为data/image1创建快照
[ceph: root@ceph01 /]# rbd mirror image snapshot data/image1
Snapshot ID: 4
- 在site-b集群查看同步信息已更新
- 在client服务器将site-a集群rbd image取消挂载,删除map映射,
[root@cilent mnt]# umount /mnt/site-a
[root@cilent mnt]# rbd unmap image1 --pool data -c /etc/ceph/site-a.conf -k /etc/ceph/site-a.client.admin.keyring[root@cilent mnt]# tree
.
├── site-a
└── site-b
- 在site-a集群将data/image1降级为非主image
[ceph: root@ceph01 /]# rbd mirror image demote data/image1
Image demoted to non-primary
在site-b集群将data/image1提升为主image
[ceph: root@ceph-a /]# rbd mirror image promote data/image1
Image promoted to primary
- site-b集群map映射及挂载rbd image并查看数据是否同步
[root@cilent mnt]# rbd map image1 --pool data -c /etc/ceph/site-b.conf -k /etc/ceph/site-b.client.admin.keyring/dev/rbd0[root@cilent mnt]# lsblk |grep rbd
rbd0 252:0 0 1G 0 disk
数据已同步
[root@cilent mnt]# mount /dev/rbd0 /mnt/site-b/
[root@cilent mnt]# tree
.
├── site-a
└── site-b├── 100M-2025-02-07_114953└── 100M-2025-02-07_115007
- 此时rab map不能映射site-a集群的data/image,因为已降级为非主,因只有主镜像有写权限,以避免数据冲突。
11. 在client服务器上取消挂载及site-b集群的data/image的映射。
[root@cilent mnt]# umount /mnt/site-b/
[root@cilent mnt]# rbd unmap image1 --pool data -c /etc/ceph/site-b.conf -k /etc/ceph/site-b.client.admin.keyring
- 在site-b集群将data/image降级为非主image
[ceph: root@ceph-a /]# rbd mirror image demote data/image1
Image demoted to non-primary
13.在site-a集群将data/image提升为主image
[ceph: root@ceph01 /]# rbd mirror image promote data/image1
Image promoted to primary
14.在site-b集群查看镜像同步状态,此时为split-brain(脑裂)状态
- 在site-b集群请求到site-a源镜像的重新同步
[ceph: root@ceph-a /]# rbd mirror image resync data/image1
Flagged image for resync from primary
Site-b同步状态过程如下:
[ceph: root@ceph-a /]# rbd mirror image status data/image1
rbd: error opening image image1: (2) No such file or directory[ceph: root@ceph-a /]# rbd mirror image status data/image1
image1:global_id: 6f6c3690-df01-49dd-9508-f7c944fbcd9astate: down+unknowndescription: status not foundlast_update:
此时恢复正常同步状态
[ceph: root@ceph-a /]# rbd mirror image status data/image1
image1:global_id: 6f6c3690-df01-49dd-9508-f7c944fbcd9astate: up+replayingdescription: replaying, {"bytes_per_second":10615398.4,"bytes_per_snapshot":106153984.0,"last_snapshot_bytes":0,"last_snapshot_sync_seconds":0,"local_snapshot_timestamp":1738909767,"remote_snapshot_timestamp":1738909767,"replay_state":"idle"}service: ceph-b.tglrho on ceph-blast_update: 2025-02-07 06:38:22
- 设置镜像快照定时策略
使用基于快照的镜像时,每当需要镜像 RBD 映像的更改内容时,都需要创建镜像快照。
默认情况下,每个image映像最多可创建5个快照。如果达到限制,则会自动删除最新的镜像快照。如果需要,可以通过配置选项覆盖该限制rbd_mirroring_max_mirroring_snapshots 。此外,当删除映像或禁用镜像时,会自动删除镜像快照。
可自定义了镜像快照计划,用于定期自动创建镜像快照。
镜像快照可以全局、按池或按映像级别进行安排。可以在任何级别定义多个镜像快照计划,但只有与单个镜像匹配的最具体的快照计划才会运行。
可以分别使用d、h、m、start-time后缀以天、小时或分钟为单位指定。
rbd mirror snapshot schedule add [--pool {pool-name}] [--image {image-name}] {interval} [{start-time}]
比如:在site-a集群中对data池下的image1制定每分钟创建1个快照的策略。
[ceph: root@ceph01 /]# rbd mirror snapshot schedule add --pool data --image image1 1m
[ceph: root@ceph01 /]# rbd mirror snapshot schedule ls --pool data --recursive
POOL NAMESPACE IMAGE SCHEDULE
data image1 every 1m
双向同步配置步骤
双向同步并非双向实时同步,只是在单向同步的基础上通过在源集群也部署rbd-mirror守护进程,在出现故障时,通过手动切换集群镜像的主辅角色,实现快速可以反向同步。
- 在两个ceph集群上登录到cephadm shell
[root@ceph01 ~]# cephadm shell
[root@ceph-a ~]# cephadm shell
- 在site-a集群中ceph02节点部署 rbd-mirror 守护进程
[ceph: root@ceph01 /]# ceph orch apply rbd-mirror ceph02
Scheduled rbd-mirror update...
在site-b集群中ceph-b节点部署 rbd-mirror 守护进程
[ceph: root@ceph-a /]# ceph orch apply rbd-mirror ceph-b
Scheduled rbd-mirror update...
查看守护进程是否正常启动
[ceph: root@ceph01 /]# ceph orch ls|grep rbd
rbd-mirror 1/1 8s ago 20s ceph02[ceph: root@ceph-a /]# ceph orch ls |grep rbd
rbd-mirror 1/1 14s ago 24s ceph-b
- 在源集群site-a新建1个存储池名为data,并启用 RBD 应用程序,在池data中创建1个名为image1的image
[ceph: root@ceph01 /]# ceph osd pool create data
pool 'data' created
[ceph: root@ceph01 /]# ceph osd pool application enable data rbd
enabled application 'rbd' on pool 'data'
[ceph: root@ceph01 /]# rbd create --size 1024 data/image1
查看创建的image的信息
- 在目标集群site-b新建1个同名存储池data,并启用 RBD 应用程序,不用创建image
[ceph: root@ceph-a /]# ceph osd pool create data
pool 'data' created
[ceph: root@ceph-a /]# ceph osd pool application enable data rbd
enabled application 'rbd' on pool 'data'
- 在site-a,site-b两个存储集群中选择 mirroring 模式为image
[ceph: root@ceph01 /]# rbd mirror pool enable data image
[ceph: root@ceph-a /]# rbd mirror pool enable data image
- 验证两个集群都已成功启用了镜像模式为pool
[ceph: root@ceph01 /]# rbd mirror pool info data
Mode: image
Site Name: 0978cb18-dc68-11ef-b0d7-000c29460ffd
Peer Sites: none [ceph: root@ceph-a /]# rbd mirror pool info data
Mode: image
Site Name: baedc6c0-e058-11ef-a23a-000c29cf8329
Peer Sites: none
- 在site-a集群创建 Ceph 用户帐户,并将存储集群对等注册到池,将 bootstrap 令牌文件复制到site-b存储集群。
[ceph: root@ceph01 /]# rbd mirror pool peer bootstrap create --site-name site-a data > /root/bootstrap_token_site-a
- 在site-b集群中导入bootstrap令牌
[ceph: root@ceph-a /]# rbd mirror pool peer bootstrap import --site-name site-b data /root/bootstrap_token_site-a
- 在site-a集群 data池中为需要同步的image启用镜像快照同步功能
[ceph: root@ceph01 /]# rbd mirror image enable data/image1 snapshot
Mirroring enabled
- site-a集群验证镜像同步复制状态
[ceph: root@ceph01 /]# rbd mirror image status data/image1
up 表示 rbd-mirror 守护进程正在运行,stopped 意味着此镜像不是从另一个存储集群复制的目标。这是因为镜像是这个存储集群的主要部分
peer_sites 显示了对等节点(site-b)的状态为up+replaying
说明此时的同步方向为site-a site-b
- site-b集群验证镜像同步复制状态
[ceph: root@ceph-a /]# rbd mirror image status data/image1
如果镜像处于up+replaying状态,表示可以正常工作。up表示rbd-mirror守护进程正在运行,replaying表示此镜像是从另一个存储集群复制的目标。
peer_sites 显示了对等节点的状态为up+stopped
双向同步复制测试
- 在client服务器端映射site-a集群的data池的image1,格式化并mount到挂载点目录。
[root@cilent mnt]# rbd map image1 --pool data -c /etc/ceph/site-a.conf -k /etc/ceph/site-a.client.admin.keyring
/dev/rbd0
[root@cilent mnt]# mkfs.xfs /dev/rbd0
[root@cilent mnt]# mount /dev/rbd0 /mnt/site-a
- dd写入1个100M的文件进行测试
[root@cilent site-a]# dd if=/dev/zero of=100M-$(date +%F_%H%M%S) bs=1M count=100
[root@cilent site-a]# tree /mnt/
/mnt/
├── site-a
│ └── 100M-2025-02-07_174949
└── site-b
- site-a集群为data/image1手动创建快照,查看是否同步到site-b集群
[ceph: root@ceph01 /]# rbd mirror image snapshot data/image1
Snapshot ID: 4
[ceph: root@ceph01 /]# rbd mirror image status data/image1
(4)查看两个集群data/image1的信息
[ceph: root@ceph01 /]# rbd --image data/image1 info
- 模拟site-a集群故障,手动将site-a data/image1降级为非主image
[ceph: root@ceph01 /]# rbd mirror image demote data/image1
Image demoted to non-primary
此时site-a集群的date/image1高级特性自动被设置为non-primary
- 手动将site-b data/image1提升为主image,如果因为site-a集群已经宕机,降级无法传播到site-a存储集群,可以使用 --force 选项
[ceph: root@ceph-a /]# rbd mirror image promote data/image1
Image promoted to primary
此时site-b集群的date/image1高级特性non-primary被取消,允许客户端进行挂载写入数据。
- client服务器端取消site-a集群data/image1的挂载和映射,改为site-b集群data/image1的挂载和映射.
[root@cilent ~]# umount /mnt/site-a
[root@cilent ~]# rbd unmap image1 --pool data -c /etc/ceph/site-a.conf -k /etc/ceph/site-a.client.admin.keyring[root@cilent ~]# rbd map image1 --pool data -c /etc/ceph/site-b.conf -k /etc/ceph/site-b.client.admin.keyring
/dev/rbd0
[root@cilent ~]# mount /dev/rbd0 /mnt/site-b
查看之前的数据同步
[root@cilent ~]# tree /mnt/
/mnt/
├── site-a
└── site-b└── 100M-2025-02-07_174949
- 再查看2个集群的同步状态
site-a集群的因为也部署了rbd-mirror守护程序,data/image1在被降级为非主镜像后,自动与设置过对等关系的site-b集群进行同步(up+replaying)。
site-b集群的data/image1因为被提升为主镜像,所以其状态为up+stopped
- 在site-b集群的data/image1的挂载目录写入测试数据并手动创建快照,观察同步情况。
[root@cilent ~]# cd /mnt/site-b/
[root@cilent site-b]# dd if=/dev/zero of=100M-$(date +%F_%H%M%S) bs=1M count=100
[root@cilent site-b]# tree /mnt/
/mnt/
├── site-a
└── site-b├── 100M-2025-02-07_174949└── 100M-2025-02-07_183332[ceph: root@ceph-a /]# rbd mirror image snapshot data/image1
Snapshot ID: 7
- 如果site-b恢复正常,可以再将主镜像切换回来。
先降级site-b集群的data/image1
[ceph: root@ceph-a /]# rbd mirror image demote data/image1
Image demoted to non-primary
再提升site-a集群的data/image1
[ceph: root@ceph01 /]# rbd mirror image promote data/image1
Image promoted to primary
等待片刻,查看两集群同步状态已恢复原始状态。
(11) client服务器上重新挂载site-a集群的data/image1,并查看数据是否正常。
[root@cilent ~]# umount /mnt/site-b/
[root@cilent ~]# rbd unmap image1 --pool data -c /etc/ceph/site-b.conf -k /etc/ceph/site-b.client.admin.keyring[root@cilent ~]# rbd map image1 --pool data -c /etc/ceph/site-a.conf -k /etc/ceph/site-a.client.admin.keyring
/dev/rbd0[root@cilent ~]# rbd showmapped -c /etc/ceph/site-b.conf -k /etc/ceph/site-b.client.admin.keyring
id pool namespace image snap device
0 data image1 - /dev/rbd0[root@cilent ~]# mount /dev/rbd0 /mnt/site-b
[root@cilent ~]# tree /mnt/
/mnt/
├── site-a
└── site-b├── 100M-2025-02-07_174949└── 100M-2025-02-07_183332
相关文章:
Ceph异地数据同步之-RBD异地同步复制(上)
#作者:闫乾苓 文章目录 前言基于快照的模式(Snapshot-based Mode)工作原理单向同步配置步骤单向同步复制测试双向同步配置步骤双向同步复制测试 前言 Ceph的RBD(RADOS Block Device)支持在两个Ceph集群之间进行异步镜…...
fastapi完全离线环境(无外网)的访问Swagger所做特殊处理
在互联网环境中,只要 启动FastAPI 服务运行在本地机器上,访问 http://localhost:8000/docs(Swagger UI)就可以访问到Swagger界面,但是在完全离线环境(无外网)下如何访问Swagger页面呢࿱…...
在网络中加入预训练的多层感知机(MLP)有什么作用?
在网络中加入预训练的多层感知机(MLP)通常是为了引入先验知识、提升特征表示能力或dropout,具体作用取决于MLP的设计和预训练任务。以下是常见的应用场景和优势: 1. 特征融合与迁移学习:预训练的MLP可以作为特征提取器࿰…...
3.2/Q2,GBD数据库最新文章解读
文章题目:Temporal trends in the burden of vertebral fractures caused by falls in China and globally from 1990 to 2021: a systematic analysis of the Global Burden of Disease Study 2021 DOI:10.1186/s13690-025-01500-y 中文标题:…...
机器学习的一百个概念(9)学习曲线
前言 本文隶属于专栏《机器学习的一百个概念》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…...
浅谈Tomcat数据源连接池
目录 为什么需要JDBC连接池 Tomcat JDBC Pool 相关参数 1. 基本配置 2. 连接池大小控制 3. 连接验证与测试 4. 空闲连接回收 5. 连接泄漏与超时 Tomcat JDBC Pool 源码分析(tomcat 8.5.3) DataSourceFactory DataSource ConnectionPool Pool…...
Techub 财报解读:Circle 冲刺 IPO,但收入增长难掩利润困局
作者:Techub 财报解读 撰文:Yangz,Techub News 4 月 1 日,Circle 向美国证券交易委员会(SEC)提交 S-1 文件,计划进行首次公开募股(IPO),股票代码为 CRCL&…...
C++中的链表操作
在C中,链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。C标准库(STL)中提供了std::list和std::forward_list两种链表实现,分别对应双向链表和单向链表。此外&am…...
Vue2 生命周期
文章目录 前言🔄 Vue2 生命周期流程(8个核心钩子)📝 代码中典型用法示例一、您的描述验证二、完整生命周期代码示例三、关键阶段行为说明🔍 常见问题 前言 提示:以下是本篇文章正文内容,下面案…...
2007-2022年 上市公司政府补助数据 -社科数据
上市公司政府补助数据(2007-2022年)-社科数据https://download.csdn.net/download/paofuluolijiang/90028547 https://download.csdn.net/download/paofuluolijiang/90028547 政府补助是指政府为支持企业发展,提供的资金或资源支持。对于上市…...
设计心得——状态机
一、状态机 在设计一些与硬件交互或者游戏等开发中,经常会听到状态机(State Machines)这个字眼,而在设计模式(GoF)中,又经常听到状态模式这个概念,它们之间有什么联系和不同呢&…...
python match case语法
学习路线:B站 普通的if判断 def if_traffic_light(color):if color red:return Stopelif color yellow:return Slow downelif color green:return Goelse:return Invalid colorprint(if_traffic_light(red)) # Output: Stop print(if_traffic_light(yellow)) …...
Lua中协程相关函数使用详解
目录 1. coroutine.create(f)2. coroutine.resume(co [, val1, ...])3. coroutine.yield([val1, ...])4. coroutine.status(co)5. coroutine.wrap(f)6. coroutine.running()7. coroutine.isyieldable()协程状态转换示例总结 Lua 中的协程(coroutine)提供…...
代码拟有感
最近的日子像被按了0.5倍速播放键。腱鞘炎让手腕转动时发出咯吱声,尾骨的钝痛让久坐变成酷刑,落枕的脖子和酸胀的手臂组成了“疼痛交响乐”——这些隐秘的、持续的身体抗议,让原本枯燥的代码练习变成了一场生理与意志的拉锯战。 我盯着屏幕苦…...
《实战AI智能体》MCP对Agent有哪些好处
首先MCP为Agent提供了标准化的方式来接入各种工具和数据源,无论是本地运行的工具,例如通过stdio服务器,还是远程托管的服务HTTP over SSE服务, Agent都可以通过统一的接口与它们进行交互,极大扩展了第三方工具库。 例如,在金融领域,Agent 可以接入股票分析的MCP工具。当…...
maptalks获取所有图层并把图层按照zIndex排序
maptalks获取所有图层并把图层按照zIndex排序 获取所有图层 通过调用 map.getLayers() 可以返回当前地图上所有的图层集合。此方法会返回一个数组形式的结果,其中包含了地图上的每一个图层层级对象。 图层属性中的 ZINDEX 每种图层类型(如矢量图层、…...
GUI-Guider 按钮按下 选项卡 右移动一个,到最右边停下
extern lv_ui guider_ui; // 在文件顶部添加// 在按钮事件中使用: lv_obj_t * tabview guider_ui.screen_tabview_1; // 替换为你的实际 TabView 名称 uint16_t current lv_tabview_get_tab_act(tabview); lv_tabview_set_act(tabview, current 1, LV_ANIM_ON); …...
让AI再次伟大-MCP-Client开发指南
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理、AI应用🔥如果感觉…...
sql工具怎么选?
为什么大多数主流工具又贵又难用? 有没有一款免费好用的sql工具? 像大多人朋友常用的sql工具,应该都遇到过这种情况, 用着用着收到了来自品牌方的律师函, 或者处理数据经常卡死, 再或者不支持国产数据库…...
video标签播放mp4格式视频只有声音没有图像的问题
video标签播放mp4格式视频只有声音没有图像的问题 这是由于视频格式是hevc(H265)编码的,这种编码格式视频video播放有问题主要是由于以下两种原因导致的: 1、浏览器没有开启硬加速模式: 开启方法(以谷歌浏览器为例)&a…...
问题解决:glog中的LOG(INFO)与VLOG无法打印
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 MotivationProcess glog版本为:https://github.com/google/glog/archive/…...
【第2月 day16】Matplotlib 散点图与柱状图
好的!以下是针对初学者的 Matplotlib 散点图与柱状图 学习内容,用简单易懂的语言和示例讲解: 一、散点图(Scatter Plot) 作用:展示两个变量之间的关系(如相关性、分布等)。 1. 核心…...
汽车 HMI 设计的发展趋势与设计要点
一、汽车HMI设计的发展历程与现状 汽车人机交互界面(HMI)设计经历了从简单到复杂、从单一到多元的演变过程。2012年以前,汽车HMI主要依赖物理按键进行操作,交互方式较为单一。随着特斯拉Model S的推出,触控屏逐渐成为…...
Vue 3 中按照某个字段将数组分成多个数组
方法一:使用 reduce 方法 const originalArray [{ id: 1, category: A, name: Item 1 },{ id: 2, category: B, name: Item 2 },{ id: 3, category: A, name: Item 3 },{ id: 4, category: C, name: Item 4 },{ id: 5, category: B, name: Item 5 }, ];const grou…...
06-Spring 中的事件驱动机制
Spring 中的事件驱动机制(ApplicationEvent 源码解析) 本小结主要总结Spring的事件,如果对于观察者模式比较熟悉的话,理解这个应该不难。 这块涉及的面试题相对简单,主要还是以日常使用为主。 另外在Spring的源码中也运…...
Python学习笔记(8)关于列表内置函数和多维列表
列表访问计数 索引直接访问 index()#获得首次出现指定元素的索引 index(value,[start,[end]] #控制搜索索引范围 counr()#获得指定元素在列表中出现的次数 len()#返回列表长度 成员资格判断 incount()返回0,代表不存在 列表切片 slice[起始偏移量 start:终止…...
【算法学习计划】回溯 -- 递归
目录 leetcode 面试题08.06.汉诺塔问题 leetcode 21.合并两个有序链表 leetcode 206.反转链表 leetcode 24.两两交换链表中的节点 leetcode 50. Pow(x, n) 本篇文章将是我们回溯专题的第一篇文章,在这里我先浅浅讲一下什么是回溯 其实就是递归,只不…...
Unity中 JobSystem使用整理
Unity 的JobSystem允许创建多线程代码,以便应用程序可以使用所有可用的 CPU 内核来执行代码,这提供了更高的性能,因为您的应用程序可以更高效地使用运行它的所有 CPU 内核的容量,而不是在一个 CPU 内核上运行所有代码。 可以单独使…...
【从零实现Json-Rpc框架】- 项目实现 - 服务端主题实现及整体封装
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
JavaScript基础-移动端常用开发框架
随着移动互联网的发展,越来越多的应用和服务需要支持移动设备。为了提高开发效率和用户体验,开发者们依赖于一些成熟的JavaScript框架来构建响应迅速、功能丰富的移动Web应用。本文将介绍几款广泛使用的移动端开发框架,并通过具体的示例展示它…...
Tree - Shaking
Vue 3 的 Tree - Shaking 技术详解 Tree - Shaking 是一种在打包时移除未使用代码的优化技术,在 Vue 3 中,Tree - Shaking 发挥了重要作用,有效减少了打包后的代码体积,提高了应用的加载性能。以下是对 Vue 3 中 Tree - Shaking …...
VSCode历史版本的下载安装
VSCode历史版本的下载安装 文章目录 VSCode历史版本的下载安装VSCode安装下载历史版本地址查询VSCode历史版本的 commit id 安装参考资料 VSCode安装 Windows版本:Windows10VSCode版本:VScode1.65.0(64位User版本)本文编写时间&a…...
Websoft9分享:在数字化转型中选择开源软件可能遇到的难题
引言:中小企业数字化转型的必由之路 全球94.57%的企业已采用开源软件(数据来源:OpenLogic 2024报告),开源生态估值达8.8万亿美元。中小企业通过开源软件构建EPR系统、企业官网、数据分析平台等,可节省80%软件采购成本。…...
【无人机】无人机PX4飞控系统高级软件架构
目录 1、概述(图解) 一、数据存储层(Storage) 二、外部通信层(External Connectivity) 三、核心通信枢纽(Message Bus) 四、硬件驱动层(Drivers) 五、飞…...
新版本Xmind结合DeepSeek快速生成美丽的思维导图
前言 我的上一篇博客(https://quickrubber.blog.csdn.net/article/details/146518898)中讲到采用Python编程可以实现和Xmind的互动,并让DeepSeek来生成相应的代码从而实现对内容的任意修改。但是,那篇博客中提到的Xmind有版本的限…...
Windows查重工具,强烈推荐大家收藏!
我大家在用电脑的时候,是不是发现用得越久,电脑里的软件和文件就越多? 今天我给大家带来的这两款重复文件查找神器,简直就是电脑里的“清洁小能手”,能帮你把那些重复的文件和文件夹找出来。 Easy DupLicate Finder 重…...
数字孪生技术之争:UE、Unity还是飞渡DTS数字孪生平台?
作为深耕数字孪生内容创作的B站UP主,我们创作的内容广受数十万粉丝喜爱。后台私信经常提及两个问题:“这质感绝了!如此丝滑流畅是UE做的吗?”VS “请问用Unity能实现这个效果吗?” Unreal Engine凭借影视级渲染&#…...
【GCC警告报错4】warning: format not a string literal and no format arguments
文章主本文根据笔者个人工作/学习经验整理而成,如有错误请留言。 文章为付费内容,已加入原创保护,禁止私自转载。 文章发布于:《C语言编译报错&警告合集》 如图所示: 原因: snprintf的函数原型&#x…...
【Tauri2】013——前端Window Event与创建Window
前言 【Tauri2】012——on_window_event函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146909801?spm1001.2014.3001.5501 前面介绍了on_window_event,这个在Builder中的方法,里面有许多事件,比如Moved,Res…...
修复SSL证书链不完整问题certificate verify failed unable to get local issuer certificate
文章目录 前言排查过程怀疑文章平台图片转存问题尝试使用 Python 代码下载图片使用 SSL Labs Server Test 验证猜想回顾 SSL 安装命令ACME 生成的证书 验证使用 [SSL Labs Server Test](https://www.ssllabs.com/ssltest/index.html) 验证文章发布平台转存验证 个人简介 前言 …...
管家婆财贸ERP BB102.采购销售订金管理
低适用版本: 财贸系列 23.8 插件简要功能说明: 采购订单/销售订单支持查询订金付款情况,联查下游付款/收款信息更多细节描述见下方详细文档 插件操作视频: 进销存类定制插件--采购销售订金管理 插件详细功能文档: …...
前端对接下载文件接口、对接dart app
嵌套在dart app里面的前端项目 1.前端调下载接口 ->后端返回 application/pdf格式的文件 ->前端将pdf处理为blob ->blob转base64 ->调用dart app的 sdk saveFile ->保存成功 async download() {try {// 调用封装的 downloadEContract 方法获取 Blob 数据const …...
牛客 简写单词
简写单词_牛客题霸_牛客网 主要是如何输入 #include <iostream> #include <string>using namespace std;int main() {string str;while(cin>>str){if(str[0]>a&&str[0]<z){cout<<char(str[0]-32);}else cout<<str[0];str.clear(…...
解决STM32CubeMX中文注释乱码
本人采用【修改系统环境变量】的方法 1. 使用快捷键 win X,打开【系统R】,点击【高级系统设置】 2. 点击【环境变量】 3. 点击【新建】 4.按图中输入【JAVA_TOOL_OPTIONS】和【-Dfile.encodingUTF-8】,新建环境变量后重启CubeMX即可。 解释…...
若依——基于AI+若依框架的实战项目(实战篇(下))
目录 前言 6. 设备管理 6.1 需求说明 6.2 生成基础代码 6.2.1 需求 6.2.2 步骤 ①创建目录菜单 ②添加数据字典 ③配置代码生成信息 ④下载代码并导入项目 6.3 设备类型改造 6.3.1 基础页面 需求 代码实现 6.4 设备管理改造 6.4.1 基础页面 需求 代码实现 …...
SpringBoot项目瘦身指南:从臃肿到高效的优化实践
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、问题背景 SpringBoot的"约定优于配置"特性极大提升了开发效率,但默认配置可能导致项目逐渐臃肿。典型的症状包括: 打…...
运筹帷幄:制胜软件开发
运筹学在软件开发项目中的作用主要体现在复杂系统建模、资源优化和决策支持中。通过数学建模、算法设计和数据分析,运筹学能够帮助开发团队更高效地实现软件需求,尤其是在涉及资源分配、路径规划、调度优化等场景时。 案例:电商物流配送系统的…...
代码随想录|动态规划|18完全背包理论基础
leetcode:52. 携带研究材料(第七期模拟笔试) 题目 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些…...
52.个人健康管理系统小程序(基于springbootvue)
目录 1.系统的受众说明 2.开发环境与技术 2.1 MYSQL数据库 2.2 Java语言 2.3 微信小程序技术 2.4 SpringBoot框架 2.5 B/S架构 2.6 Tomcat 介绍 2.7 HTML简介 2.8 MyEclipse开发工具 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作…...
大语言模型中的嵌入模型
本教程将拆解什么是嵌入模型、为什么它们在NLP中如此重要,并提供一个简单的Python实战示例。 分词器将原始文本转换为token和ID,而嵌入模型则将这些ID映射为密集向量表示。二者合力为LLMs的语义理解提供动力。图片来源:[https://tzamtzis.gr/2024/coding/tokenization-by-an…...