redis-高可用
Published: 2022-08-31 17:45:37

## 一、主从

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pub6d4ok0ym7zd68w330.png)

```
1. salve连接master，发送SYNC命令
2. master接收到SYNC命令后，可以执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令
3. master执行BGSAVE后，向所有salve发送快照文件，并在发送期间继续记录被执行的写命令
4. salve收到快照文件后丢弃所有旧数据，载入收到的快照
5. master快照发送完毕后开始向salve发送缓冲区中的写命令
6. salve完成对快照的载入，开始接受命令请求，并执行来自master缓冲区的写命令，salve初始化完成
7. master每执行一个写命令就会向salve发送相同的写命令，salve接收并执行收到的写命令(salve初始化完成后的操作)
8. 出现断开重连后，2.8之后的版本会将断线期间的命令传给从数据库，增量复制。
9. 主从刚刚连接的时候，进行全量同步;
10. 全同步结束后，进行增量同步。
11. slave在任何时候都可以发起全量同步。Redis 的策略是，无论如何，首先会尝试进行增量同步，如不成功，要求从机进行全量同步。
```

slave配置：
```
slaveof 127.0.0.1 6379
#slave只读
slave-read-only yes slave只读
```

命令：
```
#查看主从信息
redis 127.0.0.1:6379>info replication
#关闭master
redis 127.0.0.1:6379>shutdown
#把slave1变成master
redis 127.0.0.1:16379>slaveof no one
#把slave2变成变成slave1的slave
redis 127.0.0.1:26379>slaveof 127.0.0.1 16379
```

## 二、哨兵

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1w6w4figbdujww4nq2o.png)

sentinel配置
```
# 禁止保护模式
protected-mode no
# 配置监听的主服务器，这里sentinel monitor代表监控，mymaster代表服务器的名称，可以自定义，
# 监控127.0.0.1:6379，2代表只有两个或两个以上的哨兵认为主服务器不可用的时候，才会进行failover操作。
sentinel monitor mymaster 127.0.0.1 6379 2
# sentinel author-pass定义服务的密码，mymaster是服务名称，123456是# # redis服务器密码
# sentinel auth-pass mymaster 123456
```
- 
sentinel每秒ping集群中的master/salve/other sentinel
- 
response时间大于down-after-milliseconds，sentinel则认为对方主观下线（SDOWN）
- 
master被标记为主观下线（SDOWN），则所有sentinel每1秒确认master状态
- 
足够数量sentinel认定master下线，则master被标记为客观下线（ODOWN）
- 
sentinel每10秒向集群中master/salve发送info命令
- 
当master客观下线（ODOWN），sentinel则每1秒向集群中salve发送info命令
- 
若没有足够数量的sentinel同意master主观下线，就不会变成客观下线。若 master重新向sentinel发送ping返回有效回复，master主观下线状态就会被移除。

- 
优点

1. 
主从自动切换

- 
缺点

1. 
内存使用率低

1. 
难以扩容

## 三、集群

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oqatxaza7s8dujvvrlcw.png)

cluster配置
```
# 开启redis的集群模式
cluster-enabled yes
# 配置集群模式下的配置文件名称和位置,redis-cluster.conf这个文件是集群启# 动后自动生成的，不需要手动配置。
# cluster-config-file redis-cluster.conf
```
- 
每个节点都会通过集群总线(cluster bus)，与其他的节点进行通信。通讯时使用特殊的端口号，即对外服务端口号加 10000。例如如果某个 node 的端口号是 6379，那么它与其它 nodes 通信的端口号是 16379。nodes 之间的通信采用特殊的二进制协议。

- 
机器规划
```
127.0.0.1 2637(master)
127.0.0.1 2638(salve)
127.0.0.1 3637(master)
127.0.0.1 3638(salve)
127.0.0.1 4637(master)
127.0.0.1 4638(salve)
扩容：
127.0.0.1 5637(master)
127.0.0.1 5638(salve)
```

- 
命令

启动cluster
```
redis-cli --cluster create 127.0.0.1:2379 127.0.0.1:2378 127.0.0.1:3379 127.0.0.1:3378 127.0.0.1:4379 127.0.0.1:4378 --cluster-replicas 1
```
登录cluster
```
redis-cli -c -h 127.0.0.1 -p 2379
```
查看cluster信息
```
127.0.0.1:2378>cluster info
127.0.0.1:2378>cluster nodes
```
扩容，作为master加入cluster，但不检测是否已有数据，且没有分配slot
```
127.0.0.1:2378>cluster meet 127.0.0.1 5379
```
扩容，把new加入到cluster，old是已存在cluster中的，但没分配slot
```
redis-cli --cluster add-node <new_ip>:<new_port> <old_ip>:<old_port>
```
分配slot，随便cluster中的一个node
```
redis-cli --cluster reshard 127.0.0.1:2379
#根据提示指定要被分配的node
#根据提示知道要分配的slot数
```
master分配了slot，添加salve
```
1. 通过slave登录cluster
2. 通过master node id复制数据
#redis-cli -c -h 127.0.0.1 -p 5378
127.0.0.1:5378>cluster replicate <master_node_id>
```
下线
```
redis-cli --cluster reshard 127.0.0.1:2379
# 指定要重新分配的slot数量
# 指定接受slot的node id
# 指定source node id
# 输入done
```
删除node
```
127.0.0.1:2378>cluster forget <node_id>
```

- 
插槽（slot）

```
1. 插槽范围0～16383，会平均分配在master上
2. redis把key通过crc16算法计算出结果，然后和16384求余，找到对应的节点
如果超过1/2的master认为一个master宕机，此master就被下线
3. 如果master和对应salve都宕机，整个集群就挂掉
```
优点：
```
可扩展：可扩展到1000多个节点
高可用：
master挂了，可以自动failover，用投票完成salve到master提升；
节点之间通过gossip协议完成交换信息
```
缺点：
```
gossip有消息的延迟和冗余，浪费一定到带宽
```