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

Redis集群部署合集

目录

一. 原理简述

二. 集群配置​​​​​​​

2.1 环境准备

2.2 编译安装一个redis

2.3 创建集群

2.4 写入数据测试

实验一:

实验二:

实验三: 

实验四:

添加节点

自动分配槽位

提升节点为master:

实验五:

实验六:

实验七:


 官网文档(Redis集群规范) Redis cluster specification | Docs

一. 原理简述

此处的集群指的是Cluster, 通过分区/分片来实现一定程度的分布式与高可用部署。

二. 集群配置

Redis 最小集群规划,需要包含至少三个主节点,此处测试部署具有三个主服务器和三个从服务器的六节点群集。计划是在一台机器上模拟一个集群,主节点端口为三个, 从节点三个,这和生产环境的集群搭建没本质区别。下面的配置就将创建的六个redis实例端口修改为7001,7002,7003,7004,7005,7006,每个虚拟机中部署两个redis实例。

命令含义
cluster info获取集群的状态信息,包括插槽状态、节点数量等。
cluster nodes获取集群中所有节点的详细信息,包括节点ID、角色、状态等。
cluster meet <ip> <port>将新的节点加入到集群中。
cluster addslots <slot>为当前节点分配一个或多个插槽。
cluster delslots <slot>从当前节点删除一个或多个插槽。
cluster setslot <slot> <node-id>将一个插槽分配给指定节点。
cluster replicate <node-id>将当前节点设置为目标节点的从节点。
cluster failover触发趋向安全的故障转移,将当前从节点提升为主节点。
cluster reset重置集群状态(谨慎使用),可以选择温和模式或硬重置模式。CLUSTER RESET 命令可以选择温和模式(soft reset)或硬重置模式(hard reset)。温和模式通常只清除槽位信息而不改变节点ID,而硬重置模式则会生成新的节点ID。默认为温和重置模式。
cluster saveconfig将当前集群配置数据保存到集群节点的配置文件中。
cluster replicas <node-id>列出指定主节点的所有从节点。
cluster myid获取当前节点的ID。
cluster slots获取集群中所有插槽的分布情况。
cluster flushslots清空当前节点的所有插槽信息。
cluster keyslot <key>根据给定的键值计算出其对应的插槽。

删除节点的步骤

步骤命令含义
数据迁移redis-cli --cluster reshard --cluster-from <源节点ID> --cluster-to <目标节点ID> --cluster-slots <迁移插槽数> -h <集群中的任一节点IP> -p <端口> 或 手动使用cluster setslot命令将待删除节点的数据迁移到其他节点(可以手动也可自动)。
节点删除redis-cli -h <其他节点IP> -p <其他节点端口> cluster forget <节点ID>通知集群中的其他节点忘记被删除的节点。
节点下线(可选)redis-cli -h <节点IP> -p <节点端口> shutdown关闭被删除节点的Redis服务器实例。

2.1 环境准备

localhostrocky_linux9.4192.168.226.21redis5.0.10
localhostrocky_linux9.4192.168.226.22redis5.0.10
localhostrocky_linux9.4192.168.226.23redis5.0.10

关闭防火墙和selinux,时间同步。

2.2 编译安装一个redis

 现在选择第一台192.168.226.21进行先编译安装一个redis,步骤如下

[root@localhost ~]# wget http://download.redis.io/releases/redis-5.0.10.tar.gz   #下载redis
[root@localhost ~]# tar xzf redis-5.0.10.tar.gz -C /usr/local                 #解压
[root@localhost ~]# cd /usr/local/
[root@localhost local]# mv redis-5.0.10/ redis7001
[root@localhost local]# cd redis7001/
[root@localhost redis]# yum install -y gcc make                               #安装编译工具
[root@localhost redis]# make
注:如果报错请将刚才解压的安装包删除掉,再次重新解压并进行make安装即可。#以下为定义参数
#创建持久化数据目录
[root@localhost ~]# mkdir /usr/local/redis7001/data
[root@localhost ~]# cd /usr/local/redis7001
[root@localhost redis7001]# cp redis.conf redis.conf.bak    #备份配置文件
[root@localhost redis7001]# vim redis.conf         #在配置文件中找到修改如下bind 0.0.0.0                        #默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群  
pidfile  /var/run/redis_7001.pid     #pidfile文件对应7001,7002,7003,7004,7005,7006
dir  /usr/local/redis7001/data/     #数据文件存放位置对应7001,7002,7003,7004,7005,7006
port 7001                           #端口7001
timeout 300
daemonize yes                       #redis后台运行
pidfile "/var/log/redis7001.log"    #日志目录
cluster-enabled yes                 #开启集群
cluster-config-file nodes-7001.conf #集群配置信息,开启集群后自动生成
cluster-node-timeout 5000           #请求超时时长 
appendonly yes                      #开启aof日志,它会每次写操作都记录一条日志

[root@localhost redis7001]# cd #拷贝五个redis实例,每个虚拟里放两个redis实例
[root@localhost ~]# cd ~ && cp -r /usr/local/redis7001 /usr/local/redis7002[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.22:/usr/local/redis7003
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.22:/usr/local/redis7004
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.23:/usr/local/redis7005
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.23:/usr/local/redis7006
#修改剩下五个实例中的7001为自己对应的号
[root@localhost ~]# vim /usr/local/redis7002/redis.conf
#在配置未见中使用语法 :%s/7001/7002/g 即可快速匹配替换,然后保存退出
#在另外两个主机中,对剩下的四个redis实例用也同样的方法去快速匹配修改,注意在命令中修改数字,这里不在赘述

启动六个redis实例,并查验端口是否正常

#对192.168.226.21操作
[root@localhost ~]# /usr/local/redis7001/src/redis-server /usr/local/redis7001/redis.conf            
[root@localhost ~]# /usr/local/redis7001/src/redis-server /usr/local/redis7002/redis.conf 
[root@localhost ~]# ss -tnlp
State       Recv-Q      Send-Q           Local Address:Port            Peer Address:Port      Process                                      
LISTEN      0           511                    0.0.0.0:17001                0.0.0.0:*          users:(("redis-server",pid=7908,fd=9))      
LISTEN      0           511                    0.0.0.0:17002                0.0.0.0:*          users:(("redis-server",pid=7914,fd=9))      
LISTEN      0           511                    0.0.0.0:7001                 0.0.0.0:*          users:(("redis-server",pid=7908,fd=6))      
LISTEN      0           511                    0.0.0.0:7002                 0.0.0.0:*          users:(("redis-server",pid=7914,fd=6))      
LISTEN      0           128                    0.0.0.0:22                   0.0.0.0:*          users:(("sshd",pid=854,fd=3))               
LISTEN      0           128                       [::]:22                      [::]:*          users:(("sshd",pid=854,fd=4)) #对192.168.226.22操作
[root@localhost local]# /usr/local/redis7003/src/redis-server /usr/local/redis7003/redis.conf
[root@localhost local]# /usr/local/redis7003/src/redis-server /usr/local/redis7004/redis.conf
[root@localhost local]# ss -tnlp
State        Recv-Q       Send-Q               Local Address:Port                Peer Address:Port       Process                                         
LISTEN       0            511                        0.0.0.0:7004                     0.0.0.0:*           users:(("redis-server",pid=10220,fd=6))        
LISTEN       0            511                        0.0.0.0:7003                     0.0.0.0:*           users:(("redis-server",pid=10215,fd=6))              
LISTEN       0            511                        0.0.0.0:17004                    0.0.0.0:*           users:(("redis-server",pid=10220,fd=9))        
LISTEN       0            511                        0.0.0.0:17003                                       0.0.0.0:*           users:(("redis-server",pid=5693,fd=6))         
LISTEN       0            128                        0.0.0.0:22                       0.0.0.0:*           users:(("sshd",pid=859,fd=3))                                 
LISTEN       0            128                           [::]:22                          [::]:*           users:(("sshd",pid=859,fd=4))                  #对192.168.226.23操作
[root@localhost ~]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf
[root@localhost ~]# /usr/local/redis7006/src/redis-server /usr/local/redis7006/redis.conf
[root@localhost ~]# ss -tnlp
State         Recv-Q        Send-Q               Local Address:Port                Peer Address:Port       Process                                       
LISTEN        0             511                        0.0.0.0:17006                    0.0.0.0:*           users:(("redis-server",pid=1783,fd=9))       
LISTEN        0             511                        0.0.0.0:17005                    0.0.0.0:*           users:(("redis-server",pid=1778,fd=9))       
LISTEN        0             511                        0.0.0.0:7006                     0.0.0.0:*           users:(("redis-server",pid=1783,fd=6))       
LISTEN        0             511                        0.0.0.0:7005                     0.0.0.0:*           users:(("redis-server",pid=1778,fd=6))              
LISTEN        0             128                        0.0.0.0:22                       0.0.0.0:*           users:(("sshd",pid=858,fd=3))                            
LISTEN        0             128                           [::]:22                          [::]:*           users:(("sshd",pid=858,fd=4))                

#上面启动命令中,有些前面的对应的数字没修改成对应数字是可以的,但是后面那个必须要对号才行。

2.3 创建集群

# 注意ip和端口的对应,这里用第一个,即7001的redis实例创建,如果换机器注意修改数字,--cluster-replicas 1是指定每个主节点有一个从节点
[root@localhost ~]#  /usr/local/redis7001/src/redis-cli --cluster create --cluster-replicas 1 192.168.226.21:7001 192.168.226.21:7002 192.168.226.22:7003 192.168.226.22:7004 192.168.226.23:7005 192.168.226.23:7006

启动后接下开会有提示,对照后输入yes即可,这里一定要输入的是yes,不能是简写y,如下图:

 创建完成后,验证集群状态:

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster info
cluster_state:ok                           #表示集群状态是正常的
cluster_slots_assigned:16384               #表示集群中的插槽已分配的数量是16384,这是Redis集群的最大插槽数量。
cluster_slots_ok:16384                     #表示集群中的插槽正常的数量是16384。
cluster_slots_pfail:0                      #表示在插槽中标记为疑似故障(pfail)的节点数量是0。
cluster_slots_fail:0                       #表示在插槽中标记为故障(fail)的节点数量是0。
cluster_known_nodes:6                      #表示集群中已知节点的总数是6。
cluster_size:3                             #表示集群的大小(即主节点的数量)是3。
cluster_current_epoch:6                    #集群当前的配置版本(或配置纪元)。
cluster_my_epoch:1                         #该节点最后一次选举的配置版本。
cluster_stats_messages_ping_sent:362       #此节点发送的ping消息数量。
cluster_stats_messages_pong_sent:331       #此节点发送的pong消息数量。
cluster_stats_messages_sent:693            #此节点发送的总消息数量。
cluster_stats_messages_ping_received:326   #此节点接收的ping消息数量。
cluster_stats_messages_pong_received:362   #此节点接收的pong消息数量。
cluster_stats_messages_meet_received:5     #此节点接收的meet消息数量。
cluster_stats_messages_received:693        #此节点接收的总消息数量。ping:这是一个节点向其他节点发送的消息,用于检查其他节点的健康状态。当一个节点发送ping消息后,如果目标节点是活动的,它会回复一个pong消息。
pong:这是一个节点在收到其他节点的ping消息后发送的响应消息。它是对ping消息的响应,表示该节点当前是活动的。
meet:这是一种特殊类型的消息,当一个节点想要加入到集群中时会发送此消息。当一个节点收到meet消息后,它会将这个新节点添加到它所知道的节点列表中,并将这个信息通过ping消息传播给其他节点,以此方式把新节点引入到集群网络中。

使用以下命令查看集群中每个节点的状态 (当前登录的会在里面用myself标识出来,本下面第五行就标识出来了)

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
870ed4837bcfc5d8e455c04ff4e2ec39156a652b 192.168.226.21:7002@17002 slave b0dc2767920f8e319e59709a88252cd46cfdda6d 0 1719391362667 5 connected
852c2c534e007a5155f96fba95c8333e334a5c3e 192.168.226.22:7004@17004 slave e4264f2bfaff2546625b9a8f559a0e822c5e24e1 0 1719391363820 4 connected
4cad4eebb85a849614ecaffeeb4b73da032fd974 192.168.226.22:7003@17003 master - 0 1719391362773 3 connected 5461-10922
e4264f2bfaff2546625b9a8f559a0e822c5e24e1 192.168.226.21:7001@17001 myself,master - 0 1719391359000 1 connected 0-5460
171b2751e63e86aa5335c149804a0e435dbb6f7f 192.168.226.23:7006@17006 slave 4cad4eebb85a849614ecaffeeb4b73da032fd974 0 1719391364235 6 connected
b0dc2767920f8e319e59709a88252cd46cfdda6d 192.168.226.23:7005@17005 master - 0 1719391363503 5 connected 10923-16383

2.4 写入数据测试

实验一:

使用当前主机节点连接别的主机节点,插入数据测试,提示失败

#不适用-c参数连接一个节点,结果不然插入数据,对应的哈希槽不匹配
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.23 -p 7006
192.168.226.23:7006> keys *
(empty list or set)
192.168.226.23:7006> set name zhangsan
(error) MOVED 5798 192.168.226.22:7003#使用-c参数连接节点后插入数据,结果可以正常插入,他会自动插入到对应的哈希槽
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.23 -p 7006
192.168.226.23:7006> set age grg
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> set name lisi
-> Redirected to slot [5798] located at 192.168.226.22:7003
OK

在 Redis 集群中,每个主节点和从节点负责特定的哈希槽范围。哈希槽(hash slot)是 Redis 集群中的一个概念,用于将键分配到不同的节点。Redis 集群将键映射到 16384 个哈希槽,然后将这些哈希槽分配给不同的节点。使用 -c 参数(即“cluster mode”)来运行 redis-cli 是因为这个模式会处理 Redis 集群的特定行为,特别是当节点之间存在键的重定向时。这是因为 Redis 集群中的每个键都映射到特定的哈希槽,而每个哈希槽又由集群中的特定节点负责。如果你尝试在没有集群模式的情况下访问不属于该节点的键,Redis 将返回一个 MOVED 错误,指示你重定向到正确的节点。当你使用 redis-cli 连接到 Redis 集群并进行操作时,集群模式会自动处理这些重定向。这意味着,如果你试图访问一个不在当前节点处理范围内的键,redis-cli 将自动重定向你的请求到正确的节点。

实验二:

随机连接一个节点,这次使用-c参数连接后插入多条数据

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.23 -p 7006
192.168.226.23:7006> set age grg
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> set name lisi
-> Redirected to slot [5798] located at 192.168.226.22:7003
OK
192.168.226.22:7003>  
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.22 -p 7004
192.168.226.22:7004> keys *
1) "age"
192.168.226.22:7004> set a b
-> Redirected to slot [15495] located at 192.168.226.23:7005
OK
192.168.226.23:7005> set  e g
OK
192.168.226.23:7005> set  q a
OK
192.168.226.23:7005> set age 99
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> keys *
1) "age"
192.168.226.21:7001> set dgd sdf
-> Redirected to slot [14644] located at 192.168.226.23:7005
OK
192.168.226.23:7005> set 1 2
-> Redirected to slot [9842] located at 192.168.226.22:7003
OK
192.168.226.22:7003> keys *
1) "name"
2) "1"
192.168.226.22:7003> get age
-> Redirected to slot [741] located at 192.168.226.21:7001
"99"
192.168.226.21:7001> get e
-> Redirected to slot [15363] located at 192.168.226.23:7005
"g"

通过多次插入数据和查看发现,在插入时会被重定向,数据会被重定向到对应的哈希槽,同时所处的节点也会随之移动,并且查看所有key时,只能看到当前节点机器的key,随便看不到别的节点的key,但是使用get去查看别的节点存在的key,也是可以看到其对应的值的,只是在自己所处的节点不能看到别的节点的key。

简述总结:

当使用 -c 参数连接 Redis 集群时,会观察到以下行为和特点:

  1. 自动键重定向:

    • 当执行命令时,redis-cli 会根据键的哈希槽信息自动将命令发送到负责该键的节点上执行。
    • 如果键的哈希槽不在当前连接的节点上,redis-cli 会自动重定向命令到正确的节点执行,执行成功后返回结果。
  2. 节点的键查看限制:

    • 每次连接到一个节点后,只能查看该节点负责的键,而不能查看整个集群的所有键。
    • 这意味着在一个节点上执行 keys * 命令只会返回该节点负责的键列表,而不是整个集群的所有键。
  3. 位置变动:

    • 如果集群的主从节点发生变化或者数据迁移,同一个键可能会被分配到不同的节点上。
    • 因此,多次连接并查看键的位置可能会发现键在不同节点上的分布情况有所改变。
  4. 集群管理和数据一致性:

    • Redis 集群通过哈希槽来管理数据分片和负载均衡,自动将数据分散到不同的节点上。
    • 当节点加入或离开集群时,集群会重新分配哈希槽,保证数据的高可用性和一致性。

实验三: 

现在实验挂掉一个节点和挂掉一对主从节点测试。

从前面看到的分配的主从配对信息中,选择从节点192.168.226.21:7002和主节点192.168.226.23:7005来测试

首先将192.168.226.23:7005关闭服务,看从节点变化。

对192.168.226.23主机操作:
[root@localhost local]# /usr/local/redis7005/src/redis-cli -h 192.168.226.23 -p 7005 shutdown
[root@localhost ~]# ss -tnlp
State         Recv-Q        Send-Q               Local Address:Port                Peer Address:Port       Process                                       
LISTEN        0             511                        0.0.0.0:17006                    0.0.0.0:*           users:(("redis-server",pid=1783,fd=9))       
LISTEN        0             511                        0.0.0.0:7006                     0.0.0.0:*           users:(("redis-server",pid=1783,fd=6))       
LISTEN        0             128                        0.0.0.0:22                       0.0.0.0:*           users:(("sshd",pid=858,fd=3))                           
LISTEN        0             128                           [::]:22                          [::]:*           users:(("sshd",pid=858,fd=4))                #查看集群中每个节点的状态 
[root@localhost ~]# /usr/local/redis7006/src/redis-cli -h 192.168.226.23 -p 7006 cluster nodes
4cad4eebb85a849614ecaffeeb4b73da032fd974 192.168.226.22:7003@17003 master - 0 1719492508192 3 connected 5461-10922
e4264f2bfaff2546625b9a8f559a0e822c5e24e1 192.168.226.21:7001@17001 master - 0 1719492507000 1 connected 0-5460
870ed4837bcfc5d8e455c04ff4e2ec39156a652b 192.168.226.21:7002@17002 master - 0 1719492507187 7 connected 10923-16383
171b2751e63e86aa5335c149804a0e435dbb6f7f 192.168.226.23:7006@17006 myself,slave 4cad4eebb85a849614ecaffeeb4b73da032fd974 0 1719492508000 6 connected
852c2c534e007a5155f96fba95c8333e334a5c3e 192.168.226.22:7004@17004 slave e4264f2bfaff2546625b9a8f559a0e822c5e24e1 0 1719492506179 4 connected
b0dc2767920f8e319e59709a88252cd46cfdda6d 192.168.226.23:7005@17005 master,fail - 1719492406717 1719492406616 5 disconnected

可以发现把一个主节点关闭后,在集群信息中会被标记故障,然后对应的从节点会变成主机点

现在把192.168.226.23:7005的redis服务启动再观察:

#启动192.168.226.23:7005的redis服务
[root@localhost local]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf 
[root@localhost local]# ss -tnlp
State         Recv-Q        Send-Q               Local Address:Port                Peer Address:Port       Process                                       
LISTEN        0             511                        0.0.0.0:17006                    0.0.0.0:*           users:(("redis-server",pid=1783,fd=9))       
LISTEN        0             511                        0.0.0.0:17005                    0.0.0.0:*           users:(("redis-server",pid=1836,fd=9))       
LISTEN        0             511                        0.0.0.0:7006                     0.0.0.0:*           users:(("redis-server",pid=1783,fd=6))       
LISTEN        0             511                        0.0.0.0:7005                     0.0.0.0:*           users:(("redis-server",pid=1836,fd=6))       
LISTEN        0             128                        0.0.0.0:22                       0.0.0.0:*           users:(("sshd",pid=858,fd=3))                          
LISTEN        0             128                           [::]:22                          [::]:*           users:(("sshd",pid=858,fd=4))                
[root@localhost ~]# /usr/local/redis7006/src/redis-cli -h 192.168.226.22 -p 7003 -c
192.168.226.22:7003> cluster nodes
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 master - 0 1719499652547 1 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719499653000 7 connected
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 myself,master - 0 1719499653000 3 connected 5461-10922
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719499653047 4 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719499653852 6 connected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719499652547 7 connected 10923-16383
192.168.226.22:7003> 

可以看到192.168.226.23:7005的redis再开启服务后就变成了从节点,原来一组的从节点192.168.226.21:7002变成了主节点。

现在将这一对主从节点都停止服务测试:

#对192.168.226.23主机操作
[root@localhost ~]# /usr/local/redis7005/src/redis-cli -h 192.168.226.23 -p 7005 shutdown
#对192.168.226.21主机操作
[root@localhost ~]# /usr/local/redis7002/src/redis-cli -h 192.168.226.21 -p 7002 shutdown#使用192.168.226.21主机连接redis
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 -c
192.168.226.21:7001>  cluster nodes
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719403248009 4 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,master - 0 1719403227000 1 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave,fail 3473b893f94e01fee0f7be54cb53007440e487ea 1719403235885 1719403234851 7 disconnected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master,fail - 1719403230400 1719403229172 7 disconnected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 master - 0 1719403247374 3 connected 5461-10922
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719403247798 6 connected
192.168.226.21:7001> keys *
1) "www"
2) "age"
192.168.226.21:7001> get www
(error) CLUSTERDOWN The cluster is down
192.168.226.21:7001> set big 8888
(error) CLUSTERDOWN The cluster is down
192.168.226.21:7001> 

 可以看到不能看数据,也不能写数据。CLUSTERDOWN The cluster is down 错误表明 Redis 集群当前处于非活动状态,可能是因为集群中的某些节点无法正常通信或集群配置出现了问题。因此,当一对互为主从的节点宕机,则集群不可用。

现在将原来先将192.168.226.23:7005开启服务

[root@localhost local]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf 

将验证,即便先起来也不代表会先成为master节点。

现在再将192.168.226.21:7002恢复redis服务

[root@localhost ~]# /usr/local/redis7002/src/redis-server /usr/local/redis7002/redis.conf

实验四:

添加节点

此时我们新增一个虚拟机,拷贝两个redis实例并启动

localhostrocky_linux9.4192.168.226.24redis5.0.10

确认关闭防火墙和selinux,进行时间同步。

从192.168.226.21主机中拷贝两个redis实例到192.168.226.24主机中。

#对192.168.226.21操作进行拷贝
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.24:/usr/local/redis7007
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.24:/usr/local/redis7008
#对192.168.226.24主机修改配置文件
[root@localhost ~]# vim /usr/local/redis7007/redis.conf#使用:%s/7001/7007/g   然后保存退出[root@localhost ~]# vim /usr/local/redis7008/redis.conf#使用:%s/7001/7008/g   然后保存退出#启动两个redis实例
[root@localhost ~]# /usr/local/redis7007/src/redis-server /usr/local/redis7007/redis.conf[root@localhost ~]# /usr/local/redis7007/src/redis-server /usr/local/redis7008/redis.conf#验证启动
[root@localhost ~]# ss -tnlp
State        Recv-Q       Send-Q             Local Address:Port              Peer Address:Port       Process                                       
LISTEN       0            511                      0.0.0.0:7008                   0.0.0.0:*           users:(("redis-server",pid=1416,fd=6))       
LISTEN       0            511                      0.0.0.0:7007                   0.0.0.0:*           users:(("redis-server",pid=1411,fd=6))       
LISTEN       0            511                      0.0.0.0:17007                  0.0.0.0:*           users:(("redis-server",pid=1411,fd=9))       
LISTEN       0            511                      0.0.0.0:17008                  0.0.0.0:*           users:(("redis-server",pid=1416,fd=9))       
LISTEN       0            128                      0.0.0.0:22                     0.0.0.0:*           users:(("sshd",pid=849,fd=3))                
LISTEN       0            128                         [::]:22                        [::]:*           users:(("sshd",pid=849,fd=4))  

要添加节点,首先启动redis实例,用集群中的主机连接任一实例去添加这个新节点。

选择192.168.226.21去操作添加:

#添加主节点
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7002 cluster meet 192.168.226.24 7007#查看集群中每个节点的状态
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7002 cluster nodes
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719502625187 7 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719502623179 1 connected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719502623000 7 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 master - 0 1719502623681 3 connected 5461-10922
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 myself,slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719502622000 0 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 master - 0 1719502624183 1 connected 0-5460
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719502624000 3 connected

验证集群状态

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7002 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:7
cluster_size:3
cluster_current_epoch:7
cluster_my_epoch:7
cluster_stats_messages_ping_sent:3969
cluster_stats_messages_pong_sent:3466
cluster_stats_messages_meet_sent:1
cluster_stats_messages_update_sent:2
cluster_stats_messages_sent:7438
cluster_stats_messages_ping_received:3466
cluster_stats_messages_pong_received:3970
cluster_stats_messages_received:7436
#再添加一个节点
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster meet 192.168.226.24 7008#给新增的节点设置其对应的主节点,后面的字符串就是主节点的ID,通过前面用cluster nodes获取到的
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7008 cluster replicate c1250f1610d7328dba13a030f89257b480c0d781

这两个命令用法:

/path路径/redis/src/redis-cli -h <已有节点IP> -p <已有节点端口> cluster meet <新节点IP> <新节点端口>
/path路径/redis/src/redis-cli -h <新节点IP> -p <新节点端口> cluster replicate <已有节点ID>

注:

添加节点有一种情况是添加进去就是master,有一种情况添加后就是slave ,如果是slave那么执行使用cluster reset 重置这个节点再次重新添加至集群内尝试。

/usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7007 cluster reset

自动分配槽位
[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster rebalance 192.168.226.24:7007
>>> Performing Cluster Check (using node 192.168.226.24:7007)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster rebalance 192.168.226.24:7008
>>> Performing Cluster Check (using node 192.168.226.24:7008)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.

提升节点为master:
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7007 cluster failover

假设我给192.168.226.24:7007 把其从节点提升为主节点,使用CLUSTER FAILOVER命令后,会让原有的注意点之一降级为从节点,其原理解释如下:

在Redis集群中,执行CLUSTER FAILOVER命令后,所有的从节点都会尝试进行故障转移,结果是你指定的节点变为了主节点。执行过程中的变化可以解释为什么会发生角色改变。

执行的步骤

  1. 初始状态

    • 192.168.226.24:7007为从节点。
    • 192.168.226.21:7001192.168.226.21:7002192.168.226.22:7003是主节点。
  2. 执行故障转移

    • 当你在192.168.226.24:7007(原从节点)执行CLUSTER FAILOVER命令时,这个从节点被提升为主节点。

故障转移过程

故障转移过程中:

  • 原主节点(192.168.226.21:7001)的角色变为了从节点,以保持数据的高可用性和一致性。
  • 具体来说,执行CLUSTER FAILOVER命令后,192.168.226.24:7007从节点被提升为主节点,原主节点(192.168.226.21:7001)被降级为从节点。这就是为什么看到的新输出中192.168.226.24:7007变为了主节点,而192.168.226.21:7001变为了从节点。

新的集群状态解释

新的状态如下:

  • 主节点:

    • 192.168.226.24:7007
    • 192.168.226.21:7002
    • 192.168.226.22:7003
  • 从节点:

    • 192.168.226.21:7001(从原主节点降级)
    • 192.168.226.23:7005
    • 192.168.226.22:7004
    • 192.168.226.24:7008
    • 192.168.226.23:7006

新状态变更后,新的主节点和从节点的对应关系保持如下:

  • 新主节点192.168.226.24:7007接管了原主节点192.168.226.21:7001的插槽范围0-5460

变化主要是为了保持群集的高可用性和数据的一致性,同时你也成功完成了将从节点提升为主节点的操作。

#验证重新平衡
[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster check 192.168.226.24:7008
192.168.226.24:7008 (7a98972a...) -> 1 keys | 5462 slots | 2 slaves.
192.168.226.23:7005 (2544360a...) -> 3 keys | 5461 slots | 1 slaves.
192.168.226.24:7007 (94d037d0...) -> 2 keys | 5461 slots | 2 slaves.
[OK] 6 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.226.24:7008)
M: 7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008slots:[5461-10922] (5462 slots) master2 additional replica(s)
S: 3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002slots: (0 slots) slavereplicates 2544360a6e3ea711151312abb829037fe1b72163
S: 51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006slots: (0 slots) slavereplicates 7a98972ab9a038538c2106d1e6c52915d5e3999d
M: 2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004slots: (0 slots) slavereplicates 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4
S: 978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001slots: (0 slots) slavereplicates 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4
S: c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003slots: (0 slots) slavereplicates 7a98972ab9a038538c2106d1e6c52915d5e3999d
M: 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007slots:[0-5460] (5461 slots) master2 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

实验五:

使用gorget忘记一个redis实例。

在这之前的实验添加了两个节点,并将192.168.226.24:7007的实例提升为master节点,并导致整个集群从节点都会尝试进行故障转移,新的主从信息如下查看:

[root@localhost ~]#  /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 master - 0 1719457085420 8 connected 0-5460
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457085000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719457086078 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719457086196 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457086000 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 0 1719457086519 8 connected
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457087281 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457087756 9 connected

现在进行忘记一个从节点(后面的字符串是指定节点对应的ID,可在上面查看到的信息找到每个节点对应ID):

[root@localhost ~]#  /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster forget 2544360a6e3ea711151312abb829037fe1b72163

 再查询每个节点的状态

[root@localhost ~]#  /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 master - 0 1719457172640 8 connected 0-5460
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457171000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719457173425 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719457172745 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457173085 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 0 1719457172000 8 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457172306 9 connected[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.22 -p 7004 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719551425478 12 connected
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719551425000 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719551425804 9 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719551426555 9 connected 5461-10922
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719551425000 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 myself,master - 0 1719551424000 12 connected 0-5460
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719551426000 11 connected 10923-16383
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719551425000 11 connected

使用forget只是在当前节点忘记了指定ID的节点信息,但是其他节点还是存在这个信息。

使用 CLUSTER FORGET 命令来忘记一个 Redis 集群节点时,这个命令实际上是从当前节点的集群配置中移除了指定的节点信息。但是,这并不意味着该节点从整个集群中完全消失了。

集群中的其他节点可能仍然知道这个被忘记的节点,并且 cluster_known_nodes 的计数可能会继续包含它,直到这些节点也执行了 CLUSTER FORGET 命令或者通过集群的自动重新配置过程(如故障转移或重新平衡)来更新它们的集群配置。

如果在 Redis 集群中的所有其他节点上都使用 CLUSTER FORGET 命令忘记了7005节点的集群ID,那么从集群管理的角度来看,7005节点就已经从集群配置中被移除了。然而,仅仅这样做并不意味着7005节点已经停止运行或已从物理上删除。如果还需要确保7005节点不再运行并且释放其占用的资源,可以则停止7005节点的服务删除7005节点的数据和配置文件等方法。

请注意,如果7005节点在 CLUSTER FORGET 操作之后重新启动,并且它仍然保留有之前的集群状态信息(特别是 nodes.conf 文件),它可能会尝试重新加入集群。因此,彻底删除7005节点的数据和配置文件是确保它不再参与集群的关键步骤。

执行forget后,重启7005节点后,在使用forget那个节点那又可以查看到7005节点的信息了

实验六:

在实验五中仅仅使用forgrt命令测试忘记节点,那么在重新启动被forget的redis节点,就又可以恢复了。

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719459359290 12 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719459355000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719459360597 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719459360171 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719459359513 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 master - 0 1719459360054 12 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719459360597 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719459358413 9 connected

接下来尝试节点缩容。

被缩容节点和接收数据槽的几点都要求为主节点才可,在Redis集群中,只有主节点才能拥有哈希槽(slots)。

根据上述集群信息和对应ID,以及下述语法

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster reshard 192.168.226.21:7002 --cluster-from 3473b893f94e01fee0f7be54cb53007440e487ea --cluster-to 7a98972ab9a038538c2106d1e6c52915d5e3999d --cluster-slots 5461 --cluster-yes# --cluster-from 要缩容的主节点id
# --cluster-to 缩容之后的数据槽点分给哪一个master
# --cluster-slots 要缩容的主节点id的槽位数量
# --cluster-yes 可以自动执行而无需手动确认(可加可不加)

再次查询信息

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719460937784 12 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460936000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719460936000 13 connected 5461-16383
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719460937324 11 connected
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 1719460938127 1719460935871 13 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 master - 0 1719460937903 12 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460937022 13 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460936206 13 connected

实验七:

删除一个从节点

(推荐先删除从节点,后删除主几点)

下面是删除的命令,后面要跟的是被删除节点IP和端口,然后就是ID

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.23:7006 51db12ce426015bbabda015e2bb3564f0858b43e

可以看到没有7006的节点了。

删除主节点 

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.21:7002 3473b893f94e01fee0f7be54cb53007440e487ea 

 

错误原因:

[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.24:7008 7a98972ab9a038538c2106d1e6c52915d5e3999d
>>> Removing node 7a98972ab9a038538c2106d1e6c52915d5e3999d from cluster 192.168.226.24:7008
[ERR] Node 192.168.226.24:7008 is not empty! Reshard data away and try again.

 错误信息提示正在尝试从集群中删除一个非空的节点(7a98972ab9a038538c2106d1e6c52915d5e3999d),但是该节点上仍然有哈希槽(slots)和数据。在Redis集群中,不能直接删除一个包含数据的节点,因为这样会丢失数据,只有当节点是空的(即它不拥有任何哈希槽和数据)时,才能使用redis-cli --cluster del-node命令来删除该节点。

实验八:

删除集群

Redis集群创建好后,一般会有以下文件生成:$ tree
.
├── appendonly.aof
├── dump.rdb
├── nodes-7000.conf
├── redis.conf
└── redis-server0 directories, 5 files其中,nodes-*.conf记录了Redis集群的信息。要想删除一个集群,首先关闭Redis服务,方法如下:redis-cli -h 127.0.0.1 -p 7000 shutdown关闭所有集群上节点后,进入各个节点文件夹,删除以下文件:appendonly.aof
dump.rdb
nodes-7000.conf
批量删除指令如下:rm -f ./*/nodes-*.conf ./*/appendonly.aof ./*/dump.rdbok,至此,旧集群已经不复存在,只留下了redis服务进程和配置文件。

相关文章:

Redis集群部署合集

目录 一. 原理简述 二. 集群配置​​​​​​​ 2.1 环境准备 2.2 编译安装一个redis 2.3 创建集群 2.4 写入数据测试 实验一&#xff1a; 实验二&#xff1a; 实验三&#xff1a; 实验四&#xff1a; 添加节点 自动分配槽位 提升节点为master&#xff1a; 实验…...

【HDFS】关于Hadoop的IPC.Client类的一些整理

org.apache.hadoop.ipc.Client 类是IPC服务的一个客户端。 IPC请求把一个Writable对象当做参数,返回一个Writable对象当做结果value。 一个IPC服务运行在某个端口上,并且由参数class和value class定义。 Router里的IPC.Client对象就两个 有这样一个类:ClientCache 看名字就…...

Swoole v6 能否让 PHP 再次伟大?

现状 传统的 PHP-FPM 也是多进程模型的的运行方式&#xff0c;但每个进程只能处理完当前请求&#xff0c;才能接收下一个请求。而且对于 PHP 脚本来说&#xff0c;只是接收请求和响应请求&#xff0c;并不参与网络通信。对数据库资源的操作&#xff0c;也是一次请求一次有效&am…...

C++ STL Iterator Adapter

1. std::back_insert_iterator 使用 // back_insert_iterator example #include <iostream> // std::cout #include <iterator> // std::back_insert_iterator #include <vector> // std::vector #include <algorithm> // std::copy…...

android-aidl5

aidl类是实现Manager和Service通信的桥梁。 例如在修改Android Wifi功能的时候看到WifiManager管理WifiService&#xff1b; AIDL是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。 比如onclick&#xff08;&#xff09;&#xff0c;用oneway修…...

day01-项目介绍及初始化-登录页

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 day01-项目介绍及初始化-登录页一、人力资源项目介绍1.1项目架构和解决方案主要模块解决的问题 二、拉取项目基础代码1.引入库2.升级core-js版本到3.25.5按照完整依…...

华为开发者大会:全场景智能操作系统HarmonyOS NEXT

文章目录 一、全场景智能操作系统 - HarmonyOS NEXT1.1 系统特性1.2 关于架构、体验和生态 二、应用案例2.1 蚂蚁mpaas平台的性能表现 三、新版本应用框架发布3.1 新语言发布3.2 新数据库发布3.3 新版本编译器的发布 四、CodeArts和DataArts4.1 CodeArts4.2 DataArts 五、总结 …...

深度学习二分类评估详细解析与代码实战

深度学习二分类的实战代码&#xff1a;使用 Trainer API 微调模型. https://huggingface.co/learn/nlp-course/zh-CN/chapter3/3 如果你刚接触 自然语言处理&#xff0c;huggingface 是你绕不过去的坎。但是目前它已经被墙了&#xff0c;相信读者的实力&#xff0c;自行解决吧。…...

c++笔记容器详细介绍

C标准库提供了多种容器来存储和管理数据。这些容器属于<vector>, <list>, <deque>, <map>, <set>, <unordered_map>, <unordered_set>等头文件中。这些容器各有优缺点&#xff0c;适用于不同的场景。下面详细介绍几种主要的容器及其…...

CS144 Lab3 TCPSender复盘

一.基础概念 1.TCPSender在TCPSocket中的地位与作用 Lab0中实现了基于内存模拟的流控制-字节流&#xff08;ByteStream&#xff09;&#xff0c;底层使用std::deque实现&#xff0c;根据最大容量Capacity进行容量控制。个人理解它相当于应用层的输入输出缓存区&#xff0c;用户…...

建筑可视化中使用云渲染的几大理由

在建筑行业中&#xff0c;可视化技术已成为不可或缺的一部分。无论是设计方案的展示、施工进度的模拟&#xff0c;还是最终效果的呈现&#xff0c;建筑可视化都发挥着至关重要的作用。 建筑可视化是指通过计算机技术和图形学算法&#xff0c;将建筑设计、规划和施工过程中的数据…...

Python数据可视化-地图可视化

1.首先绘制实现数据可视化的思维导图 具体要实现什么功能-怎么处理&#xff0c;先把思路写好 数据来源&#xff1a; 爬取的数据 运行结果&#xff1a; 部分代码&#xff1a; 完整代码请在下方↓↓↓&#x1f447;获取 转载请注明出处&#xff01;...

leetcode 动态规划(基础版)单词拆分

题目&#xff1a; 题解&#xff1a; 一种可行的dp做法是基于完全背包问题&#xff0c;将s看成是一个背包&#xff0c;wordDict看作是物品&#xff0c;然后往s中放入物品判断最终是否可以变为给定的s即可。这道题和上一题都用到了在dp如何枚举连续子串和状态表示&#xff1a;枚…...

Ubuntu/Linux调试安装南京来可CAN卡

准备好USB rules文件和can driver文件备用! 必做&#xff1a;放置USB rules文件到对应位置处理权限问题 而后&#xff1a;安装内核driver并编译。需求众多依赖编译环境&#xff0c;视情况安装填补。如GCC,G,make等等 进入对应64bit文件夹中&#xff0c;添加权限&#xff0c;执…...

vue2+TS获取到数据后自动叫号写法

1.父组件写法 初始化&#xff1a; //引入子组件 <odialog ref"odialogRef" onSure"onSurea"></odialog> //子传父private onSurea() {// 初始化信息/重新叫号来的数据this.initTabelData()setTimeout(() > {// 播放声音的数据this.search…...

28、架构-边界:微服务的粒度

微服务的粒度 在设计微服务架构时&#xff0c;确定微服务的粒度是一个关键问题。粒度过大或过小都会带来不同的问题&#xff0c;因此需要找到合理的粒度来划分微服务。下面详细探讨微服务粒度的合理范围及其影响因素。 1. 微服务粒度的上下界 微服务的粒度不应该只有唯一正确…...

开源API网关-ApacheShenYu首次按照启动遇到的问题

一.背景 公司有API网关产品需求&#xff0c;希望有图形化的后台管理功能。看到了ApacheShenYu&#xff0c;作为Apache的顶级项目&#xff0c;直接认可了。首先&#xff0c;感谢各位大神的付出&#xff0c;初步看这个项目是国内大厂中的大神创立的&#xff0c;在此表示膜拜&…...

uniapp获取证书秘钥、Android App备案获取公钥、签名MD5值

一、 uniapp获取证书秘钥 打开uniapp开发者中心下载证书打开cmd输入以下这段代码&#xff0c;下载提供查看到的密钥证书密码就可以了&#xff01;下载证书在 java 环境下运行才可以 // your_alias 换成 证书详情中的别名&#xff0c;your_keystore.keystore 改成自己的证书文件…...

QT 如何储存多种数据类型(QVariant )

QVariant 是 Qt 框架中用于存储各种数据类型的类。它提供了一个强大的类型系统&#xff0c;允许你在运行时存储和检索多种类型的数据&#xff0c;而不需要在编译时确定类型。QVariant 的主要优点在于它的灵活性和通用性&#xff0c;这使得它在 Qt 的很多组件和机制中都被广泛使…...

持续总结中!2024年面试必问的操作系统面试题(九)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问的操作系统面试题&#xff08;八&#xff09;-CSDN博客 十七、解释什么是操作系统的安全性和它的重要性。 操作系统的安全性&#xff08;Operating System Security&#xff09;是指操作系统采取的一系列措施来保…...

操作系统入门 -- 文件管理

操作系统入门 – 文件管理 1.文件管理概述 1.1 文件系统基本功能 目前&#xff0c;计算机内存的容量依然有限&#xff0c;并且其特性决定了数据无法长时间保存&#xff0c;因此把执行的数据以文件形式保存在外存中&#xff0c;等到需要使用时再调入内存。所以&#xff0c;操…...

由浅入深,走进深度学习(2)

今天分享的学习内容主要就是神经网络里面的知识啦&#xff0c;用到的框架就是torch 在这里我也是对自己做一个学习记录&#xff0c;如果不符合大家的口味&#xff0c;大家划走就可以啦 可能没有什么文字或者原理上的讲解&#xff0c;基本上都是代码&#xff0c;但是我还是想说…...

【Python Tips】创建自己的函数包并安装进Anaconda,像引入标准包一样直接import导入

目录 一、引言 二、方法步骤 步骤一&#xff1a;创建包目录结构 步骤二&#xff1a;配置__init__.py文件 步骤三&#xff1a;文件夹外配置setup.py文件 步骤四&#xff1a;终端Pip安装 三、结尾 一、引言 在编写项目代码的时候&#xff0c;有些自定义功能的函数是可以复用的。…...

【Python机器学习实战】 | 基于支持向量机(Support Vector Machine, SVM)进行分类和回归任务分析

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…...

备份和还原

stai和dnta snat&#xff1a;源地址转换 内网---外网 内网ip转换成可以访问外网的ip 内网的多个主机可以使用一个有效的公网ip地址访问外部网络 DNAT&#xff1a;目的地址转发 外部用户&#xff0c;可以通过一个公网地址访问服务内部的私网服务。 私网的ip和公网ip做一个…...

Java数组的初始化方法

Java数组的初始化方法 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java编程中&#xff0c;数组是一种非常基础也非常重要的数据结构&#xff0c;它能够存储…...

通过分离有色和无色pdf页面减少打印费

前言 该工具是我认识的一位中科大的大佬在本科毕业的时候做的一个小工具&#xff0c;去打印店打印全彩的毕业论文的话会比较贵&#xff0c;他想到有没有一种方案可以实现有彩色页面的pdf和没有彩色页面的pdf分开打印&#xff0c;前者打印彩色&#xff0c;后者打印黑白&#xf…...

c语言--指针

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理c语言中指针的相关知识点。 指针概念 指针存储的就是数据的地址。 直观理解: 李华家是北洋路130号1单元101 用变量处理数据: 我们去李华家拿数据。 用指针处理数据: 我们去北洋路130号1单元101拿数据…...

python-九九乘法表(对齐式1)

[题目描述] 输出九九乘法表&#xff0c;输出格式见样例。输入格式&#xff1a; 无输出格式&#xff1a; 输出乘法表&#xff0c;对齐方式见样例输出。样例输入 无样例输出 来源/分类&#xff08;难度系数&#xff1a;一星&#xff09; 完整代码展示&#xff1a; #对齐式1 a[] …...

thinkphp单独为某个接口设置缓存

参考 官方文档 $this->request->cache(__URL__,600);只需要在接口方法的开头添加这个代码即可...

OpenCV视觉--视频人脸微笑检测(超详细,附带检测资源)

目录 概述 具体实现 1.加载分类器 2.打开摄像头并识别人脸 3.处理人脸并检测是否微笑 效果 总结 概述 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习库&#xff0c;广泛应用于图像处理和视频分析等领…...

docker 搭建 AI大数据模型 --- 使用GPU

docker 搭建 AI大数据模型 — 使用GPU方式 搭建本地大模型&#xff0c;最简单的方法&#xff01;效果直逼GPT 服务器GPU系统HP580 G8P40Rocky9.2 安装程序AnythingLLM前端界面Open WebUIChatOllamaollama 一、AnythingLLM 介绍 AnythingLLM 是 Mintplex Labs Inc. 开发的一…...

面向对象, 常用类, 集合, 异常, JDBC, mysql数据库 复习

1.面向对象 &#xff08;1&#xff09;面向过程和面向对象 ● 面向过程的程序设计思想 &#xff08;procedure -Oriented Programming)&#xff0c;简称POP ● 关注的焦点是过程&#xff1a;过程就是操作数据的步骤。如果某个过程的实现代码重复出 现&#xff0c;那么就可…...

js取数组最大值之Math.max、Math.max.apply

js取数组最大值之Math.max、Math.max.apply Math.maxMath.max.applyapply()第一个参数为什么可以是null 最小值同理 Math.max Math.max(n1,n2,n3,…,nX) 支持传递多个参数&#xff0c;带有较大的值的那个数 Math.max(2,5,3,6,2,4,2,15,9,6,0,1)Math.max.apply apply() 语法&a…...

各种中间件的安装

文章目录 20232306mysql的wondows安装 2023 2306 mysql的wondows安装 常用mysql教程 springboot整合druid连接池SpringBoot配置Druid连接池 mysql的wondows安装 MySQL学习笔记 01、MySQL安装 这个是安装的具体思路 win10 安装 mysql 5.7 msi版的教程图文详解 这个是安装的…...

【Mysql】多表查询、隐式内链接、显式内连接、左外连接、右外连接

多表查询 什么是多表查询 •DQL: 查询多张表,获取到需要的数据 •比如 我们要查询家电分类下 都有哪些商品,那么我们就需要查询分类与商品这两张表 数据准备 创建db3_2 数据库 -- 创建 db3_2 数据库,指定编码 CREATE DATABASE db3_2 CHARACTER SET utf8;创建分类表与商品表 …...

Linux驱动开发(三)--新字符设备驱动开发 LED驱动开发升级

1、新字符设备驱动原理 使用 register_chrdev 函数注册字符设备的时候只需要给定一个主设备号即可&#xff0c;但是这样会 带来两个问题 需要我们事先确定好哪些主设备号没有使用 会将一个主设备号下的所有次设备号都使用掉&#xff0c;比如现在设置 LED 这个主设备号为200&…...

MCU的最佳存储方案CS创世 SD NAND

大家都知道MCU是一种"麻雀"虽小&#xff0c;却"五脏俱全"的主控。它的应用领域非常广泛&#xff0c;小到手机手表&#xff0c;大到航空航天的设备上都会用到MCU.市面上目前几个主流厂商有意法半导体&#xff08;其中最经典的一款就是STM32系列&#xff09;…...

40岁学习java是否需要报班学习?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;应该不需要。各种公开免费的…...

Vitis Accelerated Libraries 学习笔记--OpenCV 运行测试

目录 1. 简介 2. 实例测试 2.1 实例介绍 2.2 创建工程 2.2.1 创建工程 2.2.2 获取路径 2.2.3 设置路径 2.2.4 打开工程 2.2.5 添加文件 2.2.6 启动 GUI 2.2.7 配置 csim 参数 3 常见错误 3.1 核心共享库报错 4. 总结 1. 简介 在《Vitis Accelerated Libraries …...

加固三防平板如何提高轨道交通系统的运营效率?

在当今快节奏的社会中&#xff0c;轨道交通系统作为城市交通的重要组成部分&#xff0c;其运营效率的提升对于缓解交通拥堵、满足人们的出行需求以及促进城市的发展具有至关重要的意义。而加固三防平板作为一种先进的技术设备&#xff0c;正逐渐在轨道交通领域发挥着关键作用&a…...

Django 靓号管理系统:实现登录功能

本文将详细介绍如何在 Django 靓号管理系统中实现登录功能,包括用户认证、验证码生成、以及中间件的使用。我们将逐步展示所有相关代码,并附带详细注释。 1. 项目结构 首先,让我们看一下项目的基本结构: number ├── manage.py ├── monaco.ttf ├── number │ …...

【Solr 学习笔记】Solr 源码启动教程

Solr 源码启动教程 本教程记录了如何通过 IDEA 启动并调试 Solr 源码&#xff0c;从 Solr9 开始 Solr 项目已由 ant 方式改成了 gradle 构建方式&#xff0c;本教程将以 Solr 9 为例进行演示&#xff0c;IDE 选择使用 IntelliJ IDEA。 Solr github 地址&#xff1a;https://gi…...

Java中的事件驱动编程模型

Java中的事件驱动编程模型 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我将为大家介绍Java中的事件驱动编程模型。事件驱动编程模型是一种以事件为核心驱…...

Python 语法基础一

1.变量 python 中变量很简单&#xff0c;不需要指定数据类型&#xff0c;直接使用等号定义就好。python变量里面存的是内存地址&#xff0c;也就是这个值存在内存里面的哪个地方&#xff0c;如果再把这个变量赋值给另一个变量&#xff0c;新的变量通过之前那个变量知道那个变量…...

从零开始:Spring Boot 中使用 Drools 规则引擎的完整指南

规则引擎作用 规则引擎主要用于将业务逻辑从应用程序代码中分离出来&#xff0c;提高系统的灵活性和可维护性。规则引擎通过预定义的规则来处理输入数据并做出相应的决策&#xff0c;从而实现业务逻辑的自动化和动态调整。 例如 门店信息校验&#xff1a;美团点评在门店信息…...

工业边缘计算网关

1 介绍 HINETG系列边缘计算网关&#xff08;Linux操作系统&#xff09;&#xff0c;是华辰智通的—款面向工业现场设备接入、数据采集、设备监控的工业级边缘计算网关。采用ARM Cortex-A7 800MHz高性能CPU,拥有以太网、串口、CAN口、IO口等丰富的接口&#xff0c;支持以太网、…...

【C++ 初阶路】--- 类和对象(末)

目录 一、const成员1.1 取地址及const取地址操作符重载 二、再谈构造函数2.1 构造函数体赋值2.2 初始化列表2.3 explicit关键字 三、static成员3.1 概念3.2 特性 四、友元4.1 友元函数4.2 友元类 五、内部类六、匿名对象 一、const成员 将const修饰的“成员函数”称之为const成…...

bable 【实用教程】

简介 bable 用于将 ES6 的语法编译为 ES5 只关心语法&#xff0c;不关心 API 是否正确。不处理模块化&#xff08;webpack 会处理&#xff09; 搭建开发环境 安装相关的包 npm i babel/cli babel/core babel/preset-env新建文件 .babelrc&#xff0c;内容为 { "presets…...

Android中使用startActivityForResult启动活动

Android中使用startActivityForResult启动活动 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将深入探讨Android开发中使用startActi…...

Qt 基础组件速学 鼠标和键盘事件

学习目标&#xff1a; 鼠标事件和键盘事件应用 前置环境 运行环境:qt creator 4.12 学习内容和效果演示&#xff1a; 1.鼠标事件 根据鼠标的坐标位置&#xff0c;做出对应的事件。 2.键盘事件 根据键盘的输入做出对应操作 详细主要代码 1.鼠标事件 #include "main…...

数据结构历年考研真题对应知识点(串的模式匹配)

目录 4.2串的模式匹配 4.2.2串的模式匹配算法——KMP算法 【KMP 匹配过程中指针变化的分析(2015)】 【KMP 匹配过程中比较次数的分析(2019)】 4.2串的模式匹配 4.2.2串的模式匹配算法——KMP算法 【KMP 匹配过程中指针变化的分析(2015)】 最终得到子串指针变化公式 jnex…...

UnityUGUI之八 InputField

custom&#xff1a; 1.当对Inputfield的属性输入一段值时&#xff0c;其子物体也会产生相同的值 监听检测&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class InputField01 : MonoBehaviour {p…...

C++ 的常见算法 之一

C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...

rs轨迹校验

最近发现有些网站的rs似乎上了轨迹校验&#xff0c;附图&#xff1a; 写了个解rscookie的插件&#xff0c;可以精准看到rs更改了那些校验点&#xff0c;需要做什么处理&#xff0c;就很舒服 有需要轨迹代码或者瑞数相关的可以联系 let v huaqu0727...

解决HTTP 400 Bad Request错误的方法

解决HTTP 400 Bad Request错误的方法 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在进行网络通信时&#xff0c;HTTP 400 Bad Request错误是相对常见的问题…...

房地产行业大宗交易活跃房企出售资产谋转型

近期,房地产行业大宗交易活跃,不少上市公司发布公告,拟收购地产商办类项目或相关股权。多位业内人士认为,在市场持续筑底回升的背景下,涉房企业正加快资产处置、资金回笼速度,随着相应重资产项目的持续出清,不少房企的债务压力或将得到缓解,也有望通过轻资产业务谋求转…...

将于2024北京车展首发东风奕派eπ008预告图发布

近日,东风奕派发布 eπ008 最新预告图。新车此前已经登录工信部申报目录,并将于 4 月开幕的 2024 北京车展上迎来首发亮相。外观方面,新车采用了封闭式的前脸设计,整体风格会偏于圆润。同时搭载了当下流行的贯穿式日间行车灯,并将大灯也融入于此。车身尺寸方面,新车长宽高…...

日系车企的“吸金”秘籍:“谨慎”与“激进”并存

近日,日系车企三强丰田、本田、日产相继发布2023财年财报。其中,丰田成为全球最为“吸金”的车企,超过中国目前排名前十车企利润的总和,也是日本近400万家企业中,营业利润首次超过5万亿日元的上市公司。同时,日产和本田也在本财年交出了一份优异的“答卷”,在营收和利润…...

Java基础学习:深入解析Java中的位运算符

在Java中&#xff0c;位运算符用于对整数类型的值进行位运算。以下是Java中的位运算符&#xff1a; 位与(&)&#xff1a;两位都为1时&#xff0c;结果为1&#xff0c;否则为0。 位或(|)&#xff1a;两位中有1个为1&#xff0c;结果为1。 位非(~)&#xff1a;位的反&#…...

深入解析Web前端三大主流框架:Angular、React和Vue

Web前端三大主流框架分别是Angular、React和Vue。下面我将为您详细介绍这三大框架的特点和使用指南。 Angular 核心概念: 组件(Components): 组件是Angular应用的构建块,每个组件由一个带有装饰器的类、一个HTML模板、一个CSS样式表组成。组件通过输入(@Input)和输出(…...

SAP 生产订单报工函数BAPI_PRODORDCONF_CREATE_TT不返回报错信息

最近财务一直反馈MES报工的数据都没有成本,然后去查看原因发现是财务当月的KP26的价格没有进行维护,导致没有收集到工单的报工成本。 但是在前台操作CO11 报工的时候,系统会给出报错的信息 但是我们在调用函数BAPI_PRODORDCONF_CREATE_TT的时候,系统并没有返回报错的信息…...