【Redis高级-集群分片】
单机安装Redis
首先需要安装Redis所需要的依赖:
yum install -y gcc tclRedis安装包上传到虚拟机的任意目录:
我放到了/tmp目录:
解压缩:
tar -zxvf /tmp/redis-6.2.4.tar.gz -C /tmp解压后:

进入redis目录:
cd /tmp/redis-6.2.4/运行编译命令:
make && make install如果没有出错,应该就安装成功了。
然后修改redis.conf文件中的一些配置:
vim /tmp/redis-6.2.4/redis.conf# 绑定地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问
bind 0.0.0.0启动Redis:
redis-server /tmp/redis-6.2.4/redis.conf停止redis服务:
redis-cli shutdownRedis主从集群
集群结构
我们搭建的主从集群结构如图:

共包含三个节点,一个主节点,两个从节点。
这里我们会在同一台虚拟机中开启3个redis实例,模拟主从集群,信息如下:
IP | PORT | 角色 |
192.168.136.130 | 7001 | master |
192.168.136.130 | 7002 | slave |
192.168.136.130 | 7003 | slave |
准备实例和配置
要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。
1)创建目录
我们创建三个文件夹,名字分别叫7001、7002、7003:
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003如图:

2)恢复原始配置(跳过)
修改redis-6.2.4/redis.conf文件,将其中的持久化模式改为默认的RDB模式,AOF保持关闭状态。
# 开启RDB
# save ""
save 3600 1
save 300 100
save 60 10000# 关闭AOF
appendonly no3)拷贝配置文件到每个实例目录
然后将redis-6.2.4/redis.conf文件拷贝到三个目录中(在/tmp目录执行下列命令):
# 进入/tmp目录
cd /tmp# 方式一:逐个拷贝
cp redis-6.2.4/redis.conf 7001
cp redis-6.2.4/redis.conf 7002
cp redis-6.2.4/redis.conf 7003# 方式二:管道组合命令,一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp redis-6.2.4/redis.confxargs:用来读取标准输入和管道中的数据
默认以空格、Tab制表符、回车符为分隔符和结束符
-n 指一次性读取几个参数
-t 表示先打印命令,然后再执行
-I{} 指定要替换的字符串
4)修改每个实例的端口、工作目录
修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(在/tmp目录执行下列命令):
# 进入/tmp目录
cd /tmpsed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.confsed:利用脚本来处理文本文件
选项:
-i 直接修改读取的文件内容
-e 执行后面的命令
动作:
s 查询替代
g 全局
数字代表操作的行数
a 在当前行的新建一行插入跟着的字符串
5)修改每个实例的声明IP
虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:
# redis实例的声明 IP
replica-announce-ip 192.168.136.130每个目录都要改,我们一键完成修改(在/tmp目录执行下列命令):
# 进入/tmp目录
cd /tmp# 逐一执行
sed -i '1a replica-announce-ip 192.168.136.130' 7001/redis.conf
sed -i '1a replica-announce-ip 192.168.136.130' 7002/redis.conf
sed -i '1a replica-announce-ip 192.168.136.130' 7003/redis.conf# 或者一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.136.130' {}/redis.conf启动
为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:
# 第1个
redis-server /tmp/7001/redis.conf
# 第2个
redis-server /tmp/7002/redis.conf
# 第3个
redis-server /tmp/7003/redis.conf启动后:

如果要一键停止,可以运行下面命令:
printf '%s\n' 7001 7002 7003 | xargs -I{} -t redis-cli -p {} shutdown开启主从关系
现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。
有临时和永久两种模式:
修改配置文件(永久生效)
在redis.conf中添加一行配置:slaveof <masterip> <masterport>
使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):
slaveof <masterip> <masterport>注意 :在5.0以后新增命令replicaof,与salveof效果一致。
这里我们为了演示方便,使用方式二。
通过redis-cli命令连接7002,执行下面命令:
# 连接 7002
redis-cli -p 7002
# 执行slaveof
replicaof 192.168.136.130 7001通过redis-cli命令连接7003,执行下面命令:
# 连接 7003
redis-cli -p 7003
# 执行slaveof
replicaof 192.168.136.130 7001然后连接 7001节点,查看集群状态:
# 连接 7001
redis-cli -p 7001
# 查看状态
info replication结果:

测试
执行下列操作以测试:
利用redis-cli连接7001,执行set num 123
利用redis-cli连接7002,执行get num,再执行set num 666
利用redis-cli连接7003,执行get num,再执行set num 888
可以发现,只有在7001这个master节点上可以执行写操作,7002和7003这两个slave节点只能执行读操作。
搭建哨兵集群
集群结构
这里我们搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群。如图:

三个sentinel实例信息如下:
节点 | IP | PORT |
s1 | 192.168.136.130 | 27001 |
s2 | 192.168.136.130 | 27002 |
s3 | 192.168.136.130 | 27003 |
准备实例和配置
要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。
我们创建三个文件夹,名字分别叫s1、s2、s3:
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir s1 s2 s3如图:

然后我们在s1目录创建一个sentinel.conf文件
cd s1
vim sentinel.conf添加下面的内容(按下 i):
port 27001
sentinel announce-ip 192.168.136.130
sentinel monitor mymaster 192.168.136.130 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"添加完成后保存退出
esc 退出
:wq 保存
解读:
port 27001:是当前sentinel实例的端口
sentinel monitor mymaster 192.168.136.130 7001 2:指定主节点信息
mymaster:主节点名称,自定义,任意写
192.168.136.130 7001:主节点的ip和端口
2:判断主节点客观下线的哨兵数量阈值
sentinel down-after-milliseconds: 配置对主节点、从节点和哨兵节点的主观下线的时间,默认30s
sentinel failover-timeout:设置故障转移每个阶段的超时时间,默认180s,如果超时,则下次该值会变为原来的2倍
然后将s1/sentinel.conf文件拷贝到s2、s3两个目录中(在/tmp目录执行下列命令):
# 进入/tmp目录
cd /tmp# 方式一:逐个拷贝
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3# 方式二:管道组合命令,一键拷贝
echo s2 s3 | xargs -t -n 1 cp /tmp/s1/sentinel.conf修改s2、s3两个文件夹内的配置文件,将端口分别修改为27002、27003:
sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' /tmp/s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' /tmp/s3/sentinel.conf启动
为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:
# 第1个
redis-sentinel /tmp/s1/sentinel.conf
# 第2个
redis-sentinel /tmp/s2/sentinel.conf
# 第3个
redis-sentinel /tmp/s3/sentinel.conf启动后:

测试
尝试让master节点7001宕机,查看sentinel日志:

查看7003的日志:

查看7002的日志:

搭建分片集群
集群结构
分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:
IP | PORT | 角色 |
192.168.136.130 | 7001 | master |
192.168.136.130 | 7002 | master |
192.168.136.130 | 7003 | master |
192.168.136.130 | 8001 | slave |
192.168.136.130 | 8002 | slave |
192.168.136.130 | 8003 | slave |
准备实例和配置
删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:
# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003在/tmp下准备一个新的redis.conf文件,内容如下:
# 进入/tmp目录
cd /tmp
# 创建并编辑
vim redis.conf按下i进行编辑,将下面的内容复制上去
按esc退出编辑模式
再按 :wq 保存退出
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.136.130
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log将这个文件拷贝到每个目录下:
# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:
# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf启动
因为已经配置了后台启动模式,所以可以直接启动服务:
# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf通过ps查看状态:
ps -ef | grep redis发现服务都已经正常启动:

如果要关闭所有进程,可以执行命令:
ps -ef | grep redis | awk '{print $2}' | xargs kill或者(推荐这种方式):
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown创建集群
虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。
我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。
Redis5.0之前
Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。
# 安装依赖
yum -y install zlib ruby rubygems
gem install redis然后通过命令来管理集群:
# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.136.130:7001 192.168.136.130:7002 192.168.136.130:7003 192.168.136.130:8001 192.168.136.130 :8002 192.168.136.130:8003Redis5.0以后
我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:
redis-cli --cluster create --cluster-replicas 1 192.168.136.130:7001 192.168.136.130:7002 192.168.136.130:7003 192.168.136.130:8001 192.168.136.130:8002 192.168.136.130:8003命令说明:
redis-cli --cluster或者./redis-trib.rb:代表集群操作命令
create:代表是创建集群
--replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master
运行后的样子:

这里输入yes,则集群开始创建:

通过命令可以查看集群状态:
redis-cli -p 7001 cluster nodes
测试
尝试连接7001节点,存储一个数据:
# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1结果悲剧了:

集群操作时,需要给redis-cli加上-c参数才可以:
redis-cli -c -p 7001这次可以了:

散列插槽
插槽原理
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
key中不包含“{}”,整个key都是有效部分
例如:key是num,那么就根据num计算,如果是{itcast}num,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。

如图,在7001这个节点执行set a 1时,对a做hash运算,对16384取余,得到的结果是15495,因此要存储到7003节点。
到了7003后,执行get num时,对num做hash运算,对16384取余,得到的结果是2765,因此需要切换到7001节点
小结
Redis如何判断某个key应该在哪个实例?
将16384个插槽分配到不同的实例
根据key的有效部分计算哈希值,对16384取余
余数作为插槽,寻找插槽所在实例即可
如何将同一类数据固定的保存在同一个Redis实例?
这一类数据使用相同的有效部分,例如key都以{typeId}为前缀
集群伸缩
redis-cli --cluster提供了很多操作集群的命令,可以通过下面方式查看:

比如,添加节点的命令:

需求分析
需求:向集群中添加一个新的master节点,并向其中存储 num = 10
启动一个新的redis实例,端口为7004
添加7004到之前的集群,并作为一个master节点
给7004节点分配插槽,使得num这个key可以存储到7004实例
这里需要两个新的功能:
添加一个节点到集群中
将部分插槽分配到新插槽
创建新的redis实例
创建一个文件夹:
cd /tmp
mkdir7004
拷贝配置文件:
cp redis.conf 7004
修改配置文件:
sed-i-e's/6379/7004/g'7004/redis.conf
启动
redis-server 7004/redis.conf
添加新节点到redis
添加节点的语法如下:

执行命令:
redis-cli --cluster add-node 192.168.136.130:7004 192.168.136.130:7001
通过命令查看集群状态:
redis-cli -p7001 cluster nodes
如图,7004加入了集群,并且默认是一个master节点:

但是,可以看到7004节点的插槽数量为0,因此没有任何数据可以存储到7004上
转移插槽
我们要将num存储到7004节点,因此需要先看看num的插槽是多少:

如上图所示,num的插槽为2765.
我们可以将0~3000的插槽从7001转移到7004,命令格式如下:

具体命令如下:
建立连接:
redis-cli --cluster reshard 192.168.136.130:7001

得到下面的反馈:

询问要移动多少个插槽,我们计划是3000个:
新的问题来了:

那个node来接收这些插槽??
显然是7004,那么7004节点的id是多少呢?

复制这个id,然后拷贝到刚才的控制台后:

这里询问,你的插槽是从哪里移动过来的?
all:代表全部,也就是三个节点各转移一部分
具体的id:目标节点的id
done:没有了
这里我们要从7001获取,因此填写7001的id:

填完后,点击done,这样插槽转移就准备好了:

确认要转移吗?输入yes:
然后,通过命令查看结果:

可以看到:

目的达成。
故障转移
集群初识状态是这样的:

其中7001、7002、7003都是master,我们计划让7002宕机。
自动故障转移
当集群中有一个master宕机会发生什么呢?
为了更好的查看故障转移过程,在此打开监听
watch redis-cli -p7001 cluster nodes
然后在复制一个标签操作集群
直接停止一个redis实例,例如7002:
redis-cli -p7002 shutdown
1)首先是该实例与其它实例失去连接
2)然后是疑似宕机:

3)最后是确定下线,自动提升一个slave为新的master:

4)当7002再次启动,就会变为一个slave节点了:
redis-server 7002/redis.conf

手动故障转移
利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。其流程如下:

这种failover命令可以指定三种模式:
缺省:默认的流程,如图1~6歩
force(强制):省略了对offset的一致性校验,如图2~3步
takeover(接管):直接执行第5歩,忽略数据一致性、忽略master状态和其它master的意见
案例需求:在7002这个slave节点执行手动故障转移,重新夺回master地位
步骤如下:
1)利用redis-cli连接7002这个节点
2)执行cluster failover命令
如图:

效果:

RedisTemplate访问分片集群
RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:
1)引入redis的starter依赖
2)配置分片集群地址
3)配置读写分离
与哨兵模式相比,其中只有分片集群的配置方式略有差异,如下:
spring:
redis:
cluster:
nodes:
- 192.168.136.130:7001
- 192.168.136.130:7002
- 192.168.136.130:7003
- 192.168.136.130:8001
- 192.168.136.130:8002
- 192.168.136.130:8003
相关文章:
【Redis高级-集群分片】
单机安装Redis首先需要安装Redis所需要的依赖:yum install -y gcc tclRedis安装包上传到虚拟机的任意目录:我放到了/tmp目录:解压缩:tar -zxvf /tmp/redis-6.2.4.tar.gz -C /tmp解压后:进入redis目录:cd /t…...
CSDN - CSDN27题解
文章目录幸运数字题目描述解题思路AC代码投篮题目描述解题思路AC代码通货膨胀-x国货币题目描述解题思路AC代码最后一位题目描述解题思路AC代码CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/41 这次题目描述刚开始好像有些问题,之后被修正了…...
docker拉取mysql
搜索mysql版本docker search mysql搜索获赞数(星星数量) 大于 1000 的镜像docker search --filterstars1000 mysql搜索官方发布的版本docker search --filter is-officialtrue mysql搜索版本号docker search mysql57拉取docker pull devbeta/mysql57查看下载镜像docker images启…...
在Linux上安装Python3
记录:373场景:在CentOS 7.9操作系统上,安装Python-3.8.9环境。版本:JDK 1.8 Python-3.8.9官网地址:https://www.python.org下载地址:https://www.python.org/ftp/python/1.安装基础依赖1.1安装gcc(1)安装命…...
23 种设计模式的通俗解释,看完秒懂
01 工厂方法 追 MM 少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是 MM 爱吃的东西,虽然口味有所不同,但不管你带 MM 去麦当劳或肯德基,只管向服务员说「来四个鸡翅」就行了。麦当劳和肯德基就是生产鸡翅的 Factory 工厂模式&…...
如何做好需求管理?经验方法、模型、工具
需求管理能力是衡量产品经理能力的一个重要指标。因为需求是产品的基石,只有选取恰当的方法进行需求分析及管理,才能更好的构建产品方案,从而输出精准的产品定义。结合本人学习和自身经验,打算将需求管理分”需求挖掘”、”需求分…...
怎么用期货做风险对冲(如何利用期货对冲风险)
不同期货市场的同一期货品种的对冲交易怎么做 不同 期货市场 的同一期货品种的 对冲交易 。 因为地域和 制度环境 不同,同一种期货品种在不同市场的同一时间的价格很可能是不一样的,并且也是在不断变化的。 这样在一个市场做多头买进࿰…...
C++标准模板库type_traits源码剖析
一、type_traits源码介绍 1、type_traits是C11提供的模板元基础库。 2、type_traits可实现在编译期计算。包括添加修饰、萃取、判断查询、类型推导等等功能。 3、type_traits提供了编译期的true和false。 二、type_traits的作用 1、根据不同类型,模板匹配不同版本…...
Python获取公众号(pc客户端)数据,使用Fiddler抓包工具
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 今天来教大家如何使用Fiddler抓包工具,获取公众号(PC客户端)的数据。 Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,…...
Maven进阶
这里写目录标题1.分模块开发1.1 模块更新后,会造成的影响2.依赖管理2.1 依赖传递2.2 可选依赖(隐藏自己的依赖,不让别人用)2.3 排除依赖(用别人的资源,把不用的去了)3.聚合与继承3.1 为什么要使用聚合工程?3.2 聚合工程开发2.1 聚合工程三级目录1.分模块开发 我们之前做的项目…...
AXI实战(一)-为AXI总线搭建简单的仿真测试环境
AXI实战(一)-搭建简单仿真环境 看完在本文后,你将可能拥有: 一个可以仿真AXI/AXI_Lite总线的完美主端(Master)或从端(Slave)一个使用SystemVerilog仿真模块的船信体验小何的AXI实战系列开更了,以下是初定的大纲安排: 欢迎感兴趣的朋友关注并支持,以下为正文部分 文章目录…...
数据库管理-第五十六期 监控(20230210)
数据库管理 2023-02-10第五十六期 监控1 怎么监控2 直观3 历史分析4 另一个BUG总结第五十六期 监控 春节后的7天班过后就来到了2月份,本周对之前发现X8M上的那个bug进行补丁修复和协助从12.2迁移了一套PDB到这个一体机上面,2次割接。这周还和原厂老大哥…...
测试开发,测试架构师为什么能拿50 60k呢需要掌握哪些技能呢
这篇文章是软件工程系列知识总结的第五篇,同样我会以自己的理解来阐述软件工程中关于架构设计相关的知识。相比于我们常见的研发架构师,测试架构师是近几年才出现的一个岗位,当然岗位title其实没有特殊的含义,在我看来测试架构师其…...
Miniblink 入门
miniblink官网:入门之前强烈建议将Miniblink介绍仔细看一遍。 MB内核组件标准版接口文档:这里列举了所有的api以及简单的说明,但是本人建议还是看wke.h更方便,里面都是宏实现的,直接搜相关函数即可。 mb demo下载和参…...
[python入门㊷] - python存储数据
目录 ❤ json.dump()存储数据 ❤ json.laod()读取数据 ❤ 保存和读取用户生成的数据 ❤ 重构 JSON(JavaScript Object Notation)格式最初是为JavaScript开发的,但随后成了一种常见格式,被包括Python在内的众多语言采用 ❤ json.dump()存储数据…...
Little Fighter:旺角——NFT 系列来袭!
《小朋友齐打交 2 (LF2) 》是一款流行的格斗游戏,由 Marti Wong 和 Starsky Wong 于 1999 年创作。这是一款非常容易上瘾的游戏,具有多种游戏模式、横向卷轴格斗系统以及 24 个具有复杂动作和连击的不同角色。这款游戏在世界范围内非常受欢迎,…...
基础篇:01-微服务概述
1.单体应用与微服务架构区别 如上图左侧为单体应用架构。在传统单体应用中,所有功能模块都在一个工程中编码、部署,即使是集群部署,也只是单体应用的水平复制。 如上图右侧为微服务架构。在微服务架构的项目中,每个应用会按照领域…...
TC358775XBG替代方案|完美替代 TC358775XBG替代方案|低BOM成本DSI转LVDS方案CS5518
TC358775XBG替代方案|完美替代 TC358775XBG替代方案|低BOM成本DSI转LVDS方案CS5518 TC358775XBG芯片的主要功能是DSI到LVDS桥,通过DSI链路实现视频流输出,以驱动LVDS兼容的显示面板。该芯片支持单链路LVDS高达1366768 24位像素分辨率,双链路L…...
Android开发
前言:因为这学期选了手机APP开发这门课,所以还是写个博客记录一下学习过程,包括安卓开发和ios开发。用到的资料包括课程PPT,和我在网上找的一些视频和资料。 1.Andriod入门 XML:描绘应用界面 (决定APP长什…...
virtualbox虚拟机导入到vmware esxi虚拟机
virtualbox导出的ova文件转换为ovf文件导入到vmware esxi虚拟机 1、下载安装程序 链接:https://pan.baidu.com/s/1pRP8MQswDSDecMB5eJGNYA?pwdmv2q 提取码:mv2q 双击VMware-ovftool-3.0.1-801290-win.x86_64.msi默认安装 2、在cmd中进入到Vware OVF…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
