缓存架构设计之——Redis集群搭建

前述

这里我们要基于Docker 安装一个redis集群,主要包含:Redis集群配置,主从复制,集群扩容缩容。

1、Redis集群高级应用

这里安装6个redis,配置如下

Redis节点IP端口
Redis-7001172.18.0.27001
Redis-7002172.18.0.37002
Redis-7003172.18.0.47003
Redis-7004172.18.0.57004
Redis-7005172.18.0.67005
Redis-7006172.18.0.77006

小知识点(Redis6.0.5):

如果需要安装单机版,需要安装指定的插件
yum -y install gcc gcc-c++ libstdc++-devel
升级gcc
yum -y install centos-release-scl devtoolset-7
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
切换gcc7
scl enable devtoolset-7 bash
单机版安装
解压redis-6.0.5.tar.gz
tar -xf redis-6.0.5.tar.gz
进入到redis-6.0.5目录
cd redis-6.0.5
编译安装
make
make install PREFIX=/usr/local/server/redis-cluster/redis
redis.conf拷贝到安装bin目录下
cp /usr/local/server/redis-cluster/redis-6.0.5/redis.conf /usr/local/server/rediscluster/redis/bin/
修改redis.conf更改redis配置:
设置daemonize为yes 让redis支持后台启动
将protected-mode 改为no,远程连接就不需要账号密码了
bind 192.168.139.188

注意安装Redis6.x的时候一定要切换到gcc7再安装,否则会报如下错误:
在这里插入图片描述
切换语法:

scl enable devtoolset-7 bash

1.1、 Redis版本特性介绍

Redis我们采用Redis6.0.5最新版本,它有很多新特性,我们这里对Redis每个版本的特性介绍一下:
Redis2.6

Redis2.6在2012年正是发布,经历了17个版本,到2.6.17版本,相对于Redis2.4,主要特性如下:
1)服务端支持Lua脚本。
2)去掉虚拟内存相关功能。
3)放开对客户端连接数的硬编码限制。
4)键的过期时间支持毫秒。
5)从节点支持只读功能。
6)两个新的位图命令:bitcount和bitop。
7)增强了redis-benchmark的功能:支持定制化的压测,CSV输出等功能。
8)基于浮点数自增命令:incrbyfloat和hincrbyfloat。
9)redis-cli可以使用--eval参数实现Lua脚本执行。
10)shutdown命令增强。
11)重构了大量的核心代码,所有集群相关的代码都去掉了,cluster功能将会是3.0版本最大的亮点。
12)info可以按照section输出,并且添加了一些统计项
13)sort命令优化

Redis2.8

Redis2.8在2013年11月22日正式发布,经历了24个版本,到2.8.24版本,相比于Redis2.6,主要特性如下:
1)添加部分主从复制的功能,在一定程度上降低了由于网络问题,造成频繁全量复制生成RDB对系统造成的压力。
2)尝试性的支持IPv6.
3)可以通过config set命令设置maxclients。
4)可以用bind命令绑定多个IP地址。
5)Redis设置了明显的进程名,方便使用ps命令查看系统进程。
6)config rewrite命令可以将config set持久化到Redis配置文件中。
7)发布订阅添加了pubsub。
8)Redis Sentinel第二版,相比于Redis2.6的Redis Sentinel,此版本已经变成生产可用。

Redis3.0(里程碑)

Redis3.0在2015年4月1日正式发布,相比于Redis2.8主要特性如下:
Redis最大的改动就是添加Redis的分布式实现Redis Cluster。
1)Redis Cluster:Redis的官方分布式实现。
2)全新的embedded string对象编码结果,优化小对象内存访问,在特定的工作负载下载速度大幅提升。
3)Iru算法大幅提升。
4)migrate连接缓存,大幅提升键迁移的速度。
5)migrate命令两个新的参数copy和replace。
6)新的client pause命令,在指定时间内停止处理客户端请求。
7)bitcount命令性能提升。
8)cinfig set设置maxmemory时候可以设置不同的单位(之前只能是字节)。
9)Redis日志小做调整:日志中会反应当前实例的角色(master或者slave)。
10)incr命令性能提升。

Redis3.2

Redis3.2在2016年5月6日正式发布,相比于Redis3.0主要特征如下:
1)添加GEO相关功能。
2)SDS在速度和节省空间上都做了优化。
3)支持用upstart或者systemd管理Redis进程。
4)新的List编码类型:quicklist。
5)从节点读取过期数据保证一致性。
6)添加了hstrlen命令。
7)增强了debug命令,支持了更多的参数。
8)Lua脚本功能增强。
9)添加了Lua Debugger。
10)config set 支持更多的配置参数。
11)优化了Redis崩溃后的相关报告。
12)新的RDB格式,但是仍然兼容旧的RDB。
13)加速RDB的加载速度。
14)spop命令支持个数参数。
15)cluster nodes命令得到加速。
16)Jemalloc更新到4.0.3版本。

Redis4.0

可能出乎很多的意料,Redis3.2之后的版本是4.0,而不是3.4、3.6、3.8。
一般这种重大版本号的升级也意味着软件或者工具本身发生了重大改革。下面是Redis4.0的新特性:
1)提供了模块系统,方便第三方开发者拓展Redis的功能。
2)PSYNC2.0:优化了之前版本中,主从节点切换必然引起全量复制的问题。
3)提供了新的缓存剔除算法:LFU(Last Frequently Used),并对已有算法进行了优化。
4)提供了非阻塞del和flushall/flushdb功能,有效解决删除了bigkey可能造成的Redis阻塞。
5)提供了memory命令,实现对内存更为全面的监控统计。
6)提供了交互数据库功能,实现Redis内部数据库的数据置换。
7)提供了RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优势。
8)Redis Cluster 兼容NAT和Docker。

Redis5.0

1.新的Stream数据类型。5.0
2.新的Redis模块API:Timers and Cluster API。
3. RDB现在存储LFU和LRU信息。
4.集群管理器从Ruby(redis-trib.rb)移植到C代码。可以在redis-cli中。查看`redis-cli —cluster help`了解
更多信息。
5.新sorted set命令:ZPOPMIN / MAX和阻塞变量。
6.主动碎片整理V2。
7.增强HyperLogLog实现。
8.更好的内存统计报告。
9.许多带有子命令的命令现在都有一个HELP子命令。
10.客户经常连接和断开连接时性能更好。
11.错误修复和改进。
12. Jemalloc升级到5.1版

Redis6.0.5(里程碑)

1.ACL用户权限控制功能
2.RESP3:新的 Redis 通信协议
3.Cluster 管理工具
4.SSL 支持
5.IO多线程支持
6.新的Module API
7.新的 Expire 算法
8.Redis Cluster Proxy
9.Disque

1.2、Redis集群配置

我在学习Docker时候接触了Redis集群安装配置,所以这里使用Docker 安装,安装大概分为以下五个步骤:

1、创建redis-cluster.tmpl配置Redis信息【端口、是否开启集群等】
2、创建redis.sh配置需要创建的redis信息
3、添加网络,redis集群使用该网络
4、执行redis.sh实现创建redis
5、执行redis-cli创建集群

配置Redis信息
创建 redis-cluster.tmpl 配置Redis信息(redis.conf)

#端口
port ${PORT}
#非保护模式
protected-mode no
#启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
#超时时间
cluster-node-timeout 5000
#集群各节点IP地址
cluster-announce-ip 192.168.139.188
#集群节点映射端口
cluster-announce-port ${PORT}
#集群总线端口
cluster-announce-bus-port 1${PORT}
#开启aof持久化策略
appendonly yes
#后台运行
#daemonize yes
#进程号存储
pidfile /var/run/redis_${PORT}.pid
#集群加密
#masterauth fuhua
#requirepass fuhua

Redis创建配置
创建 redis.sh 配置需要创建的 Redis 集群

 #!/bin/bash
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息
#输入信息
read -p "请输入本机IP地址:" Native_IP
#创建文件夹
mkdir -p /usr/local/server/redis-cluster
#下载redis配置模板
echo "正在下载redis-cluster.tmpl配置模板,请手动下载redis-cluster.tmpl文件并复制到/usr/local/server/redis-cluster目录";
#文件下载地址 请手动下载redis-cluster.tmpl文件
#wget -P /usr/local/server/redis-cluster https://gitee.com/cxsunfeng/redis-cluster/blob/master/redis-cluster.tmpl

echo "正在创建redis-net网络";
#c创建网络
docker network create redis-net

echo "正在创建redis配置文件";
for port in `seq 7001 7006`; 
do 
  mkdir -p /usr/local/server/redis-cluster/${port}/conf && PORT=${port} Native_IP=${Native_IP}   envsubst < /usr/local/server/redis-cluster/redis-cluster.tmpl > /usr/local/server/redis-cluster/${port}/conf/redis.conf  && mkdir -p /usr/local/server/redis-cluster/${port}/data;
done
echo "正在启动redis容器";
#创建6个redis容器
for port in `seq 7001 7006`;
do
	docker run -d -it -p ${port}:${port} -p 1${port}:1${port} -v /usr/local/server/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/server/redis-cluster/${port}/data:/data --privileged=true --restart always --name redis-${port} --net redis-net --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf;
done
#查找ip
for port in `seq 7001 7006`;
do
#下面这句是格式化获取docker网络的ip   
	echo  -n "$(docker inspect --format '{{ (index .NetworkSettings.Networks "redis-net").IPAddress }}' "redis-${port}")":${port}" ";
done
#换行 echo -n 不换行输出  echo -e
echo -e "\n"
#输入信息
read -p "请把输入要启动的docker容器名称,默认redis-7001:" DOCKER_NAME
#判断是否为空
if [ ! $DOCKER_NAME ]; 
	then DOCKER_NAME='redis-7001'; 
fi
#进入容器
docker exec -it redis-7001 /bin/bash

#删除容器
#docker rm -f $(docker ps -a |  grep "redis-*"  | awk '{print $1}')

移除脚本创建

#!/bin/bash
echo "正在停止所有redis容器";
docker stop $(docker ps -a |  grep "redis-*"  | awk '{print $1}')
echo "正在删除所有redis容器";
docker rm -f $(docker ps -a |  grep "redis-*"  | awk '{print $1}')
echo "正在删除redis-net网络";
docker network rm redis-net
echo "正在删除/usr/local/server目录";
#根据自己的需要配置
rm -rf /usr/local/server/redis-cluster/70*

脚本授权:给 redis.sh 和 stop.sh 添加可执行权限:

chmod +x redis.sh
chmod +x stop.sh

执行脚本安装Redis节点

./redis.sh

在这里插入图片描述

进入容器说明配置成功, 然后exit退出容器,然后进入到安装好的单机版redis中 cd redis/bin
在这里插入图片描述

执行Redis集群创建命令,注意这里的IP端口要使用执行./redis.sh控制台打印的IP端口

./redis-cli --cluster create 172.18.0.2:7001 172.18.0.3:7002 172.18.0.4:7003 172.18.0.5:7004 172.18.0.6:7005 172.18.0.7:7006 --cluster-replicas 1

–cluster-replicas 表示有一个主有几个slave。
在这里插入图片描述
安装好之后我们可以连接Redis集群 如下图
在这里插入图片描述

1.3 、Redis主从复制

在这里插入图片描述

1、Slave服务启动,主动连接Master,并发送PSYNC命令,请求初始化同步;
2、Master收到PSYNC后,执行BGSAVE命令生成RDB文件,并缓存该时间段内的写命令;
3、Master完成RDB文件后,将其发送给所有Slave服务器;
4、Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件;
5、Master在发送完RDB后,即刻向所有Slave服务器发送缓存中的写命令;

我们可以用 DesktopManager 链接Redis集群,并测试数据,往redis集群添加2条数据,可以明显看到主从效果,效
果如下:操作7003 显示如下是因为 数据是由key CRC16hash算法分配到不同的哈希槽上。
在这里插入图片描述

1.4、集群的扩容、缩容

上面虽然创建了主从复制,但如果手动给节点添加一个从节点,有可能添加主节点,也有可能添加从节点,这是我们想要干的。接下来我们给集群节点添加指定的从节点。
我们安装 7007 、 7008 几个Redis节点,然后将 7007 作为主节点,添加到集群中, 7008 作为从节
点添加到集群中, 注意下面的IP 由于我操作过程中多次执行创建脚本和删除脚本,前面图片中导致IP地址网段不一致,这个不会影响集群,只要在执行

Redis节点IP端口
Redis-7007172.18.0.27007
Redis-7008172.18.0.37008
Redis-7009172.18.0.47009
基于Docker安装Redis这里编写了一个脚本,安装脚本 redis-port.sh 如下:
#!/bin/bash
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息
#换行
echo -e "\n"
#输入信息
read -p "请输入容器端口:" DOCKER_PORT
#输入端口赋值
port=$DOCKER_PORT;
echo -e "$port"
#创建配置文件
mkdir -p ./${port}/conf && PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf && mkdir -p ./${port}/data;
#创建redis容器
docker run -d -it -p ${port}:${port} -p 1${port}:1${port} -v /usr/local/server/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf  -v /usr/local/server/redis-cluster/${port}/data:/data --privileged=true --restart always --name redis-${port}  --net redis-net --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf;
#查找ip
echo -n "启动$(docker inspect --format '{{ (index .NetworkSettings.Networks "redis-net").IPAddress }}' "redis-${port}")":${port}" 成功!";
echo -e "\n"

我们执行 redis-port.sh 脚本,实现 7007,7008,7009 节点安装。
添加可执行权限

chmod +x redis-port.sh

查看集群状态
主节点查看:

./redis-cli -p 7001 cluster nodes|grep master

主节点状态信息如下:
在这里插入图片描述
从节点查看:

./redis-cli -p 7001 cluster nodes|grep slave

从节点节点状态信息如下:
在这里插入图片描述
从上面信息我们可以看出集群关系:

Master:7001 Slave:7005
Master:7002 Slave:7006
Master:7003 Slave:7004

1.4.1、添加集群主节点

我们需要给集群节点添加一个主节点,我们需要将 192.168.211.141:7007 节点添加到 192.168.211.141:7001 节
点所在的集群中,并且添加后作为主节点,添加命令行如下:

./redis-cli --cluster add-node 192.168.139.188:7007 192.168.139.188:7001

命令说明:

将192.168.139.188:7007节点添加到192.168.139.188:7001节点所在的集群中

执行命令后,效果如下:
在这里插入图片描述
此时我们可以进入到集群节点之一查看此时的集群状态,我们进入到 7002 节点中输入 cluster node 查询,操作方
法如下:

进入容器
docker exec -it redis-7002 /bin/bash
进入到redis-cli脚本目录
cd /usr/local/bin
登录7002节点
./redis-cli -p 7002 -c
查询集群状态
cluster nodes

效果如下:
在这里插入图片描述

1.4.2、哈希槽分配

在这里插入图片描述
从图中可以看出新加的主节点没有分配hash槽。这和Redis集群原理有关系,我们来讲解一下集群的原理,然后实现新增节点哈希槽(这段数字范围)的分配。
在这里插入图片描述
Redis原理:

(1)Redis Cluster 特性之一是引入了槽的概念。一个redis集群包含 16384 个哈希槽。
(2)集群时,会将16384个哈希槽分别分配给每个Master节点,每个Master节点占16384个哈希槽中的一部分。
(3)执行GET/SET/DEL时,都会根据key进行操作,Redis通过CRC16算法对key进行计算得到该key所属Redis节点。
(4)根据key去指定Redis节点操作数据。

从原理上分析,因为之前 7001,7002,7003 已经瓜分了16384个哈希槽,所以再增加一个新节点是没有剩余哈希槽分
配的,所以新增的 7007 节点没有分配到哈希槽。我们只能重新分配哈希槽,才能让新增节点分配到一定的哈希槽,
重新分配哈希槽后,我们还要考虑之前其他Redis节点中的数据迁移。

重新分配Hash槽
我们将 7001,7002,7003 中的 100 个哈希槽挪给 7007 ,命令如下:

 ./redis-cli --cluster reshard 192.168.139.188:7001 --cluster-from bd6cfb12d4b2e23aeadf2bda6dd79b8f3db7e0a4,afebc9d18651a5250cf9beafd67bae5c721fd16b,a06d1d0f725fec16f25221cce3369850838e59ec --cluster-to b397d59abda81c18a6b14bfa0439285b2fcc7fb5 --cluster-slots 100

命令说明:

将节点
bd6cfb12d4b2e23aeadf2bda6dd79b8f3db7e0a4
afebc9d18651a5250cf9beafd67bae5c721fd16b
a06d1d0f725fec16f25221cce3369850838e59ec 
中的100个哈希槽移动到
b397d59abda81c18a6b14bfa0439285b2fcc7fb5 
中

参数说明:

--cluster-from:表示slot目前所在的节点的node ID,多个ID用逗号分隔
--cluster-to:表示需要新分配节点的node ID
--cluster-slots:分配的slot数量

将100个哈希槽挪给7007后,我们查询下节点信息:

./redis-cli -p 7001 cluster nodes|grep master

在这里插入图片描述

1.4.3、添加集群从节点

我们需要往集群中给 7007 节点添加一个从节点 7008 ,添加从节点的主要目的是提高高可用,防止主节点宕机后该
节点无法提供服务。添加从节点命令如下:

./redis-cli --cluster add-node 192.168.139.188:7008 192.168.139.188:7007 --cluster-slave --cluster-master-id b397d59abda81c18a6b14bfa0439285b2fcc7fb5

在这里插入图片描述
命令说明:

将192.168.139.188:7008节点添加到192.168.139.188:7007对应的集群中,并且加入的节点为从节点,对应的主节点id是
b397d59abda81c18a6b14bfa0439285b2fcc7fb5

参数说明:

add-node: 后面的分别跟着新加入的slave和slave对应的master
cluster-slave:表示加入的是slave节点
--cluster-master-id:表示slave对应的master的node ID

在这里插入图片描述
集群信息查看:
在这里插入图片描述

1.4.4、缩容

1)数据迁移
2)从节点删除
3)哈希槽迁移
4)主节点删除

Redis实现缩容,需要哈希槽重新分配,将需要移除的节点所分配的所有哈希槽值分配给其他需要运行工作的节点,
还需要移除该节点的从节点,然后再删除该节点。

移除从节点

移除7007节点上的从节点7008

./redis-cli --cluster del-node 192.168.139.188:7008 d84cce145f05e953a4e61fd2d4814b564e401416

参数说明:

del-node:删除节点,后面跟着slave节点的 ip:port 和node ID

删除后,我们再来查看集群节点,此时再无7008节点。
在这里插入图片描述
迁移Master的Slot
我们需要将 7007 节点的哈希槽迁移到 7001,7002,7003 节点上,仍然用上面用过的 redis-cli --cluster reshard
语法,命令如下:
第1次迁移:

./redis-cli --cluster reshard  192.168.139.188:7007 --cluster-from b397d59abda81c18a6b14bfa0439285b2fcc7fb5 --cluster-to bd6cfb12d4b2e23aeadf2bda6dd79b8f3db7e0a4 --cluster-slots 33 --cluster-yes

命令说明:

将192.168.139.188:7007节点所在集群中b397d59abda81c18a6b14bfa0439285b2fcc7fb5 节点的33个哈希槽迁移给
bd6cfb12d4b2e23aeadf2bda6dd79b8f3db7e0a4 节点,不回显需要迁移的slot,直接迁移

效果如下:
在这里插入图片描述
查看集群节点:
在这里插入图片描述
可以清楚的看出原本属于7001的hash槽已经被归还。
下面我们将迁移其他哈希槽到其他节点,将剩余的哈希槽迁移到7002和7003去。
第2次迁移:

./redis-cli --cluster reshard 192.168.139.188:7007 --cluster-from b397d59abda81c18a6b14bfa0439285b2fcc7fb5 --cluster-to afebc9d18651a5250cf9beafd67bae5c721fd16b --cluster-slots 34 --cluster-yes

第三次迁移:

./redis-cli --cluster reshard 192.168.139.188:7007 --cluster-from b397d59abda81c18a6b14bfa0439285b2fcc7fb5 --cluster-to a06d1d0f725fec16f25221cce3369850838e59ec --cluster-slots 33 --cluster-yes

集群状态查询:
在这里插入图片描述
删除7007主节点
删除节点命令如下:

./redis-cli --cluster del-node 192.168.139.188:7007 b397d59abda81c18a6b14bfa0439285b2fcc7fb5

效果如下
在这里插入图片描述

再次查看集群节点,发现7007节点已经被移除
在这里插入图片描述
至此Docker 搭建Redis集群操作完毕!后续会有Redis Sentinel 详解。Sentinel 集群搭建! 感谢阅读

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页