Redis 集群的三种配置方式案例_redis 集群配置
前言
Redis 有三种集群模式:
- 主从复制
- 哨兵 (Sentinel)
- 集群 (Cluster)
主从复制 读写分离
在多个 redis 实例建立起主从关系,当主 redis 中的数据发生变化,从 redis 中的数据也会同步变化。
通过主从配置可以实现 redis 数据的备份(从 redis 就是对主 redis 的备份),保证数据的安全性; 通过主从配置可以实现 redis 的读写分离
条件有限我是在一台机器上演示的?,使用多个不同的 redis.conf 来启动服务,相当于多台 redis,我这里就用 3 个 redis 服务来演示,我使用的 redis 版本是 5.0.5,废话少说开始演示。
- 在 redis 目录创建文件夹存放主从复制的配置
mkdir msconf
- 把 redis 目录下的 redis.conf 复制到 msconf,作为主服务的配置
cp redis.conf msconf/redis-master.conf
- 修改 redis-master.conf 配置
port 6380
pidfile /var/run/redis_6380.pid
dump_6380.rdb
appendonly_6380.aof
在拷贝 2 份作为 slave 从服务端口 (6381,6382),直接使用快捷操作,省的修改端口号
sed 's/6380/6381/g' redis-master.conf > redis-slave1.conf
sed 's/6380/6382/g' redis-master.conf > redis-slave1.conf
- 修改 slave 配置文件,跟从 6380
slaveof 127.0.0.1 6380 #master的ip、端口,我redis都在本机所有可以写127.0.0.1
masterauth 123456 #这个是master的密码
- 根据配置启动三个 redis 实例
redis-server redis-master.conf &
redis-server redis-slave1.conf &
redis-server redis-slave2.conf &
启动 slave 节点的时候发现日志中连接 master 节点
- 测试
在主 (master) 写入数据,在 slave1、slave2 中查询
哨兵模式 (高可用)
主从切换技术的⽅法是:当主服务器宕机后,需要⼿动把⼀台从服务器切换为主服务器,这就需要⼈⼯⼲预,费事费⼒,还会造成⼀段时间内服务不可⽤。这不是⼀种推荐的⽅式,更多时候,我们优先考虑哨兵模式。Redis 从 2.8 开始正式提供了 [Sentinel](https://so.csdn.net/so/search?q=Sentinel&spm=1001.2101.3001.7020)(哨兵) 架构来解决这个问题。谋朝篡位的⾃动版,能够后台监控主机是否故障,如果故障了根据投票数⾃动将从库转换为主库。哨兵模式是⼀种特殊的模式,⾸先 Redis 提供了哨兵的命令,哨兵是⼀个独⽴的进程,作为进程,它会独⽴运⾏。其原理是哨兵通过发送命令,等待 Redis 服务器响应,从⽽监控运⾏的多个 Redis 实例
这⾥的哨兵有两个作⽤
通过发送命令,让 Redis 服务器返回监控其运⾏状态,包括主服务器和从服务器。
当哨兵监测到 master 宕机,会⾃动将 slave 切换成 master,然后通过发布订阅模式通知其他的从服务器,修改配置⽂件,让它们切换主机。然⽽⼀个哨兵进程对 Redis 服务器进⾏监控,可能会出现问题,为此,我们可以使⽤多个哨兵进⾏监控。各个哨兵之间还会进⾏监控,这样就形成了多哨兵模式
假设主服务器宕机,哨兵 1 先检测到这个结果,系统并不会⻢上进⾏ failover 过程,仅仅是哨兵 1 主观的认为主服务器不可⽤,这个现象成为主观下线。当后⾯的哨兵也检测到主服务器不可⽤,并且数量达到⼀定值时,那么哨兵之间就会进⾏⼀次投票,投票的结果由⼀个哨兵发起,进⾏ failover[故障转移] 操作。切换成功后,就会通过发布订阅模式,让各个哨兵把⾃⼰监控的从服务器实现切换主机,这个过程称为客观下线。
哨兵配置前提
-
首先完成主从配置
-
创建并启动三个哨兵
-
创建文件夹、拷贝 sentinel.conf 文件
mkdir sentinelcnf #创建存放哨兵配置文件夹
cp sentinel.conf sentinelcnf/sentinel-26380.conf #复制哨兵配置模板
- 修改配置文件
vim sentinel-26380.conf
#修改内容:
port 26380 #哨兵端口
pidfile /var/run/redis-sentinel-26380.pid
sentinel monitor mymaster 127.0.0.1 6380 2 #127.0.0.1 6380:监听主 2:有几个哨兵确认他宕机就是真的宕机,一般写n+1 一半多一个,例如有3个哨兵他的一般就是1+1就写2,例如5个哨兵一般就是2+1,就写3
sentinel auth-pass <master-name> <password> #redis密码 sentinel auth-pass mymaster 123456
- 快捷拷贝另外 2 个哨兵配置
sed 's/26380/26381/g' sentinel-26380.conf > sentinel-26381.conf
sed 's/26380/26382/g' sentinel-26380.conf > sentinel-26382.conf
编辑每个 sentinel.conf 配置
vim sentinel-26380.conf
#删除
sentinel myid 1552e6c9be7f8294d0ef8d90c8ef6b590c708c30 #这行没用可以删除
#添加
sentinel down-after-milliseconds mymaster 30000 #mymaster30秒没有响应就确认它宕机了,mymaster 是自定义的根据sentinel monitor mymaster 127.0.0.1 6380 2 来确定的
sentinel-26381.conf、sentinel-26382.conf 也是一样的操作
- 安装指令
yum install -y lsof
- 停止 redis 服务 (没有启动可以无视)
lsof -i:6380 #查看pid
kill -9 pid #关闭服务
把 6381、6382 也关了
- 启动 Redis
复制三个窗口来操作
进入 redis 目录
主操作:
cd /usr/local/redis-5.0.5/msconf/
redis-server redis-master.conf
从 1 操作:
cd /usr/local/redis-5.0.5/msconf/
redis-server redis-slave1.conf
从 2 操作:
cd /usr/local/redis-5.0.5/msconf/
redis-server redis-slave2.conf
- 启动哨兵
复制三个窗口
启动哨兵 1:
redis-sentinel /usr/local/redis-5.0.5/sentinelcnf/sentinel-26380.conf
启动时监听到了主从
启动哨兵 2、3
redis-sentinel /usr/local/redis-5.0.5/sentinelcnf/sentinel-26381.conf
redis-sentinel /usr/local/redis-5.0.5/sentinelcnf/sentinel-26382.conf
每个哨兵能监听到主从、以及其他哨兵的加入
测试
- 停止 (mester)6380
从 (slave) 节点的日志开始报错,尝试连接主被拒绝
- 因为设置的 30 秒,等待 30 秒查看哨兵日志...
slave:6381 的日志,直接连接到了新主 6382 了
Cluster 模式 (高可用、高并发同时支持)
说明
- 每个 Redis 节点必须要有一个备机,例如搭建 3 个节点的集群就要有 6 个 redis 实例
- 数据按照 slots 分布式存储在不同的 redis 节点上,节点中的数据可共享,可以动态调整数据的分布
- 可扩展性强,可以动态增删节点 ,最多可扩展 1000 + 节点
- 集群每个节点通过主备 (哨兵模式),可以保证其高可用性
- 创建文件夹
由于我是单机里面操作启动 6 个 redis 所有创建这个文件夹统一放 6 个 redis 配置文件
mkdir cluster-conf
- 拷贝一个配置文件
cat redis.conf | grep -v "#"|grep -v "^$" > cluster-conf/redis-7001.conf
命令解读:
-
cat redis.conf:读取 redis.conf 文件
-
grep -v "#":去除文件中包含 #的所在行
-
grep -v "^$" :去除空格
-
cluster-conf/redis-7001.conf:写到 cluster-conf 目录下的 redis-7001.conf 文件里面
redis.conf 文件内容:
过滤注释的行和换行后的 redis-7001.conf:
- 编辑配置
编辑 redis-7001.conf,修改文件中这些内容,成这样的结果
protected-mode no
port 7001
#bind 127.0.0.1
pidfile /var/run/redis_7001.pid
dbfilename dump_7001.rdb
appendfilename "appendonly_7001.aof"
#下面4个是集群主要配置
clusterd-enable yes #开启支持集群开关
cluster-config-file nodes-7001.conf
cluster-node-timeout 15000
daemonize yes
- 拷贝其它配置 5
上面以及配置了一份还需 5 份配置,端口分别是 7002~7006
sed 's/7001/7002/g' redis-7001.conf > redis-7002.conf
sed 's/7001/7003/g' redis-7001.conf > redis-7003.conf
sed 's/7001/7004/g' redis-7001.conf > redis-7004.conf
sed 's/7001/7005/g' redis-7001.conf > redis-7005.conf
sed 's/7001/7006/g' redis-7001.conf > redis-7006.conf
- 启动 6 个实例
**注意:**记得开放对应端口,安全组,防火墙 (不止要放行 70017006, 因为这个是我们 redis 设置端口,但是集群节点相互发现使用的端口是原端口号加一万,那就也得放行 1700117006),否则在第六步会一直卡在 Waiting for the cluster to join ....
redis-server redis-7001.conf &
redis-server redis-7002.conf &
redis-server redis-7003.conf &
redis-server redis-7004.conf &
redis-server redis-7005.conf &
redis-server redis-7006.conf &
再次查看,多了 6 个 nodes 的配置文件
查看 6 个实例是否启动 ps -ef | grep redis
- 启动集群
语法:redis-cli --cluster create --cluster-replicas [几个备机] -a [密码没有可省略] [ip: 端口...]
备机要和总数除得进,例如 6 个 redis 实例,1 个备机,最终结果是 3 个实例,3 个备机,一个实例和一个备机一组,总共三组
redis-cli --cluster create --cluster-replicas 1 -a 123456 182.61.29.144:7001 182.61.29.144:7002 182.61.29.144:7003 182.61.29.144:7004 182.61.29.144:7005 182.61.29.144:7006
如下图:筛选出了 3 个主,3 个备,并且指定了谁是谁的主
然后是否确认上面的配置,确认输入 "yes" 成功如下
- 进入客户端
7.1 进入
redis-cli -p 7001 #此方法启动是只能进入7001,并且里面的操作是单节点操作,其他节点拿不到
redis-cli -p 7001 -c #此方法才是以集群方式进入
7.2 进入后输入密码才能操作
auth redis密码
7.3 写入值
set k1 666
可能出现异常:
-> Redirected to slot [12706] located at 182.61.29.144:7003
(error) NOAUTH Authentication required.
原因:每次重定向需要输入密码,需要在客户端登录时配置 -a,退出 redis 客户端重新使用如下命令进入
redis-cli -c -p 7001 -a 123456
7.4 继续尝试 7.3 步骤写入成功,在尝试多写入几个值,如下图,发现 【k1 写到了 7003,k2 写到了 7001,k3 也是】
7.5 查询所有 keys
keys *
结果和上面写入时一样,因为 k1 写到了 7003,所有 7001 只能查询到 k2、k3
但是直接 get k1 还是可以拿到值的,直接从 7003 拿,这就证明配置成功!
集群管理
查看集群状态
语法:redis-cli --cluster info ip:端口 -a 密码
示例:redis-cli --cluster info 182.61.29.144:7001 -a 123456
平衡节点槽数量
- 数据槽的迁移可能会导致数据量不平衡, 使用如下命令 (把 7001 节点中的槽的数量做到相对统一),作用: 每个节点的存储,检索效率相对一致
redis-cli --cluster rebalance 182.61.29.144:7001 -a 123456
迁移节点槽
- 在这个集群中有 3 个节点,我想把 7001 干掉, 但是它有数据,所有要把数据迁移到其他节点,我这里案例就迁移到 7002
命令:
redis-cli --cluster reshard 182.61.29.144:7001 -a 123456
How many slots do you want to move (from 1 to 16384)? 5461 #要迁移几个槽
What is the receiving node ID? a5dba591a312fd1f7cd45aa681736ffe5d7cd921 #迁移到那个节点,输入对应节点的Id
Source node #1: 8bca11ccef368d7df3dc6603fc424a271a070155 #那个槽要被迁移,输入对应的id
done #完毕
然后出现是否执行输入 yes
执行完毕后查看集群状态
如上图,7001 已经没有槽了,但是 7002 槽很多,此时输入平衡节点槽命令
再次查看状态,发现槽数量平衡了
删除节点
删除条件:没有数据槽,需要输入节点 id
节点 id 可以使用迁移数据槽的命令来查看,如下图
语法:
redis-cli --cluster del-node (id: 端口) (节点 id) -a (密码没有可忽略)
redis-cli --cluster del-node 182.61.29.144:7001 8bca11ccef368d7df3dc6603fc424a271a070155 -a 123456
再次查看集群状态,这次命令就不能用 7001 会报错 redis-cli --cluster info 182.61.29.144:7002 -a 123456 发现 7001 没了
注意:删除节点会顺便帮你关闭这个节点的服务
添加节点
先启动节点
redis-server /usr/local/redis-5.0.5/cluster-conf/redis-7001.conf &
在添加
语法:redis-cli --cluster add-node (要加入的 ip: 端口) (加入的集群,有 7002、7003 随便输入一个都可以) [-a 密码]
redis-cli --cluster add-node 182.61.29.144:7001 182.61.29.144:7002 -a 123456
再次查看状态,如下图,存在了 7001
主从复制和集群的区别
- 主从复制:一个负责写,N 个负责读
- 集群:每个实例都可以进行读写
高可用:保证 redis 一直处于可用状态,即使出现了故障也有方案保证可用性
高并发:一个 redis 实例已经可以支持多大 11W 并发读操作,或者 8.1W 并发写操作;但是如果对于有更高并发需求的应用来说,可以通过读写分离、集群配置
SpringBoot 连接集群
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
原始连接配置:
spring:
redis:
host: 182.61.29.144
password: 123456
集群连接配置
spring:
redis:
cluster:
nodes: 182.61.29.144:7001,182.61.29.144:7002,182.61.29.144:7003
max-redirects: 3 #连接失败的时候重试几次
password: 123456
测试
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void test2() {
stringRedisTemplate.opsForValue().set("s1", "222");
String s1 = stringRedisTemplate.opsForValue().get("s1");
System.out.println("s1 = " + s1);
}
进入 redis 查看