【Redis分布式缓存】分片集群

Redis 分片集群

搭建分片集群

集群结构

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

IP PORT 角色
192.168.150.101 7001 master
192.168.150.101 7002 master
192.168.150.101 7003 master
192.168.150.101 8001 slave
192.168.150.101 8002 slave
192.168.150.101 8003 slave

准备实例和配置

删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:

sh 复制代码
# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003

在/tmp下准备一个新的redis.conf文件,内容如下:

ini 复制代码
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下:

sh 复制代码
# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

sh 复制代码
# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

启动

因为已经配置了后台启动模式,所以可以直接启动服务:

sh 复制代码
# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

通过ps查看状态:

sh 复制代码
ps -ef | grep redis

发现服务都已经正常启动:

如果要关闭所有进程,可以执行命令:

sh 复制代码
ps -ef | grep redis | awk '{print $2}' | xargs kill

或者(推荐这种方式):

sh 复制代码
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

1)Redis5.0之前

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

sh 复制代码
# 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群:

sh 复制代码
# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

2)Redis5.0以后

我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:

sh 复制代码
redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的样子:

这里输入yes,则集群开始创建:

通过命令可以查看集群状态:

sh 复制代码
redis-cli -p 7001 cluster nodes

测试

尝试连接7001节点,存储一个数据:

sh 复制代码
# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1

结果悲剧了:

集群操作时,需要给redis-cli加上-c参数才可以:

sh 复制代码
redis-cli -c -p 7001

这次可以了:

散列插槽

Redis 会把每一个master节点映射到0~16383共16384个插槽(hash slot)上

数据key不是与节点绑定,而是与插槽绑定。(方便集群伸缩)

  • key中包含"{}",且"{}"中至少包含1个字符,"{}"中的部分是有效部分
  • key中不包含"{}",整个key都是有效部分

连接集群任何一个节点即可,不同节点会重定向。

如何将同一类数据固定的保存在同一个 Redis 实例?

这一类数据使用相同的有效部分,例如key都以{typeId}为前缀

集群伸缩

1、添加节点

sh 复制代码
redis-cli --cluster add-node 192.168.150.101:7004 192.168.150.101:7001

2、分配插槽

sh 复制代码
redis-cli --cluster reshard 192.168.150.101:7001

故障转移

  1. 该实例与其它实例失去连接
  2. 疑似宕机
  3. 确定下线,自动提升一个slave为新的master

数据迁移

利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。

  • 缺省:默认的流程,如图1~6步
  • force:省略了对offset的一致性校验
  • takeover:直接执行第5步,忽略数据一致性、忽略master状态和其它master的意见

RedisTemplate 访问分片集群

  1. 引入redis的starter依赖
  2. 配置分片集群地址(指定分片集群的每一个节点信息)
  3. 配置读写分离
相关推荐
FL4m3Y4n10 分钟前
MySQL缓存策略
数据库·mysql·缓存
野犬寒鸦34 分钟前
Redis复习记录day1
服务器·开发语言·数据库·redis·缓存
Nyarlathotep01131 小时前
Redis的内存回收和对象共享
redis·后端
野犬寒鸦2 小时前
Redis热点key问题解析与实战解决方案(附大厂实际方案讲解)
服务器·数据库·redis·后端·缓存·bootstrap
mldlds3 小时前
Windows安装Redis图文教程
数据库·windows·redis
Nyarlathotep01133 小时前
Redis的对象(5):有序集合对象
redis·后端
feng68_3 小时前
Redis架构实践
linux·运维·redis·架构·bootstrap
美好的事情能不能发生在我身上4 小时前
Jmeter压测遇到的问题
java·分布式·jmeter
石逸凡4 小时前
谈AI原生:本质、单体、群、分布式、数据库与计算机架构
数据库·分布式·ai-native
菜菜小狗的学习笔记5 小时前
黑马程序员Redis--实战篇(黑马点评)
数据库·redis·缓存