Redis集群安装
Redis集群安装
1.集群介绍
首先要了解,Redis的高可用机制。
- 2个master节点,挂掉1个,1不过半,则集群宕机,不可用,容错率为0;
- 3个master节点,挂掉1个,2>1,还可正常运行,容错率为1;
- 4个master节点,挂掉1个,3>1,还可正常运行,但是当宕掉2个时,2=2,不过半,容错率依然为1;
所以结合硬件资源,以及应用实际需求来评估,一般3主3从最优,即6节点模式。
Redis集群的基本工作原理:
Redis集群的每个主节点负责一部分哈希槽(slot),而从节点则作为主节点的副本,当主节点宕机时,从节点可以升级为主节点。
这里规划的是3台服务器,每台上面1主1从,从而形成 3 master + 3 slave 的集群模式。
OS: CentOS Linux release 7.9.2009 (Core)
机器:
IP | cpu | 内存 | 存储 |
---|---|---|---|
10.28.19.101 | 8 核 | 32 G | 100 G |
10.28.19.102 | 8 核 | 32 G | 100 G |
10.28.19.103 | 8 核 | 32 G | 100 G |
2.环境准备
规划
IP地址 | 端口 | 角色 |
---|---|---|
10.28.19.101 | 5000 | Master |
10.28.19.101 | 5001 | Slave |
10.28.19.102 | 5002 | Master |
10.28.19.102 | 5003 | Slave |
10.28.19.103 | 5004 | Master |
10.28.19.103 | 5005 | Slave |
依赖安装
在三台服务器上执行以下命令安装编译工具:
yum install -y gcc tcl make wget
ssh免密访问配置
生成密钥对
在3台机器上分别执行
ssh-keygen -t rsa
cd /root/.ssh
在10.28.19.101机器上执行
cp id_rsa.pub id_rsa_10.28.19.101.pub
在10.28.19.102机器上执行,执行scp时,会提示输入密码
scp /root/.ssh/id_rsa.pub root@10.28.19.101:/root/.ssh/id_rsa_10.28.19.102.pub
在10.28.19.103机器上执行,执行scp时,会提示输入密码
scp /root/.ssh/id_rsa.pub root@10.28.19.101:/root/.ssh/id_rsa_10.28.19.103.pub
在10.28.19.101机器上执行,执行scp时,会提示输入密码
touch authorized_keys
cat id_rsa_10.28.19.10*.pub >> authorized_keys
scp authorized_keys root@10.28.19.102:/root/.ssh
scp authorized_keys root@10.28.19.103:/root/.ssh
在3台机器上分别执行
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
内核参数调优 (添加到/etc/sysctl.conf):
vm.overcommit_memory = 1
vm.swappiness = 0
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
fs.file-max = 65535
参数 | 推荐值 | 作用 | 典型应用场景 |
---|---|---|---|
vm.overcommit_memory | 1 | 允许内存过度提交,避免fork失败 | Redis持久化、高并发内存分配 |
vm.swappiness | 0 | 禁用主动交换,防止Redis数据页被换出 | Redis内存数据库 |
net.core.somaxconn | 65535 | 增大监听队列长度,避免高并发连接被丢弃 | Redis高并发连接接入 |
net.ipv4.tcp_max_syn_backlog | 65535 | 增大SYN队列长度,防止握手阶段连接被丢弃 | 防DDoS攻击、高并发连接建立 |
net.ipv4.tcp_fin_timeout | 30 | 缩短TIME_WAIT 时间,加速端口和内存回收 | Redis短连接密集型业务(如API网关) |
fs.file-max | 65535 | 确保系统有足够的资源支持高并发,同时防止因单个进程配置过高导致其他进程资源不足。 | Redis高并发连接接入 |
以上配置,可显著提升Redis在高并发、高内存压力下的稳定性和性能,同时降低因系统限制导致的服务中断风险。
文件描述符限制 (添加到/etc/security/limits.conf):
redis soft nofile 65535
redis hard nofile 65535
通过设置soft nofile
和hard nofile
为65535,可以确保Redis进程在高负载情况下不会因为文件描述符不足而出现问题,从而保证服务的稳定性和可靠性。
透明大页(THP)禁用 (添加到/etc/rc.local):
编辑/etc/rc.local
文件(如果存在),添加以下行:
if test -f /sys/kernel/mm/transparent_hugepage/enabled; thenecho never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; thenecho never > /sys/kernel/mm/transparent_hugepage/defrag
fi
禁用透明大页(THP)可以显著提高Redis集群的性能,减少内存分配延迟,避免内存碎片化,提高响应速度,并确保Redis的稳定运行。在安装Redis集群时,建议禁用THP以获得最佳性能。
3.安装Redis
下载与编译
在每台服务器上操作:
cd /usr/local
wget https://download.redis.io/releases/redis-7.4.0.tar.gz
tar -zxvf redis-7.4.0.tar.gz
cd redis-7.4.0
make && sudo make install
创建集群目录
每台服务器按端口创建配置和数据目录:
在 10.28.19.101 上执行
mkdir -p /opt/redis-cluster/{5000/{data,logs},5001/{data,logs}}
在 10.28.19.102 上执行
mkdir -p /opt/redis-cluster/{5002/{data,logs},5003/{data,logs}}
在 10.28.19.103 上执行
mkdir -p /opt/redis-cluster/{5004/{data,logs},5005/{data,logs}}
3.配置节点
在10.28.19.101机器上执行下面步骤
编写配置文件模板:
cat << \EOF > /opt/redis-cluster/redis_conf.template
################################## 基础配置 ####################################
# 网络与进程
# 绑定IP地址(0.0.0.0表示允许所有网络接口访问)
bind 0.0.0.0
# 实例端口(5000/5001/5002/5003/5004/5005等)
port ${PORT}
# 守护进程模式
daemonize yes
# PID文件路径
pidfile /opt/redis-cluster/${PORT}/redis_${PORT}.pid
# 高并发场景提升连接队列
tcp-backlog 65535
# TCP保活检测(秒)
tcp-keepalive 300
# 关闭保护模式(集群模式下不需要)
protected-mode no# 日志与监控
# 日志级别(notice适合生产环境)
loglevel notice
# 日志路径(确保目录权限)
logfile "/opt/redis-cluster/${PORT}/logs/redis_${PORT}.log"
# 记录>10ms的操作(单位微秒)
slowlog-log-slower-than 10000
# 慢查询日志最大条目
slowlog-max-len 1024
# 延迟监控阈值(单位毫秒)
latency-monitor-threshold 100################################# 内存与持久化 #################################
# 数据文件目录
dir /opt/redis-cluster/${PORT}/data
# 内存管理
# 实例内存限制(32G总内存留8G给系统,分配12GB,占可用内存的50%)
maxmemory 12gb
# 淘汰策略(根据过期键LRU淘汰)
maxmemory-policy volatile-lru
# 淘汰采样精度
maxmemory-samples 10
# 异步内存回收(避免大Key阻塞)
lazyfree-lazy-eviction yes# RDB快照配置
# 1小时1次修改触发快照
save 3600 1
# RDB失败仍允许写入(防雪崩)
stop-writes-on-bgsave-error no
# 启用压缩
rdbcompression yes
# 启用校验和
rdbchecksum yes
# RDB文件名
dbfilename "dump_${PORT}.rdb"# AOF配置(建议开启)
# 启用AOF持久化
appendonly yes
appendfilename "appendonly_${PORT}.aof"
# 每秒刷盘(平衡性能与安全)
appendfsync everysec
# 重写期间不同步(提升性能)
no-appendfsync-on-rewrite yes
# AOF增长80%触发重写
auto-aof-rewrite-percentage 80
# AOF最小重写大小
auto-aof-rewrite-min-size 2gb
# 混合持久化(RDB+AOF头部)
aof-use-rdb-preamble yes################################ 集群配置 ###################################
# 集群核心参数
# 启用集群模式
cluster-enabled yes
# 集群节点配置文件
cluster-config-file nodes_${PORT}.conf
# 节点超时时间(毫秒,建议15秒)
cluster-node-timeout 15000
# 部分槽位失效仍可用
cluster-require-full-coverage no# 集群网络通信
# 节点真实IP(如10.28.19.101)
#cluster-announce-ip ${IP}
# 节点服务端口
#cluster-announce-port ${PORT}
# 集群总线端口(通常为服务端口+10000)
#cluster-announce-bus-port ${BUS_PORT}
# 无盘复制(SSD建议开启)
repl-diskless-sync yes
# 无盘复制等待时间(秒)
repl-diskless-sync-delay 5
# 复制积压缓冲区(提升主从容灾)
repl-backlog-size 512mb############################### 性能优化 ###################################
# 数据结构优化
# 小哈希使用ziplist
hash-max-ziplist-entries 512
# (单位字节)
hash-max-ziplist-value 64
# 小有序集合优化
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# 主动Rehash(内存碎片整理)
activerehashing yes
# 普通客户端限制(处理常规请求,需防止大结果集/慢查询导致内存失控)
client-output-buffer-limit normal 1gb 512mb 300
# 从节点复制连接限制(主从同步专用,需平衡同步延迟与内存消耗)
client-output-buffer-limit replica 2gb 1gb 120
# 发布订阅客户端限制(高频消息场景需控制突发流量)
client-output-buffer-limit pubsub 128mb 32mb 30
EOF
模板当中,只需要修改 ${PORT}
、${IP}
、${BUS_PORT}
这里写了一个脚本,批量生成集群6个节点的所有配置文件。
批量生成所有节点配置文件:
cat << \EOF > /opt/redis-cluster/generate_redis_configs.sh
#!/bin/bash# 节点列表 (IP:Port)
nodes=("10.28.19.101:5000""10.28.19.101:5001""10.28.19.102:5002""10.28.19.103:5003""10.28.19.103:5004""10.28.19.103:5005"
)# 模板文件路径
TEMPLATE_FILE="./redis_conf.template"# 遍历所有节点生成配置
for node in "${nodes[@]}"; do# 提取IP和端口IFS=':' read -ra ADDR <<< "${node}"IP="${ADDR[0]}"PORT="${ADDR[1]}"BUS_PORT=$((PORT + 10000))# 生成配置文件路径CONFIG_FILE="redis_${PORT}.conf"# 使用 sed 替换模板变量sed -e "s|\${PORT}|${PORT}|g" \-e "s|\${IP}|${IP}|g" \-e "s|\${BUS_PORT}|${BUS_PORT}|g" \"${TEMPLATE_FILE}" > "${CONFIG_FILE}"echo "Generated: ${CONFIG_FILE}"
doneecho "All Redis cluster config files generated!"
EOF
授予可执行权限,并批量生成配置文件
cd /opt/redis-cluster/
chmod +x generate_redis_configs.sh
sh generate_redis_configs.sh
同步配置到部署的目录:
cp redis_5000.conf /opt/redis-cluster/5000/
cp redis_5001.conf /opt/redis-cluster/5001/
scp redis_5002.conf root@10.28.19.102:/opt/redis-cluster/5002/
scp redis_5003.conf root@10.28.19.102:/opt/redis-cluster/5003/
scp redis_5004.conf root@10.28.19.103:/opt/redis-cluster/5004/
scp redis_5005.conf root@10.28.19.103:/opt/redis-cluster/5005/
4.启动服务
手动启动节点
在每台服务器上启动对应实例:
在 10.28.19.101 上执行
redis-server /opt/redis-cluster/5000/redis_5000.conf
redis-server /opt/redis-cluster/5001/redis_5001.conf
在 10.28.19.102 上执行
redis-server /opt/redis-cluster/5002/redis_5002.conf
redis-server /opt/redis-cluster/5003/redis_5003.conf
在 10.28.19.103 上执行
redis-server /opt/redis-cluster/5004/redis_5004.conf
redis-server /opt/redis-cluster/5005/redis_5005.conf
验证进程状态
ps -ef | grep redis
这里附上停服务命令:
redis-cli -p 5000 shutdown
5.创建集群
执行集群创建命令
在任意一台服务器上运行(需指定所有节点地址):
redis-cli --cluster create \
10.28.19.101:5000 10.28.19.102:5002 10.28.19.103:5004 \
10.28.19.101:5001 10.28.19.102:5003 10.28.19.103:5005 \
--cluster-replicas 1
输入 yes
确认节点分配方案。
验证集群状态
redis-cli -h 10.28.19.101 -p 5000 cluster nodes
也可以使用快速检查集群是否健康
redis-cli --cluster check 10.28.19.101:5000
6.开机自启
在10.28.19.101机器上执行下面步骤
编写systemd服务文件模板:
cat << \EOF > /opt/redis-cluster/redis_service.template
[Unit]
Description=Redis Cluster Node ${PORT}
After=network.target[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /opt/redis-cluster/${PORT}/redis_${PORT}.conf
Restart=always
User=root[Install]
WantedBy=multi-user.target
EOF
批量生成 Systemd 服务文件
cat << \EOF > /opt/redis-cluster/generate_redis_services.sh
#!/bin/bash# 端口列表 (Port)
ports=("5000""5001""5002""5003""5004""5005"
)# 模板文件路径
TEMPLATE_FILE="./redis_service.template"# 遍历所有节点生成配置
for port in "${ports[@]}"; do# 生成配置文件路径SERVICE_FILE="redis_${port}.service"# 使用 sed 替换模板变量sed -e "s|\${PORT}|${port}|g" \"${TEMPLATE_FILE}" > "${SERVICE_FILE}"echo "Generated: ${CONFIG_FILE}"
doneecho "All Redis cluster service files generated!"
EOF
授权可执行权限,并生成服务文件:
cd /opt/redis-cluster
chmod +x generate_redis_services.sh
sh generate_redis_services.sh
为每个实例创建服务:
cp redis_5000.service /etc/systemd/system/
cp redis_5001.service /etc/systemd/system/
scp redis_5002.service root@10.28.19.102:/etc/systemd/system/
scp redis_5003.service root@10.28.19.102:/etc/systemd/system/
scp redis_5004.service root@10.28.19.103:/etc/systemd/system/
scp redis_5005.service root@10.28.19.103:/etc/systemd/system/
启用并启动服务
在 10.28.19.101 上执行
systemctl daemon-reload && systemctl enable redis_5000 && systemctl enable redis_5001
systemctl start redis_5000 && systemctl start redis_5001
在 10.28.19.102 上执行
systemctl daemon-reload && systemctl enable redis_5002 && systemctl enable redis_5003
systemctl start redis_5002 && systemctl start redis_5003
在 10.28.19.103 上执行
systemctl daemon-reload && systemctl enable redis_5004 && systemctl enable redis_5005
systemctl start redis_5000 && systemctl start redis_5001
7.防火墙配置
开放端口
在每台服务器上开放 Redis 服务端口及集群总线端口(服务端口 + 10000):
firewall-cmd --permanent --add-port={5000,5001,15000,15001}/tcp
firewall-cmd --reload
按实际端口,逐个服务器上开放
如果是公司内部网络访问,可以考虑直接关闭与禁用防火墙
systemctl stop firewalld
systemctl disable firewalld
8.验证与测试
写入数据测试
redis-cli -h 10.28.19.101 -p 5000 -c
127.0.0.1:5000> set test_key "Hello Redis"
跨节点读取
redis-cli -h 10.28.19.102 -p 5002 -c get test_key
9.故障知识
✅ 高可用性需求说明
我们部署了由三台服务器组成的 Redis 集群环境,每台服务器上运行一个主节点(Master)和一个从节点(Slave),共计 3 个主节点和 3 个从节点。集群中的每个主节点负责一部分哈希槽(Hash Slot),以实现数据的分布式存储。
我们的目标是:当其中任意一台服务器发生宕机或 Redis 服务不可用时,其余两台服务器上的 Redis 节点仍能正常对外提供服务,确保整个集群的持续可用性。
🧠 Redis 集群故障转移机制回顾
Redis 集群通过主从复制与自动故障转移机制来保障高可用性:
- 每个主节点都有一个对应的从节点,用于实时同步数据。
- 当某个主节点无法访问(如网络中断、服务宕机等),且超过设定的超时时间仍未恢复时,集群将触发故障转移流程。
- 在此过程中,该主节点的从节点会被选举为新的主节点,接替原主节点的工作职责,接管其负责的哈希槽。
📌 场景分析:单台服务器宕机后集群状态变化
假设当前集群结构为:
Node1: Master A + Slave B'
Node2: Master B + Slave C'
Node3: Master C + Slave A'
当 Node1 宕机后,集群状态将发生变化:
- Master A 和 Slave B’ 均不可用。
- 剩余两个健康节点:Master B 和 Master C,以及它们的从节点 Slave C’ 和 Slave A’。
此时,集群会根据 Gossip 协议检测到 Master A 不可达,并在剩余的健康从节点中(Slave C’ 或 Slave A’)选择一个作为新主节点,替代原 Master A 的角色。
最终集群结构如下:
Node2: Master B + Slave C'
Node3: Master C + Slave A'
新选出的 Master A': 来自 Slave C' 或 Slave A'
⚠️ 注意:由于只剩下一个从节点可用,因此新的 Master A’ 将没有自己的从节点,集群进入“部分降级”状态,但仍保持完整哈希槽覆盖,可继续对外提供读写服务。
✅ 总结:满足高可用性要求的关键点
条件 | 是否满足 |
---|---|
单台服务器宕机 | ✅ 是 |
整体集群仍可读写 | ✅ 是 |
自动完成主节点故障转移 | ✅ 是 |
数据完整性与一致性 | ✅ 是(基于主从复制) |
最终形成 3 主 + 1 从 结构 | ✅ 是 |
💡 手工订正集群状态(提高容灾能力)
每台服务器上运行一个主节点(Master)和一个从节点(Slave),当发现哪台服务器上是两个slave时,执行下面脚本:
这里以 10.28.19.101 为例,编写 redis_reset_master_slave_10.28.19.101.sh
#!/bin/bash# 定义变量
NODE_IP="10.28.19.101"
MASTER_PORT=5000
SLAVE_PORT=5001# 获取当前节点ID
MASTER_NODE_ID=$(redis-cli -h $NODE_IP -p $MASTER_PORT cluster nodes | grep myself | awk '{print $1}')
SLAVE_NODE_ID=$(redis-cli -h $NODE_IP -p $SLAVE_PORT cluster nodes | grep myself | awk '{print $1}')echo "[$(date)] 当前节点信息:"
echo "主节点 (5000) Node ID: $MASTER_NODE_ID"
echo "从节点 (5001) Node ID: $SLAVE_NODE_ID"# 步骤1:将5000节点强制接管成为master
echo "[$(date)] 强制将节点 $MASTER_NODE_ID 提升为 master..."
redis-cli -h $NODE_IP -p $MASTER_PORT cluster failover takeoverif [ $? -eq 0 ]; thenecho "[$(date)] 节点 $MASTER_NODE_ID 已成功变更为 master。"
elseecho "[$(date)] 提升 master 失败,请检查集群状态。"exit 1
fi# 等待一段时间确保集群状态更新
sleep 5# 步骤2:将5001设为5000的从节点
echo "[$(date)] 将节点 $SLAVE_NODE_ID 设为 $MASTER_NODE_ID 的从节点..."
redis-cli -h $NODE_IP -p $SLAVE_PORT cluster replicate $MASTER_NODE_IDif [ $? -eq 0 ]; thenecho "[$(date)] 节点 $SLAVE_NODE_ID 已成功设为 $MASTER_NODE_ID 的从节点。"
elseecho "[$(date)] 设置从节点失败。"exit 1
fi# 步骤3:验证结果
echo "[$(date)] 验证集群节点角色..."
redis-cli -h $NODE_IP -p $MASTER_PORT cluster nodes | grep $MASTER_NODE_ID
redis-cli -h $NODE_IP -p $SLAVE_PORT cluster nodes | grep $SLAVE_NODE_IDecho "[$(date)] 操作完成。"
分别在3台机器的 /opt/redis-cluster 目录下创建对应的订正脚本,请注意,每个机器上订正脚本中的ip与端口要正确。
10.28.19.101 /opt/redis-cluster 目录下创建:
vim redis_reset_master_slave_10.28.19.101.sh
chmod +x redis_reset_master_slave_10.28.19.101.sh
10.28.19.102 /opt/redis-cluster 目录下创建:
vim redis_reset_master_slave_10.28.19.102.sh
chmod +x redis_reset_master_slave_10.28.19.102.sh
10.28.19.103 /opt/redis-cluster 目录下创建:
vim redis_reset_master_slave_10.28.19.102.sh
chmod +x redis_reset_master_slave_10.28.19.103.sh
✅ 验证数据同步情况
编写脚本:
cat << \EOF > /opt/redis-cluster/redis_cluster_data_sync_check.sh
#!/bin/bash
# 定义集群任意一个正常节点作为入口
ENTRY_NODE="10.28.19.101:5000"# 测试 Key 前缀和值(确保覆盖不同哈希槽)
TEST_KEY_PREFIX="cluster_test_"
TEST_VALUE="sync_ok_$(date +%s)"
TEST_KEY_EXPIRE=300 # 测试 Key 过期时间(秒)# 函数:检查主从偏移量一致性
check_replication_sync() {local node_ip=$1local node_port=$2local master_id=$3echo "===== 检查主节点 ${node_ip}:${node_port} 及其从节点 ====="# 获取主节点偏移量master_offset=$(redis-cli -h $node_ip -p $node_port INFO replication | grep "master_repl_offset" | awk -F: '{print $2}' | tr -cd '[:digit:]')echo "主节点 ${master_id} 偏移量: ${master_offset:-0}"# 查找所有从节点slaves=$(redis-cli -h $node_ip -p $node_port CLUSTER NODES | grep -E "slave" | grep "master=${master_id}" | awk '{print $2}' | cut -d@ -f1)for slave in $slaves; doslave_ip=$(echo $slave | cut -d: -f1)slave_port=$(echo $slave | cut -d: -f2)# 获取从节点偏移量slave_offset=$(redis-cli -h $slave_ip -p $slave_port INFO replication | grep "master_repl_offset" | awk -F: '{print $2}' | tr -cd '[:digit:]')echo "从节点 ${slave_ip}:${slave_port} 偏移量: ${slave_offset:-0}"# 验证一致性if [ "${slave_offset:-0}" -ne "${master_offset:-0}" ]; thenecho "错误:从节点 ${slave_ip}:${slave_port} 数据不同步!"return 1fidoneecho "主从同步正常"return 0
}# 函数:跨节点数据读写验证
test_data_consistency() {local key="${TEST_KEY_PREFIX}$(shuf -i 0-16383 -n 1)" # 随机哈希槽local value="$TEST_VALUE"local result=0# 写入数据(带过期时间,避免残留)echo "===== 测试 Key: ${key} ====="redis-cli -c -h ${ENTRY_NODE%:*} -p ${ENTRY_NODE#*:} \SET ${key} "${value}" EX ${TEST_KEY_EXPIRE} > /dev/null# 从所有节点读取验证cluster_nodes=$(redis-cli -h ${ENTRY_NODE%:*} -p ${ENTRY_NODE#*:} CLUSTER NODES | grep -vE "fail|handshake" | awk '{print $2}' | cut -d@ -f1)for node in $cluster_nodes; donode_ip=$(echo $node | cut -d: -f1)node_port=$(echo $node | cut -d: -f2)read_value=$(redis-cli -c -h $node_ip -p $node_port GET ${key} 2>/dev/null)if [ "$read_value" != "$value" ]; thenecho "错误:节点 ${node_ip}:${node_port} 数据不一致!预期: '${value}',实际: '${read_value}'"result=1elseecho "节点 ${node_ip}:${node_port} 数据一致"fidone# 主动删除测试 Key(即使过期时间存在也立即清理)redis-cli -c -h ${ENTRY_NODE%:*} -p ${ENTRY_NODE#*:} DEL ${key} > /dev/null 2>&1echo "测试 Key ${key} 已清理"return $result
}# 主流程
overall_status=0# 步骤 1:获取所有主节点列表并检查同步状态
masters=$(redis-cli -h ${ENTRY_NODE%:*} -p ${ENTRY_NODE#*:} CLUSTER NODES | grep -E "master" | grep -vE "fail|handshake" | awk '{print $2, $3}')
while read -r node_line; donode_addr=$(echo $node_line | awk '{print $1}')node_ip=$(echo $node_addr | cut -d: -f1)node_port=$(echo $node_addr | cut -d: -f2)master_id=$(echo $node_line | awk '{print $2}')if ! check_replication_sync $node_ip $node_port $master_id; thenoverall_status=1fi
done <<< "$masters"# 步骤 2:跨节点数据读写验证
if ! test_data_consistency; thenoverall_status=1
fi# 步骤 3:检查集群状态
cluster_check=$(redis-cli --cluster check $ENTRY_NODE | grep -E "OK|ERROR")
if [[ $cluster_check == *"OK"* ]]; thenecho "集群状态正常:所有 16384 个槽位已分配"
elseecho "集群状态异常:$cluster_check"overall_status=1
fiexit $overall_status
EOF
授予执行权限:
chmod +x redis_cluster_data_sync_check.sh
执行redis_cluster_data_sync_check.sh
即可验证集群数据同步情况。
10.引用Reference
- CentOS8搭建nfs服务
- Kubernetes1.25.4版本安装
- kubeasz安装kubernetes1.25.5
- k8s一键安装redis单机版
- k8s一键安装mysql8单机版
- k8s部署springboot应用
- Docker安装及学习
- Docker制作springboot运行应用镜像
- Docker制作Java8环境镜像
- Docker安装Mysql5.7.31
- Docker安装Mysql8.1.0
- Elasticsearch单机版本安装
- Elasticsearch集群安装
- ELK安装
- Docker安装ELK
- zookeeper集群安装
- Nginx日志切割
- RabbitMQ集群安装
- Docker安装RabbitMQ单机版
- springboot集成prometheus+grafana
- windows11安装android应用
- Windows下多个JDK版本快速切换
- MongoDB主从仲裁模式安装
- MongoDB单机版安装
- Redis集群安装
相关文章:
Redis集群安装
Redis集群安装 1.集群介绍 首先要了解,Redis的高可用机制。 2个master节点,挂掉1个,1不过半,则集群宕机,不可用,容错率为0;3个master节点,挂掉1个,2>1,…...
下载知网外文文献全文的方法
知网和一些外文数据库机构是合作关系,因知网没有订购外文文献全文,所以可以搜到外文文献但不能下载全文,基本提供的都是外文文献摘要。本文就实例演示一下获取知网外文文献全文的方法步骤。 例如下面这篇知网外文文献,该文献被收…...
解决IDEA无法运行git的问题
之前git一直没有问题,今天打开就提示我安装git,自然用git去提交新项目也会遇到问题。 我出现问题的原因是:git路径缺失 文件->设置->git 发现git的路径为空,按照实际位置填写即可...
基于Qt6 + MuPDF在 Arm IMX6ULL运行的PDF浏览器——MuPDF Adapter文档
项目地址:总项目Charliechen114514/CCIMXDesktop: This is a Qt Written Desktop with base GUI Utilities 本子项目地址:CCIMXDesktop/extern_app/pdfReader at main Charliechen114514/CCIMXDesktop 前言 这个部分说的是Mupdf_adaper下的文档的工…...
Ubuntu20.04 搭建Kubernetes 1.28版本集群
环境依赖 以下操作,无特殊说明,所有节点都需要执行 安装 ssh 服务安装 openssh-server复制代码 sudo apt-get install openssh-server修改配置文件复制代码 vim /etc/ssh/sshd_config找到配置项 复制代码 LoginGraceTime 120 PermitRootLogin prohibit-password StrictModes…...
操作系统和数据库账号密码的安全管理、使用,安当SMS凭据管理系统
引言:密码管理困局下的破局之道 在数字化转型的深水区,企业正面临前所未有的密码管理挑战。某跨国制造企业因数据库密码泄露导致核心工艺参数外泄,某三甲医院因运维账号滥用引发百万级医疗数据泄露事件,这些真实案例揭示着传统密…...
Java设计模式之代理模式:从入门到精通(保姆级教程)
1. 代理模式概述 代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用,可以在不改变目标对象代码的情况下增加额外的功能。 1.1 专业概念解释 代理模式:为其他对象提供一种代理…...
单片机-STM32部分:13-1、蜂鸣器
飞书文档https://x509p6c8to.feishu.cn/wiki/V8rpwIlYIiEuXLkUljTcXWiKnSc 一、应用场景 大部分的电子产品、家电(风扇、空调、电水壶)都会有蜂鸣器,用于提示设备的工作状态 二、原理 蜂鸣器是一种将电信号转换为声音信号的器件࿰…...
JVM——方法内联
引入 在现代软件开发中,性能优化始终是一个关键课题。随着硬件架构的不断演进,CPU的主频提升逐渐放缓,而软件复杂度却持续增加,这使得编译器优化技术的重要性日益凸显。方法内联(Method Inlining)作为编译…...
C++类成员
一、内联函数(Inline Functions) 作用 解决频繁调用小函数时的栈内存消耗问题,通过将函数代码直接插入调用点,避免压栈/出栈开销。 定义形式 inline 返回类型 函数名(参数列表) { ... }• 隐式声明:类内直接定义的成员…...
SpringBoot校园失物招领信息平台
SpringBoot校园失物招领信息平台 文章目录 SpringBoot校园失物招领信息平台1、技术栈2、项目说明2.1、登录注册2.2、管理员端截图2.3、用户端截图 3、核心代码实现3.1、前端首页3.2、前端招领广场3.3、后端业务处理 1、技术栈 本项目采用前后端分离的架构,前端和后…...
代码随想录算法训练营第三十八天
LeetCode题目: 1143. 最长公共子序列1035. 不相交的线53. 最大子数组和392. 判断子序列2094. 找出 3 位偶数(每日一题) 其他: 今日总结 往期打卡 1143. 最长公共子序列 跳转: 1143. 最长公共子序列 学习: 代码随想录公开讲解 问题: 给定两个字符串 text1 和 text2࿰…...
Nginx stream模块是连接级别的负载均衡
在Nginx的stream模块中,upstream的权重配置实现的是连接级别的负载均衡,这和http模块不同。 当客户端发起一个新的TCP连接时,Nginx根据各upstream的权重值选择其中一个upstream建立连接,之后该连接上的所有数据传输都由这个upstre…...
贝叶斯算法
贝叶斯算法是一类基于贝叶斯定理的机器学习算法,它们在分类任务中表现出色,尤其在处理具有不确定性和 probabilistic 关系的数据时具有独特优势。本文将深入探讨贝叶斯算法的核心原理、主要类型以及实际应用案例,带你领略贝叶斯算法在概率推理…...
计算机网络:CPU与时钟的关系
在计算机中,CPU(中央处理器)与时钟的关系是核心且密不可分的。时钟信号是驱动CPU运行的“心跳”,决定了计算机执行指令的节奏和协调性。以下是两者的关键关系及作用: 1. 时钟信号:CPU的“节拍器” 时钟频率(Clock Speed) CPU的时钟频率(如3.5 GHz)表示每秒的时钟周期…...
java中强引用、软应用、弱应用、虚引用
在Java中,引用类型决定了对象的生命周期和垃圾回收的时机。Java提供了四种不同的引用类型:强引用、软引用、弱引用和虚引用。每种引用类型的行为和用途不同,了解这些差异对优化内存管理和垃圾回收非常重要。 1. 强引用(Strong Re…...
分析红黑树工程实用的特点
🧭 本节目标 理解红黑树在工程中的优劣势对比红黑树与其他数据结构(AVL 树、跳表、哈希表等)分析红黑树为何成为内核级应用(如 Linux CFS、内存管理)首选总结红黑树工程上的典型使用建议 一、红黑树工程级使用的主要特…...
C/C++ 内存管理深度解析:从内存分布到实践应用(malloc和new,free和delete的对比与使用,定位 new )
一、引言:理解内存管理的核心价值 在系统级编程领域,内存管理是决定程序性能、稳定性和安全性的关键因素。C/C 作为底层开发的主流语言,赋予开发者直接操作内存的能力,却也要求开发者深入理解内存布局与生命周期管理。本文将从内…...
如何使用主机名在 CMD 中查找 IP 地址?
在网络中,每个系统都有一个由几位数字组成的唯一标识,称为 IP 地址。然而,记住它们可能是一项艰巨的任务,尤其是当系统数量众多时。例如,互联网上运行的每个网站都有一个 IP 地址,以便其他系统在需要时可以调用它们,但你认为记住我们访问的每个网站的长串数字是可行的吗…...
解读RTOS:第二篇 · 线程/任务管理与调度策略
1. 引言 在 RTOS 中,线程(Task)是最基本的执行单元,它封装了应用功能、资源使用和优先级属性。任务管理与调度策略决定了系统在多任务场景下的响应速度、资源分配效率与实时性保证。理解并掌握任务创建、状态转换、优先级设计和调度算法,是 RTOS 应用开发的核心内容。 2…...
linux下minio的进程管理脚本
准备工作: 参考链接: Deploy MinIO: Single-Node Single-Drive — MinIO Object Storage for Linux 下载: wget https://dl.min.io/server/minio/release/linux-amd64/minio kill-app.sh #!/bin/bash # 文件名: kill-app.sh…...
论文学习_A Survey of Binary Code Similarity
摘要:二进制代码相似性方法的主要目的是比较两个或多个二进制代码片段,以识别它们之间的相似性与差异(研究背景)。由于在许多实际场景中源代码往往不可获取,因此具备比较二进制代码的能力显得尤为重要,例如…...
python标准库--sys - 系统相关功能在算法比赛的应用
目录 1. 快速输入输出 2. 调整递归深度限制 1. 快速输入输出 算法比赛中,大量数据的读写可能成为瓶颈。sys.stdin和sys.stdout比内置的input()和print()效率更高。 import sys# 读取多行输入(每行一个整数) n int(sys.stdin.readline()) …...
运算放大器相关的电路
1运算放大器介绍 解释:运算放大器本质就是一个放大倍数很大的元件,就如上图公式所示 Vp和Vn相差很小但是放大后输出还是会很大。 运算放大器不止上面的三个引脚,他需要独立供电; 如图比较器: 解释:Vp&…...
进程和线程
目录 1. 基本定义 2. 核心区别 3. 优缺点对比 进程和线程是操作系统中用于实现并发执行的两个核心概念,它们既有相似之处,又有明显的区别。下面从多个维度对它们进行对比分析: 1. 基本定义 进程(Process) 进程是程…...
生成对抗网络(GAN)深度解析:理论、技术与应用全景
生成对抗网络(Generative Adversarial Networks,GAN)作为深度学习领域的重要突破,通过对抗训练框架实现了强大的生成能力。本文从理论起源、数学建模、网络架构、工程实现到行业应用,系统拆解GAN的核心机制,涵盖基础理…...
Java面试全记录:Spring Cloud+Kafka+Redis实战解析
Java面试全记录:Spring CloudKafkaRedis实战解析 人物设定 姓名:张伟(随机生成唯一姓名) 年龄:28岁 学历:硕士 工作年限:5年 工作内容: 基于Spring Cloud搭建微服务架构使用Kafka…...
人脸识别deepface相关笔记
人脸识别deepface相关笔记 项目地址项目结构 项目地址 https://github.com/serengil/deepface.git 项目结构...
量子加密通信:守护信息安全的未来之盾
摘要 在数字化时代,信息安全成为全球关注的焦点。传统加密技术面临着被量子计算破解的风险,而量子加密通信作为一种基于量子力学原理的新型加密技术,提供了理论上无条件安全的通信保障。本文将详细介绍量子加密通信的基本原理、技术实现、应用…...
三、transformers基础组件之Model
1. 什么是Model Head Model Head 是连接在模型后的层,通常为1个或多个全连接层Model Head 将模型的编码的表示结果进行映射,以解决不同类型的任务 不同的任务会有不同的Model Head。 2. 模型加载 2.1 在线加载 预训练模型的加载与Tokenizer类似,我们只需要指定想…...
【语法】C++的多态
目录 虚函数的重写: 虚函数 重写(覆盖) 虚函数重写的两个例外: 协变: 析构函数的重写: 练习: final和override关键字 抽象类 接口继承和实现继承 虚函数重写的原理: 打印虚函数表: …...
WebGIS开发新突破:揭秘未来地理信息系统的神秘面纱
你有没有想过,未来的地理信息系统(GIS)会是什么样子?是像电影里那样,一块透明屏幕就能呈现整个城市的实时动态?还是像《钢铁侠》中那样,一个手势就能操控全球地图? 其实,…...
JVM类加载
JVM类加载 1. 类的生命周期(类加载过程)类加载的五个阶段: 2. 类加载器的分类3. 双亲委派模型4. 类的卸载与热加载5.类加载器命名空间隔离 1. 类的生命周期(类加载过程) 类加载的五个阶段: 加载ÿ…...
AD开启交叉选择功能,只选中器件,不选中网络、焊盘
AD开启交叉选择功能,只选中器件,不选中网络、焊盘。 一、打开首选项 二、打开System→Navigationg,配置如下。 三、最后点击OK即可。...
机器学习——集成学习基础
一、鸢尾花数据训练模型 1. 使用鸢尾花数据分别训练集成模型:AdaBoost模型,Gradient Boosting模型 2. 对别两个集成模型的准确率以及报告 3. 两个模型的预测结果进行可视化 需要进行降维处理,两个图像显示在同一个坐标系中 代码展示&…...
C++匿名函数
C 中的匿名函数(Lambda 表达式)是 C11 引入的一项重要特性,它允许你在需要的地方定义一个临时的、无名的函数对象,使代码更加简洁和灵活。 1. 基本语法 Lambda 表达式的基本结构: [capture list](parameter list) -…...
互联网大厂Java面试实战:Spring Boot到微服务的技术问答解析
💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通 😁 2. 毕业设计专栏,毕业季咱们不慌忙,几百款毕业设计等你选。 ❤️ 3. Python爬虫专栏…...
神经网络是如何工作的
人工智能最核心的技术之一,就是神经网络(Neural Networks)。但很多初学者会觉得它是个黑盒:为什么神经网络能识别图片、翻译语言,甚至生成文章? 本文用图解最小代码实现的方式,带你深入理解&am…...
Kubernetes控制平面组件:Kubelet详解(二):核心功能层
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
【android bluetooth 框架分析 02】【Module详解 13】【CounterMetrics 模块介绍】
1. CounterMetrics 介绍 CounterMetrics 模块代码很少, 我简单介绍一下。 // system/gd/metrics/counter_metrics.cc #define LOG_TAG "BluetoothCounterMetrics"#include "metrics/counter_metrics.h"#include "common/bind.h" #i…...
Matlab自学笔记五十四:符号数学工具箱和符号运算、符号求解、绘图
1.什么是符号数学工具箱? 符号数学工具箱是Matlab针对符号对象的运算功能,它引入了一种特殊的数据类型 - 符号对象; 该数据类型包括符号数字,符号变量,符号表达式和符号函数,还包含符号矩阵,以…...
Matlab 模糊控制平行侧边自动泊车
1、内容简介 Matlab 233-模糊控制平行侧边自动泊车 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
新书速览|纯血鸿蒙HarmonyOS NEXT原生开发之旅
《纯血鸿蒙HarmonyOS NEXT原生开发之旅》 本书内容 《纯血鸿蒙HarmonyOS NEXT原生开发之旅》全面系统地介绍了基于HarmonyOS NEXT系统进行原生应用开发的实用技巧。全书共12章,内容涵盖从基础工具使用到高级功能实现的各个方面。第1章详细介绍了开发环境的搭建、Ar…...
tinyint(3)数据类型讲解
TINYINT(3) 是数据库中用于定义字段数据类型的一种写法,常见于 MySQL 等数据库系统。下面来详细了解其含义和作用: 数据类型本质 TINYINT 属于整数类型,在不同的数据库系统中,它所占用的存储空间和表示范围通常是固定的。以 MyS…...
manjaro系统详解
1. Manjaro 概述 Manjaro 是一款基于 Arch Linux 的滚动更新发行版,以 用户友好、易用性 和 硬件兼容性 为核心设计理念。它继承了 Arch 的灵活性和软件丰富性,同时通过图形化工具和稳定的更新策略降低了使用门槛,适合从新手到高级用户的广泛…...
# 实时英文 OCR 文字识别:从摄像头到 PyQt5 界面的实现
实时英文 OCR 文字识别:从摄像头到 PyQt5 界面的实现 引言 在数字化时代,文字识别技术(OCR)在众多领域中发挥着重要作用。无论是文档扫描、车牌识别还是实时视频流中的文字提取,OCR 技术都能提供高效且准确的解决方案…...
9.3.云原生架构模式
目录 一、云原生架构核心概念 云原生定义与核心原则 • 四大核心要素:容器化、微服务、DevOps、持续交付 • 核心原则:弹性、可观测性、自动化、不可变基础设施 云原生技术矩阵 • 容器与编排:Docker、Kubernetes、CRI-O • 服务治理&#…...
现代化水库运行管理矩阵平台如何建设?
政策背景 2023年8月24日,水利部发布的水利部关于加快构建现代化水库运行管理矩阵的指导意见中指出,在全面推进水库工程标准化管理的基础上,强化数字赋能,加快构建以推进全覆盖、全要素、全天候、全周期“四全”管理,完…...
木马查杀引擎—关键流程图
记录下近日研究的木马查杀引擎,将关键的实现流程图画下来 PHP AST通道实现 木马查杀调用逻辑 模型训练流程...
基于libevent的异步事件驱动型线程池实现
----------------------| IFoxThread | ← 抽象线程接口|----------------------|| dispatch() || start() || stop() || ... |----------^-----------|--------------------|----------------------| …...