Redis集群配置

Redis集群

之前介绍了Redis主从复制、Redis哨兵模式。现在介绍Redis集群

三者的区别

主从复制

Redis的主从复制解决了数据的备份,以及读写分离。在主服务器出现损坏的时候从服务器依然可以保证数据的安全。

数据同步
数据同步
数据同步
master
slave
slave
slave

哨兵模式

哨兵模式:哨兵模式保证的是服务整体的可用性,保证在主服务宕机的时候,及时在从服务中选择一个新的主服务继续提供服务。

redis
哨兵
监控
监控
监控
复制
监控
监控
复制
哨兵2
主服务
从服务1
从服务2
哨兵1
哨兵3

Redis集群

上面解决了服务的可用性,数据的安全性,而Redis集群解决的就是高并发问题。Redis集群将数据进行分散。整个Redis分成不同的数据槽,共同分担数据处理任务。

redis
请求
请求
复制
复制
请求
复制
复制
数据请求
主服务1
从服务3
从服务4
主服务2
从服务1
从服务2

Redis集群的原理

redis集群是完全去中心化的,不存在中心节点或者代理节点。Redis集群没有统一的入口,客户端连接集群中任意节点即可。内部节点使用PING-PONG机制完成通讯。每个节点都是一个Redis实例。

节点健康判断

Redis为了判断节点是否监控,集群提供了一个投票机制,如果集群中超过半数节点认为某个节点宕机。那么就认为这个节点宕机了。

集群宕机

当集群中任意一个节点宕机,并且当前节点没有从节点,则认为这个集群宕机了。当然一个节点宕机就认为集群宕机这是和Redis集群实现原理有关。

数据槽

Redis集群内置了16384个slot(哈希槽)。集群将所有物理节点映射到这16384个slot种。当Rredis存放一个数据时,redis会先对这个key进行crc16算法,然后得到结果,再把这个结果对16384进行求余,然后获得余数对应其中一个槽位,然后决定数据放入到哪个节点中。如果某个节点挂了,则该节点对应的slot无法使用,则导致集群无法正常工作。

Redis集群最大数

根据上面可知,Redis一共提供了16384个槽位,所以理论上Redis支持16384个节点。

Redis集群数量

Redis集群最少需要3个节点,这样才可以启动投票机制来确认某节点宕机。同时为了保证当一个节点宕机后整个集群不至于宕机所以,一个主节点至少配置一台从节点来实现高可用,所以一个Redis集群最低值为三主三从一共六个节点。

配置Redis集群

实例中我是单机配置一个三主三从的集群

首先将最原始的Redis解压复制6份,分别对应6379至6384六个端口的服务

修改每个Redis的配置

这里主要修改的有两个地方。端口号(port),打开集群模式

# 6379为默认,除了第一个后续的修改为6380-6384之间
port 6379

# 打开集群模式,之前被注释掉,打开注释
cluster-enabled yes 

# 这是本人习惯,使用后台启动
daemonize yes

启动所有的实例

依次启动所有的实例

cd /usr/local/redis-cluster/redis-6384/src
redis-server ../redis.conf  
cd /usr/local/redis-cluster/redis-6383/src
redis-server ../redis.conf  
cd /usr/local/redis-cluster/redis-6382/src
redis-server ../redis.conf  
cd /usr/local/redis-cluster/redis-6381/src
redis-server ../redis.conf  
cd /usr/local/redis-cluster/redis-6380/src
redis-server ../redis.conf  
cd /usr/local/redis-cluster/redis-6379/src
redis-server ../redis.conf  

觉得麻烦的可以将此写成一个jio本start-redis.sh

设置权限

chmod +x start-redis.sh

启动脚本

./start-redis.sh

验证实例是否启动

使用ps aux|grep redis确定实例全部启动

[root@iZbp1buyhgwtrw6hrp2ugjZ redis-cluster]# ps aux|grep redis    
root     10186  0.0  0.0 156964  7696 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6384 [cluster]
root     10191  0.0  0.0 153892  7684 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6383 [cluster]
root     10193  0.0  0.0 153892  7684 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6382 [cluster]
root     10198  0.0  0.0 153892  7684 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6381 [cluster]
root     10203  0.0  0.0 153892  7684 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6380 [cluster]
root     10211  0.0  0.0 153892  7684 ?        Ssl  14:25   0:00 redis-server 127.0.0.1:6379 [cluster]
root     10216  0.0  0.0 112708   980 pts/0    S+   14:26   0:00 grep --color=auto redis

安装ruby

Redis5.0之后已经不用redis-trib.rb了,至于安装ruby那自然是不需要了。

配置集群

Redis5.0后,创建集群的命令从./redis-trib.rb迁移到redis-cli。新的创建集群的命令为redis-cli --cluster create。可以使用redis-cli --cluster help 查看帮助

[root@iZbp1buyhgwtrw6hrp2ugjZ redis-cluster]# redis-cli --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN
                 --cluster-replicas <arg>
  check          host:port
                 --cluster-search-multiple-owners
  info           host:port
  fix            host:port
                 --cluster-search-multiple-owners
  reshard        host:port
                 --cluster-from <arg>
                 --cluster-to <arg>
                 --cluster-slots <arg>
                 --cluster-yes
                 --cluster-timeout <arg>
                 --cluster-pipeline <arg>
                 --cluster-replace
  rebalance      host:port
                 --cluster-weight <node1=w1...nodeN=wN>
                 --cluster-use-empty-masters
                 --cluster-timeout <arg>
                 --cluster-simulate
                 --cluster-pipeline <arg>
                 --cluster-threshold <arg>
                 --cluster-replace
  add-node       new_host:new_port existing_host:existing_port
                 --cluster-slave
                 --cluster-master-id <arg>
  del-node       host:port node_id
  call           host:port command arg arg .. arg
  set-timeout    host:port milliseconds
  import         host:port
                 --cluster-from <arg>
                 --cluster-copy
                 --cluster-replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

执行下面命令创建集群

# --cluster-replicas 该命令提供从指定主节点复制的副本节点列表。
redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 --cluster-replicas 1

因为我们是单机配置了所有的实例,所以启动的时候会出现一个警告提醒,这里直接yes即可

[root@iZbp1buyhgwtrw6hrp2ugjZ redis-cluster]# redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:6383 to 127.0.0.1:6379
Adding replica 127.0.0.1:6384 to 127.0.0.1:6380
Adding replica 127.0.0.1:6382 to 127.0.0.1:6381
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: b162948201fed0db9d455ed7135df17372852f1d 127.0.0.1:6379
   slots:[0-5460] (5461 slots) master
M: 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50 127.0.0.1:6380
   slots:[5461-10922] (5462 slots) master
M: b204b942459e726fc3a9ab832388940a7b7c07a5 127.0.0.1:6381
   slots:[10923-16383] (5461 slots) master
S: 6be29973a4f0bc9fb7569a0277cb4c8c48d82ad2 127.0.0.1:6382
   replicates b204b942459e726fc3a9ab832388940a7b7c07a5
S: 5fb4fb0ec0949f6dbac4b56fdb982839ce76b66a 127.0.0.1:6383
   replicates b162948201fed0db9d455ed7135df17372852f1d
S: a45b86d6d81cffc907ad5512fbf6fc62e2935701 127.0.0.1:6384
   replicates 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50
Can I set the above configuration? (type 'yes' to accept): 

检查一下集群的完整性

[root@iZbp1buyhgwtrw6hrp2ugjZ redis-cluster]# redis-cli --cluster check 127.0.0.1:6380
127.0.0.1:6380 (677bf6a0...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:6379 (b1629482...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:6381 (b204b942...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:6380)
M: 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50 127.0.0.1:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: a45b86d6d81cffc907ad5512fbf6fc62e2935701 127.0.0.1:6384
   slots: (0 slots) slave
   replicates 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50
S: 6be29973a4f0bc9fb7569a0277cb4c8c48d82ad2 127.0.0.1:6382
   slots: (0 slots) slave
   replicates b204b942459e726fc3a9ab832388940a7b7c07a5
S: 5fb4fb0ec0949f6dbac4b56fdb982839ce76b66a 127.0.0.1:6383
   slots: (0 slots) slave
   replicates b162948201fed0db9d455ed7135df17372852f1d
M: b162948201fed0db9d455ed7135df17372852f1d 127.0.0.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: b204b942459e726fc3a9ab832388940a7b7c07a5 127.0.0.1:6381
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

可以看到All 16384 slots covered所有的槽位都已经分配

删除节点

Redis提供了del-node命令删除节点

# 参数分别对应主机地址,端口,节点ID
redis-cli --cluster del-node host:port node_id

现在我们尝试移除6384节点

[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# redis-cli --cluster del-node 127.0.0.1:6384 'a45b86d6d81cffc907ad5512fbf6fc62e2935701' 
>>> Removing node a45b86d6d81cffc907ad5512fbf6fc62e2935701 from cluster 127.0.0.1:6384
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

这个时候可以查看我们已经移除了一个节点(注意此节点不是被断开集群而是被SHUTDOWN了)

[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# redis-cli --cluster check 127.0.0.1:6380                                               
127.0.0.1:6380 (677bf6a0...) -> 0 keys | 5462 slots | 0 slaves.
127.0.0.1:6379 (b1629482...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:6381 (b204b942...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:6380)
M: 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50 127.0.0.1:6380
   slots:[5461-10922] (5462 slots) master
S: 6be29973a4f0bc9fb7569a0277cb4c8c48d82ad2 127.0.0.1:6382
   slots: (0 slots) slave
   replicates b204b942459e726fc3a9ab832388940a7b7c07a5
S: 5fb4fb0ec0949f6dbac4b56fdb982839ce76b66a 127.0.0.1:6383
   slots: (0 slots) slave
   replicates b162948201fed0db9d455ed7135df17372852f1d
M: b162948201fed0db9d455ed7135df17372852f1d 127.0.0.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: b204b942459e726fc3a9ab832388940a7b7c07a5 127.0.0.1:6381
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

额外增加节点

Redis提供了add-node命令删除节点。

  # 第一个参数为待添加的新节点,第二个参数为cluster中任何一个节点.
redis-cli --cluster add-node new_host:new_port existing_host:existing_port

我们现在把刚才移除的6384节点,启动然后添加回来

[root@iZbp1buyhgwtrw6hrp2ugjZ src]# redis-cli --cluster add-node 127.0.0.1:6384 127.0.0.1:6380

但此时发现新的节点并没有成为某一个节点的从节点。而是直接成了主节点。

[root@iZbp1buyhgwtrw6hrp2ugjZ src]# redis-cli --cluster check 127.0.0.1:6380
127.0.0.1:6380 (677bf6a0...) -> 0 keys | 5462 slots | 0 slaves.
127.0.0.1:6384 (d3fd8a89...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:6379 (b1629482...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:6381 (b204b942...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:6380)
M: 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50 127.0.0.1:6380
   slots:[5461-10922] (5462 slots) master
S: 6be29973a4f0bc9fb7569a0277cb4c8c48d82ad2 127.0.0.1:6382
   slots: (0 slots) slave
   replicates b204b942459e726fc3a9ab832388940a7b7c07a5
S: 5fb4fb0ec0949f6dbac4b56fdb982839ce76b66a 127.0.0.1:6383
   slots: (0 slots) slave
   replicates b162948201fed0db9d455ed7135df17372852f1d
M: d3fd8a89e1c60ae662a17ae702664c4affd5c98c 127.0.0.1:6384
   slots: (0 slots) master
M: b162948201fed0db9d455ed7135df17372852f1d 127.0.0.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: b204b942459e726fc3a9ab832388940a7b7c07a5 127.0.0.1:6381
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

这是因为下面内容会添加一个主节点

redis-cli --cluster add-node <new_ip:new_port> <exist_ip:exist_port>

想要添加此节点成为某一个主节点的从节点需要下面的命令

我们需要使用下面的命令配置指定其主节点

## cluster-slave 指定为从节点 cluster-master-id  指定主节点ID
[root@iZbp1buyhgwtrw6hrp2ugjZ src]# redis-cli --cluster add-node 127.0.0.1:6384 127.0.0.1:6380 --cluster-slave --cluster-master-id  677bf6a0d6d19e5a78c1a1d8697173ec9507fb50

现在新的节点已经成了6380的从节点

[root@iZbp1buyhgwtrw6hrp2ugjZ src]# redis-cli --cluster check 127.0.0.1:6380
127.0.0.1:6380 (677bf6a0...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:6379 (b1629482...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:6381 (b204b942...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:6380)
M: 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50 127.0.0.1:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: e21638ec15c7da9f8b3bca9d5cc104cb94213c71 127.0.0.1:6384
   slots: (0 slots) slave
   replicates 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50
S: 6be29973a4f0bc9fb7569a0277cb4c8c48d82ad2 127.0.0.1:6382
   slots: (0 slots) slave
   replicates b204b942459e726fc3a9ab832388940a7b7c07a5
S: 5fb4fb0ec0949f6dbac4b56fdb982839ce76b66a 127.0.0.1:6383
   slots: (0 slots) slave
   replicates b162948201fed0db9d455ed7135df17372852f1d
M: b162948201fed0db9d455ed7135df17372852f1d 127.0.0.1:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: b204b942459e726fc3a9ab832388940a7b7c07a5 127.0.0.1:6381
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

对接集群时的问题

Node 127.0.0.1:6379 is not empty

组建集群的时候Redis要求所有的实例必须是空的,所以此时需要将redis启动目录中的appendonly.aof,nodes.conf,dump.rdb这几个文件存在则删除。

Some slaves are in the same host as their master

系统检测到你集群里面主从可能存在在一个主机上,这样当一个主机宕机主从就会全部宕机,高可用意义就不存在了。当然这里是测试的所以放在一个服务器上可以直接yes跳过

新添加的组件没有分配数据槽slots为空

需要使用下面的命令重新分配数据槽

# cluster-from:表示slot目前所在的节点的node ID,多个ID用逗号分隔
# cluster-to:表示需要新分配节点的node ID(貌似每次只能分配一个)
# cluster-slots:分配的slot数量
redis-cli --cluster reshard 127.0.0.1:6385 --cluster-from 677bf6a0d6d19e5a78c1a1d8697173ec9507fb50,b162948201fed0db9d455ed7135df17372852f1d,b204b942459e726fc3a9ab832388940a7b7c07a5 --cluster-to 新的节点ID --cluster-slots 1024

Spring Boot2 集成Redis

这里我使用了我以前项目作为模板: redis简单使用 当然只是修改了配置,其他的没有修改

主要的变动在配置方面的变化

spring:
  application:
    name: sample.redis
  redis:
    jedis:
      pool:
        #最大连接数据库连接数,设 0 为没有限制
        max-active: 8
        #最大等待连接中的数量,设 0 为没有限制
        max-idle: 8
        #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
        max-wait: -1ms
        #最小等待连接中的数量,设 0 为没有限制
        min-idle: 0
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        max-wait: -1ms
        min-idle: 0
      shutdown-timeout: 1000ms
    cluster:
      # 此处需要配置每个实例的节点 
      nodes: 127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6383,127.0.0.1:6384
    password: 密码

server:
  port: 8000


此处一个疑问(主要是懒不想去测试了),根据官方说法

The initial configuration points driver libraries to an initial set of cluster nodes. Changes resulting from live cluster reconfiguration are kept only in the native driver and are not written back to the configuration.

https://docs.spring.io/spring-data/redis/docs/current/reference/html/#_enabling_redis_cluster

spring.redis.cluster.node只是一个初始配置,Redis端进行节点的新增和删除,没法被回写到配置中,但是在本机驱动中会保留?现在我有个疑问假如我在初始就只填写部分节点。这个时候Spring会从Redis里面拉取完整的节点来补完整个集群的节点信息么?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值