单体部署Redis
下载安装Redis
检查gcc环境
# 实验环境可以关闭防火墙,使用docker不关
#systemctl stop firewalld.service
#安装gcc
gcc --version
yum install gcc
yum install gcc-c++
#递归创建下载目录
mkdir -p /opt/software/redis
cd /opt/software/redis
wget https://download.redis.io/redis-stable.tar.gz
tar -xzf redis-stable.tar.gz
cd redis-stable
#编译,出错时需要make distclean清理旧编译结果再重新install
make install
#检查是否成功生成
ll /usr/local/bin
配置redis
直接修改官方示例在/opt/software/redis/redis-stable目录下修改redis.conf
bind * -::* 绑定地址
daemonize yes #守护进程
logfile /opt/software/redis/redis-stable/redis.log #指定日志文件
dir /opt/software/redis #指定工作目录
requirepass sda456 #设置默认用户密码,实验环境可以不设置
protected-mode no #安全模式(yes不可以远程连接)
指定配置文件启动redis
redis-server redis.conf
缺点
主从部署Redis
这里使用dokcer部署两个从节点,请不要使用windows版的docker,它无法直接与容器通信
docker容器内redis的配置文件注意几个参数
bind * -::* 绑定地址
daemonize no #不要开启守护进程,否则容器认为程序已经退出
logfile "" #不要指定日志文件,否则docker logs看不到内容,或者绑定宿主机文件
dir ./ #指定工作目录
requirepass sda456 #设置默认用户密码,实验环境可以不设置
protected-mode no #安全模式(yes不可以远程连接)
replicaof ip port #配置主节点的ip端口,默认没有,新增一行。
mkdir -p /opt/docker/mount/redis/redis1/conf
mkdir -p /opt/docker/mount/redis/redis2/conf
mkdir -p /opt/docker/mount/redis/redis3/conf
#放入官方的示例配置后再修改配置文件
docker network create --driver bridge --subnet=192.168.100.0/24 --gateway=192.168.100.1 redis-network
docker run -d \
--name redis1 \
--network redis-network \
--ip 192.168.100.11 \
-p 6379:6379 \
-v /opt/docker/mount/redis/redis1/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis2 \
--network redis-network \
--ip 192.168.100.12 \
-p 6479:6379 \
-v /opt/docker/mount/redis/redis2/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis3 \
--network redis-network \
--ip 192.168.100.13 \
-p 6579:6379 \
-v /opt/docker/mount/redis/redis3/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
缺点
-
数据一致性弱(最终一致)
从节点是异步复制主节点的数据,在主节点宕机前的瞬间,可能有数据尚未同步到从节点。
一旦主节点宕机并被手动或自动切换为新的主节点,可能丢失最后一部分写入的数据。 -
写操作无法扩展
所有写操作必须发送到主节点,写性能无法横向扩展;
多个从节点只能缓解读压力,不能分担写负载。master挂了需要人工干预 -
复制阻塞和延迟
大量写操作时,从节点可能复制延迟严重;
在网络抖动或带宽占满时,主从之间同步可能中断甚至 full sync(全量复制),影响性能。 -
无事务强一致性保障
Redis 主从复制并不保证在事务层面同步执行,比如 MULTI/EXEC 块在主节点执行后,从节点未必能完全同步中间状态。 -
复制链路断开易导致全量同步
如果从节点断线时间较久,或复制 offset 不匹配,Redis 会触发 全量复制(Full Resync),对主节点 IO 是一个大负担。
部署哨兵Redis sentinel
这里使用docker单独开容器部署Redis sentinel方便模拟节点宕机sentinel不宕机的情况。
mkdir -p /opt/docker/mount/redis/redis-sentinel1/conf
mkdir -p /opt/docker/mount/redis/redis-sentinel2/conf
mkdir -p /opt/docker/mount/redis/redis-sentinel3/conf
#放入官方的示例配置后再修改配置文件
docker run -d \
--name redis-sentinel1 \
--network redis-network \
--ip 192.168.100.21 \
-p 26379:26379 \
-v /opt/docker/mount/redis/redis-sentinel1/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.2 \
redis-sentinel /usr/local/etc/redis/sentinel.conf
docker run -d \
--name redis-sentinel2 \
--network redis-network \
--ip 192.168.100.22 \
-p 26479:26379 \
-v /opt/docker/mount/redis/redis-sentinel2/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.2 \
redis-sentinel /usr/local/etc/redis/sentinel.conf
docker run -d \
--name redis-sentinel3 \
--network redis-network \
--ip 192.168.100.23 \
-p 26579:26379 \
-v /opt/docker/mount/redis/redis-sentinel3/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
redis:7.2 \
redis-sentinel /usr/local/etc/redis/sentinel.conf
配置哨兵
daemonize no #不要开启守护进程,否则容器认为程序已经退出
logfile "" #不要指定日志文件,否则docker logs看不到内容,或者绑定宿主机文件
dir ./ #指定工作目录,docker可以不指定
protected-mode no #安全模式(yes不可以远程连接)
replicaof ip port #配置主节点的ip端口,默认没有,新增一行。
sentinel monitor mymaster 127.0.0.1 6379 2 #2表示两个哨兵发现主节点宕机则主节点确实宕机
sentinel down-after-milliseconds mymaster 30000 #判断宕机的周期
sentinel failover-timeout mymaster 180000 #故障节点超时时间
查看哨兵
redis-cli -p 26379 info sentinel
测试主节点宕机
docker stop redis1
#查看日志
docker logs redis-sentinel1
观察到主节点切换日志,主节点切换为redis3(192.168.100.13)
节点重新启动
docker start redis1
重新加入后变成从节点
redis集群
配置容器
删除docker容器
docker stop redis1 redis2 redis3 redis-sentinel1 redis-sentinel2 redis-sentinel3
docker rm redis1 redis2 redis3 redis-sentinel1 redis-sentinel2 redis-sentinel3
创建容器
mkdir -p /opt/docker/mount/redis/redis-master1/conf
mkdir -p /opt/docker/mount/redis/redis-master2/conf
mkdir -p /opt/docker/mount/redis/redis-master3/conf
mkdir -p /opt/docker/mount/redis/redis-slave1/conf
mkdir -p /opt/docker/mount/redis/redis-slave2/conf
mkdir -p /opt/docker/mount/redis/redis-slave3/conf
#放入官方的示例配置后再修改配置文件(6个相同即可)
cp redis.conf /opt/docker/mount/redis/redis-master1/conf
cp redis.conf /opt/docker/mount/redis/redis-master2/conf
cp redis.conf /opt/docker/mount/redis/redis-master3/conf
cp redis.conf /opt/docker/mount/redis/redis-slave1/conf
cp redis.conf /opt/docker/mount/redis/redis-slave2/conf
cp redis.conf /opt/docker/mount/redis/redis-slave3/conf
#想持久化cluster.conf可以
#cluster.conf集群文件无需人为修改
touch /opt/docker/mount/redis/redis-master1/conf/cluster.conf
touch /opt/docker/mount/redis/redis-master2/conf/cluster.conf
touch /opt/docker/mount/redis/redis-master3/conf/cluster.conf
touch /opt/docker/mount/redis/redis-slave1/conf/cluster.conf
touch /opt/docker/mount/redis/redis-slave2/conf/cluster.conf
touch /opt/docker/mount/redis/redis-slave3/conf/cluster.conf
#并给每个容器挂载文件 -v /opt/docker/mount/redis/redis-master1/conf/cluster.conf:/data/{配置文件写的文件cluster-nodes.conf} \
docker run -d \
--name redis-master1 \
--network redis-network \
--ip 192.168.100.11 \
-p 6379:6379 \
-v /opt/docker/mount/redis/redis-master1/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis-slave1 \
--network redis-network \
--ip 192.168.100.21 \
-p 7379:6379 \
-v /opt/docker/mount/redis/redis-slave1/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis-master2 \
--network redis-network \
--ip 192.168.100.12 \
-p 6479:6379 \
-v /opt/docker/mount/redis/redis-master2/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis-slave2 \
--network redis-network \
--ip 192.168.100.22 \
-p 7479:6379 \
-v /opt/docker/mount/redis/redis-slave2/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis-master3 \
--network redis-network \
--ip 192.168.100.13 \
-p 6579:6379 \
-v /opt/docker/mount/redis/redis-master3/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
docker run -d \
--name redis-slave3 \
--network redis-network \
--ip 192.168.100.23 \
-p 7579:6379 \
-v /opt/docker/mount/redis/redis-slave3/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:7.2 \
redis-server /usr/local/etc/redis/redis.conf
bind * -::* 绑定地址
daemonize no #不要开启守护进程,否则容器认为程序已经退出
logfile "" #不要指定日志文件,否则docker logs看不到内容,或者绑定宿主机文件
dir ./ #指定工作目录,docker可以不指定
protected-mode no #安全模式(yes不可以远程连接)
cluster-enabled yes #开启集群
cluster-node-timeout 5000 #集群超时时间
cluster-config-file cluster-nodes.conf #集群配置文件,如果不是docker,在一个系统启动多个实例要确保没有重叠的配置文件名
appendonly yes #AOF持久化
appendfilename "appendonly.aof" #AOF持久化文件如果不是docker,在一个系统启动多个实例要确保没有重叠的配置文件名
dbfilename "dump.rdb"#RDB默认持久化文件如果不是docker,在一个系统启动多个实例要确保没有重叠的配置文件名
#集群不需要replicaof ip port #配置主节点的ip端口,默认没有,新增一行。
#cluster-announce-ip可以配置其他节点访问本节点应使用的地址,否则根据命令的地址进行通信
启动集群
进入其中一个容器登录节点执行命令。cluster-replicas 1表示一个主带一个从。主从由redis自动分配
redis-cli --cluster create \
192.168.100.11:6379 \
192.168.100.12:6379 \
192.168.100.13:6379 \
192.168.100.21:6379 \
192.168.100.22:6379 \
192.168.100.23:6379 \
--cluster-replicas 1
成功搭建集群,查看集群信息
redis-cli cluster info
redis-cli info replication
redis-cli cluster nodes
一共 6 个节点,分配情况如下:
节点 IP | 角色 | 槽位范围 | 跟随哪个主 |
---|---|---|---|
192.168.100.11 | 主 | 0–5460 | - |
192.168.100.12 | 主 | 5461–10922 | - |
192.168.100.13 | 主 | 10923–16383 | - |
192.168.100.22 | 从 | - | 100.11 |
192.168.100.23 | 从 | - | 100.12 |
192.168.100.21 | 从 | - | 100.13 |
故障主节点自动切换测试
关闭容器redis-master1(192.168.100.11),并查看从节点redis-slave2(192.168.100.22)日志
docker stop redis-master1
docker logs redis-slave2
查看redis-slave2(192.168.100.22)的信息发现变成了主节点。重启发现redis-master1,节点变成了
redis-slave2的从节点
docker exec -it redis-slave2 /bin/bash
redis-cli info replication