Redis复制
查看docker 容器 ip
docker inspect 容器id | grep IPAddressdocker inspect -f='{{.Name}} {{.NetworkSettings.IPAddress}}' $(docker ps -aq)
修改配置文件
初始配置文件见 => redis.conf
- 远程访问
- bind 0.0.0.0
- protected-mode no
- 主机设置
- replicaof 172.17.0.2 6379
- 主机访问密码
- masterauth 111111
redis_6379.conf
bind 0.0.0.0
protected-mode no
port 6379
pidfile /var/run/redis6379.pid
logfile "/data/6379.log"
dbfilename dump6379.rdb
dir /data
masterauth 111111
requirepass 111111
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
redis_6380.conf
bind 0.0.0.0
protected-mode no
port 6379
pidfile /var/run/redis6380.pid
logfile "/data/6380.log"
dbfilename dump6380.rdb
dir /data
replicaof 172.17.0.2 6379
masterauth 111111
requirepass 111111
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
redis_6381.conf
bind 0.0.0.0
protected-mode no
port 6379
pidfile /var/run/redis6381pid
logfile "/data/6381.log"
dbfilename dump6381.rdb
dir /data
replicaof 172.17.0.2 6379
masterauth 111111
requirepass 111111
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
主从复制:一主二从
启动
docker run --name redis79 \
-v /usr/local/redis7.2.4/6379/data:/data \
-v /usr/local/redis7.2.4/6379/conf:/usr/local/etc/redis \
-p 6379:6379 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis6379.conf --port 6379
docker run --name redis80 \
-v /usr/local/redis7.2.4/6380/data:/data \
-v /usr/local/redis7.2.4/6380/conf:/usr/local/etc/redis \
-p 6380:6380 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis6380.conf --port 6380
docker run --name redis81 \
-v /usr/local/redis7.2.4/6381/data:/data \
-v /usr/local/redis7.2.4/6381/conf:/usr/local/etc/redis \
-p 6381:6381 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis6381.conf --port 6381
查看主从信息 info replication
主从问题演示
从机不可以执行写命令
从机从头开始复制
先下线6381(此时master未插入数据),之后master执行set,再上线6381,6381复制master全量数据
主机下线后,主从关系不会变化
可以看到 redis79下线再上线,主从关系没有变化,只是从机的 master_link_status
up down转换
主从复制工作流程
- 建立连接
- 节点发送
slaveof
命令与主节点建立连接
- 节点发送
- 数据同步
- 主节点会执行
bgsave
命令生成RDB快照文件,并将其发送给从节点 - 全量复制=>在节点初始化时,将主节点的数据一次性同步到从节点
- 增量复制=>同步自上次同步之后发生变更的数据(从机重启之后增量复制,具体是记录一个偏移量)
- 主节点会执行
- 命令传播
- 同步完成后,进入命令传播阶段,在此阶段,主节点将持续向从节点发送写命令
Redis哨兵
由于主从复制在master挂了之后,不会自动选取新的master,故引入哨兵。哨兵监控master和slave,当master挂了之后,在slave中选出新master
sentinel.conf
测试架构图
配置文件准备
查看 master 容器 IP,用于后面设置 master IP
sentinel26379.conf
protected-mode no
port 26379
daemonize yes
pidfile /var/run/redis-sentinel26379.pid
logfile "/data/sentinel26379.log"
dir /data
sentinel monitor mymaster 172.17.0.2 6379 2
sentinel auth-pass mymaster 111111
sentinel26380.conf
protected-mode no
port 26380
daemonize yes
pidfile /var/run/redis-sentinel26380.pid
logfile "/data/sentinel26380.log"
dir /data
sentinel monitor mymaster 172.17.0.2 6379 2
sentinel auth-pass mymaster 111111
sentinel26381.conf
protected-mode no
port 26381
daemonize yes
pidfile /var/run/redis-sentinel26381.pid
logfile "/data/sentinel26381.log"
dir /data
sentinel monitor mymaster 172.17.0.2 6379 2
sentinel auth-pass mymaster 111111
启动Redis
docker run --name redis6379 \
-v /usr/local/redis7.2.4/6379/data:/data \
-v /usr/local/redis7.2.4/6379/conf:/usr/local/etc/redis \
-p 6379:6379 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis_6379.conf --port 6379
启动哨兵
docker run --name redis-sentinel26379 \
-v /usr/local/redis7.2.4/6379/conf/sentinel26379.conf:/usr/local/etc/redis/sentinel.conf \
-d 9b38108e295d
docker exec -it redis-sentinel26379 /bin/bash
redis-sentinel /usr/local/etc/redis/sentinel.conf
效果
所有启动的容器展示
搭建完成后哨兵效果
下线 6379 主机之后再上线效果
选举新的master,旧主变为slave
哨兵运行流程和选举原理
1、哨兵集群监控 master
2、sdown
: sentinel 发送心跳包,一定时间没有收到master的回复,就认为主观下线
3、odown
: 当有 quorum 个 sentinel 认为主观下线,就认为 master 客观下线
4、选出哨兵 leader (RAFT算法)
5、哨兵 leader 选出新master slaveof on one
- 比较优先级 `repliica-priority` (优先级数值小的)
- 比较复制偏移量 `offset` (偏移量大的)
- 比较
run id
(run id 小的)
6、leader 让其他 slave 认新master
7、leader 让老master 降级,成为新 master 的 slave
哨兵使用建议
1、使用哨兵集群,保证高可用
2、哨兵节点的数量应该为奇数
3、哨兵集群 + 主从复制,不能保证数据零丢失
Redis集群
redis集群也不保证强一致性
Redis 集群 = 数据分片 + 高可用性。在这种模式下,数据被分散存储在多个节点上,每个节点只保存部分数据。这提高了系统的可扩展性和性能。通过一致性哈希,集群能够实现自动的数据分片,同时通过节点间的通信保持数据的同步和状态的一致。
Redis 哨兵 = 主从复制 + 故障转移。当主节点发生故障时,哨兵节点会自动将从节点升级为新的主节点,并通知其他从节点和客户端更新配置。这种模式的优势在于其自动化的故障恢复机制,提高了系统的可用性,并且配置简单。
业务需要处理大量数据并且要求高性能,集群模式更合适
业务对数据量的要求不高,但希望建立一个简单且具有高可用性的缓存系统,哨兵模式更合适
slot 槽映射 == 三种实现
集群搭建
配置基本相同,改下端口和文件名
bind 0.0.0.0
protected-mode no
port 7301
logfile "/data/cluster7301.log"
pidfile /data/cluster7301.pid
dir /data
dbfilename dump7301.rdb
appendonly yes
appendfilename "appendonly7301.aof"
requirepass 111111
masterauth 111111cluster-enabled yes
cluster-config-file nodes-7301.conf
cluster-node-timeout 5000
启动六个实例
docker run --name redis7301 \
-v /usr/local/redis7.2.4/cluster/data:/data \
-v /usr/local/redis7.2.4/cluster/conf/redis-cluster-7301.conf:/usr/local/etc/redis/redis.conf \
-p 7301:7301 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis.conf --port 7301
docker run --name redis7306 \
-v /usr/local/redis7.2.4/cluster/data:/data \
-v /usr/local/redis7.2.4/cluster/conf/redis-cluster-7306.conf:/usr/local/etc/redis/redis.conf \
-p 7306:7306 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis.conf --port 7306
启动容器并查看IP
docker inspect -f='{{.Name}} {{.NetworkSettings.IPAddress}}' $(docker ps -aq)
构建主从关系
进入容器 redis 7301
docker exec -it redis7301 /bin/bash
将六个节点加入到集群,一主一从
redis-cli -p 7301 -a 111111 --cluster create --cluster-replicas 1 \
172.17.0.7:7306 \
172.17.0.6:7305 \
172.17.0.5:7304 \
172.17.0.4:7303 \
172.17.0.3:7302 \
172.17.0.2:7301
查看集群和节点状态
操作集群
集群需要路由到位 ,即命令中添加
-c
查看key属于哪个槽
cluster keyslot key
主从切换
故障转移
redis7306
重新上线后,主从关系变了,为了改回初始的主从关系,登录到原来的主机使用cluster failover
扩容
docker run --name redis7307 \
-v /usr/local/redis7.2.4/cluster/data:/data \
-v /usr/local/redis7.2.4/cluster/conf/redis-cluster-7307.conf:/usr/local/etc/redis/redis.conf \
-p 7307:7307 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis.conf --port 7307
docker run --name redis7308 \
-v /usr/local/redis7.2.4/cluster/data:/data \
-v /usr/local/redis7.2.4/cluster/conf/redis-cluster-7308.conf:/usr/local/etc/redis/redis.conf \
-p 7308:7308 -d 9b38108e295d \
redis-server /usr/local/etc/redis/redis.conf --port 7308
redis-cli -a 111111 -p 7301 --cluster add-node \
172.17.0.8:7307 \
172.17.0.2:7301
redis-cli -a 111111 -p 7301 --cluster add-node 要加入的节点信息【IP:PORT】 集群中任一节点信息【IP:PORT】
查看集群状态(新节点未分配槽位)
redis-cli -a 111111 -p 7301 --cluster check 【IP:PORT】 集群中的任一节点都能得到信息
重新分配槽位
分配从节点
redis-cli -a 密码 --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
redis-cli -a 111111 -p 7301 --cluster add-node \
172.17.0.9:7308 \
172.17.0.8:7307 \
--cluster-slave --cluster-master-id 4a849f4b3d5e9e6bbf4412e8c86e7904477f4d4b
缩容
删除从节点7308
命令:redis-cli -a 密码 --cluster del-node ip:端口 节点ID
redis-cli -a 111111 -p 7301 --cluster del-node 172.17.0.9:7308 14cca2509252d583b06d3fe521eed8661f7efc15
将主节点7307的槽位重新分配给其他主节点
redis-cli -a 111111 --cluster reshard 172.17.0.2:7301
槽位重新分配,7307也变为从节点
删除原主节点7307
redis-cli -a 111111 -p 7301 --cluster del-node 172.17.0.8:7307 4a849f4b3d5e9e6bbf4412e8c86e7904477f4d4b