Redis 集群

目录

一、案例分析

1.1、案例概述

1.2、案例前置知识点 

1)客户端分片 

2)代理分片 

3)服务端分片 

1.3、案例环境 

1)本实验案例环境 

2)案例需求 

3)案例实现思路 

二、案例实施 

2.1、下载并安装 Redis 

2.2、修改 Redis 配置文件 

2.3、创建 Redis 集群 

2.4、调整组的主从 

1)删除原有集群中的所有从节点 

2)删除节点配置文件和持久化配置文件 

3)重新添加从节点 

4)检查新的主从关系 

5)测试 Redis 集群 


一、案例分析

1.1、案例概述

现今 Redis 在很多业务场景,使用越来越广泛。在互联网发展的今天,网站的稳定性和高可用性不言而喻。随着技术的发展,集群方案层出不穷,目前 Redis 集群的实现方法 一般有客户端分片、代理分片和服务器端分片三种解决方案。 

1.2、案例前置知识点 

1)客户端分片 

客户端分片方案是将分片工作放在业务程序端。程序代码根据预先设置的路由规则,直接对多个 Redis 实例进行分布式访问。这样的好处是,群集不依赖于第三方分布式中间件,实现方法和代码都自己掌控,可随时调整,不用担心踩到坑。这实际上是一种静态分片技术, Redis 实例的增减,都得手工调整分片程序。基于此分片机制的开源产品,现在仍不多见。 这种分片机制的性能比代理式更好(少了一个中间分发环节),但缺点是升级麻烦,对研发人员的个人依赖性强,需要有较强的程序开发能力做后盾。如果主力程序员离职,可能新的负责人会选择重写一遍。所以这种方式下可运维性较差,一旦出现故障,定位和解决都得研发人员和运维人员配合解决,故障时间变长。因此这种方案,难以进行标准化运维,不太适合中小公司。

2)代理分片 

代理分片方案是将分片工作交给专门的代理程序来做。代理程序接收到来自业务程序的数据请求,根据路由规则,将这些请求分发给正确的 Redis 实例并返回给业务程序。这种机制下,一般会选用第三方代理程序(而不是自己研发)。因为后端有多个 Redis 实例, 所以这类程序又称为分布式中间件。这种分片机制的好处是业务程序不用关心后端 Redis 实例,维护起来也方便。虽然会因此带来些性能损耗,但对于 Redis 这种内存读写型应用, 相对而言是能容忍的。这是比较推荐的集群实现方案。像 Twemproxy、Codis 就是基于该 机制的开源产品的其中代表,应用非常广泛。

  • Twemproxy 代理分片机制

Twemproxy 是一种代理分片机制,由 Twitter 开源。Twemproxy 作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个 Redis 服务器,再原路返回。这个方案顺理成章地解决了单个 Redis 单实例问题。当然 Twemproxy 本身也是单点,需要用 Keepalived 做高可用方案。在很长的时间内,Twemproxy 是应用范围最广、稳定性最高、 最久经考验的分布式中间件。

当然 Twemproxy 还有诸多的缺点,具体如下所示。

  1. 无法平滑地扩容/缩容,增加了运维难度。当业务量突增需要增加 Redis 服务器或业务量萎缩需要减少 Redis 服务器时,Twemproxy 都无法平滑地进行扩容或缩容等操作。
  2. 运维操作不友好,甚至没有控制面板。由于使用了中间件代理,相比客户端直接连接服务器方式,性能上有所损耗,实测性能效果降低了 20%左右。 
  • Codis 代理分片机制 

Codis 由豌豆荚于 2014 年 11 月开源,基于 Go 语言和 C 语言开发,是近期涌现的、 国人开发的优秀开源软件之一,现已广泛用于豌豆荚的各种 Redis 业务场景。从各种压力测试来看,Codis 的稳定性符合高效运维的要求。实测 Codis 集群业务处理性能改善很多, 最初集群处理数据性能要比Twemproxy差20%左右,现在比Twemproxy好很多。并且Codis 具有可视化运维管理界面。因此综合方面会优于 Twemproxy 很多。目前越来越多的公司选 择 Codis。 

Codis 引入了 Group 的概念,每个 Group 包括 1 个 Redis Master 及至少 1 个 Redis Slave,这是和 Twemproxy 的区别之一。这样做的好处是,如果当前 Master 有问题,则运维人员可通过 Dashboard“自助式”切换到 Slave,而不需要小心翼翼地修改程序配置文件。 为支持数据热迁移(Auto Rebalance),出品方修改了 Redis Server 源码,并称之为 Codis Server。Codis 采用预先分片(Pre-Sharding)机制,事先规定分成 1024 个 slots(也就是说,最多能支持后端 1024 个 Codis Server),这些路由信息保存在 zookeeper 中。 

3)服务端分片 

Redis-Cluster 是 Redis 官方的集群分片技术。Redis-Cluster 将所有 Key 映射到 16384 个 slot 中,集群中每个 Redis 实例负责一部分,业务程序是通过集成的 Redis-Cluster 客户端进行操作。客户端可以向任一实例发出请求,如果所需数据不在该实例中,则该实例引导 客户端自动去对应实例读写数据。Redis-Cluster 成员之间的管理包括节点名称、IP、端口、 状态、角色等,都通过节点与之间两两通讯,定期交换信息并更新。 

Redis-Cluster 是在 Redis3.0 版中推出,支持 Redis 分布式集群部署模式,采用无中心分布式架构。所有的 Redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽。节点的 fail 是通过集群中超过半数的节点检测失败时才生效。客户端与 Redis 节点直连,不需要中间代理层。客户端也不需要连接集群所有节点,连接集群中任何一个可用节点即可,这样即减少了代理层,也大大提高了 Redis 集群性能。 

1.3、案例环境 

1)本实验案例环境 

目前 Redis 官网最新稳定版本已经更新到 5.0.7,本次案例实验环境就使用 4.0.9。为了实验环境简单明了、方便部署使用六台服务器,然后启动六个 Redis 实例组成集群,集群 包括三组,每组都是一主一从的关系。在实际生产环境考虑到架构的高可用能,在实验环境至少需要六台服务器。具体环境参考下表。 

系统版本 CentOS7.6(最小化安装)
Redis 版本 4.0.9
服务器 IP 地址 192.168.23.208——213
主机名 master1-3,slave1-3
Firewalld 关闭
Selinux 禁用
Redis 实例端口 6379

 案例环境

案例拓扑如下图所示:

 实验拓扑图

2)案例需求 

  • 使用六台 Redir 搭建一个 Redis 集群。
  • 要求任意宕机一组实例,集群写入或读取数据不受任何影响。
  • 要求理解 Redis 的性能管理。 

3)案例实现思路 

  1. 下载安装 Redis。
  2. 配置启动六个 Redis 实例。
  3. 将六个 Redis 实例组成集群。
  4. 集群结构微调。
  5. 破坏性测试。 

二、案例实施 

2.1、下载并安装 Redis 

Redis 常见的安装方式也分为两种:YUM 安装和源码安装。这里部署集群建议采用源码安装的方式。 

所有节点上操作:

[root@master1 ~]# tar zxf redis-4.0.9.tar.gz -C /usr/src/
[root@master1 ~]# cd /usr/src/redis-4.0.9/
[root@master1 redis-4.0.9]# make
[root@master1 redis-4.0.9]# make PREFIX=/usr/local/redis install
[root@master1 redis-4.0.9]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@master1 redis-4.0.9]# cd utils/
[root@master1 utils]# ./install_server.sh 

2.2、修改 Redis 配置文件 

所有节点上操作:

修改 master1-3、slave1-3 的配置文件,以下配置文件参数需要根据机器环境修改。 

[root@master1 ~]# vim /etc/redis/6379.conf 
# bind 127.0.0.1  //注释掉 bind 项,Redis 中 bind 选项默认监听所有网卡
protected-mode no  //关闭保护模式
port 6379  //端口号
daemonize yes  //以独立进程启动
cluster-enabled yes  //打开集群
cluster-config-file nodes-6379.conf   //集群配置文件名称设置
cluster-node-timeout 15000  //集群超时时间设置
appendonly yes  //开启 aof 持久化
[root@master1 ~]# /etc/init.d/redis_6379 restart  重启服务
[root@master1 ~]# ss -anpt | grep redis
LISTEN     0      128          *:16379                    *:*                   users:(("redis-server",pid=20164,fd=11))
LISTEN     0      128          *:6379                     *:*                   users:(("redis-server",pid=20164,fd=7))
LISTEN     0      128       [::]:16379                 [::]:*                   users:(("redis-server",pid=20164,fd=10))
LISTEN     0      128       [::]:6379                  [::]:*                   users:(("redis-server",pid=20164,fd=6))

正常启动后/var/lib/redis/6379/目录下会多出两个文件,一个是持久化 appendonly.aof 文件,另外一个是节点首次启动生成的 nodes-6379.conf 

[root@master1 ~]# ls /var/lib/redis/6379/
appendonly.aof  dump.rdb  nodes-6379.conf

2.3、创建 Redis 集群 

仅在 master1 上操作

创建集群要用到 ruby 的一个脚本,在创建集群前,需要先安装 ruby 的运行环境和 ruby 的 redis 客户端,该操作在其中一台服务器上进行即可(这里在master1上操作)。gem命令是提前下载的 redis-3.2.0.gem 软件包提供的,直接上传即可使用。

[root@master1 ~]# ls
anaconda-ks.cfg  redis-3.2.0.gem  redis-4.0.9.tar.gz
[root@master1 ~]# yum -y install ruby rubygems
[root@master1 ~]# gem install redis --version 3.2.0
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed

创建集群

使用源码解压目录中的 redis-trib.rb 工具创建群集。六个实例分为三组,每组一主一从, --replicas 1 表示每组一个从,下面交互的时候需要输入 yes 才可以创建。 

[root@master1 ~]# cd /usr/src/redis-4.0.9/src/
[root@master1 src]# ./redis-trib.rb create --replicas 1 192.168.23.208:6379 192.168.23.209:6379 192.168.23.210:6379 192.168.23.211:6379 192.168.23.212:6379 192.168.23.213:6379
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.23.208:6379
192.168.23.209:6379
192.168.23.210:6379
Adding replica 192.168.23.212:6379 to 192.168.23.208:6379
Adding replica 192.168.23.213:6379 to 192.168.23.209:6379
Adding replica 192.168.23.211:6379 to 192.168.23.210:6379
M: 35a9152a7abbf511d7867d43600598ae0b23e198 192.168.23.208:6379
   slots:0-5460 (5461 slots) master
M: 11147fea9d52437d3b26ca19f0689c3fc4f02d1f 192.168.23.209:6379
   slots:5461-10922 (5462 slots) master
M: 1f60ae3203c794bb61c5cf066dff73ecaed7e79c 192.168.23.210:6379
   slots:10923-16383 (5461 slots) master
S: 34a1c7e7c8fb5ccae1040db3e3032dc722b527e9 192.168.23.211:6379
   replicates 1f60ae3203c794bb61c5cf066dff73ecaed7e79c
S: bc1b96e3fed105d4991e2bd14ad1071912fa6560 192.168.23.212:6379
   replicates 35a9152a7abbf511d7867d43600598ae0b23e198
S: b733301329cfb79c2fb06007262f1fb00a134409 192.168.23.213:6379
   replicates 11147fea9d52437d3b26ca19f0689c3fc4f02d1f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.23.208:6379)
M: 35a9152a7abbf511d7867d43600598ae0b23e198 192.168.23.208:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 11147fea9d52437d3b26ca19f0689c3fc4f02d1f 192.168.23.209:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 1f60ae3203c794bb61c5cf066dff73ecaed7e79c 192.168.23.210:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: b733301329cfb79c2fb06007262f1fb00a134409 192.168.23.213:6379
   slots: (0 slots) slave
   replicates 11147fea9d52437d3b26ca19f0689c3fc4f02d1f
S: 34a1c7e7c8fb5ccae1040db3e3032dc722b527e9 192.168.23.211:6379
   slots: (0 slots) slave
   replicates 1f60ae3203c794bb61c5cf066dff73ecaed7e79c
S: bc1b96e3fed105d4991e2bd14ad1071912fa6560 192.168.23.212:6379
   slots: (0 slots) slave
   replicates 35a9152a7abbf511d7867d43600598ae0b23e198
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看群集状态

[root@master1 src]# ./redis-trib.rb check 192.168.23.208:6379
>>> Performing Cluster Check (using node 192.168.23.208:6379)
M: 35a9152a7abbf511d7867d43600598ae0b23e198 192.168.23.208:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 11147fea9d52437d3b26ca19f0689c3fc4f02d1f 192.168.23.209:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 1f60ae3203c794bb61c5cf066dff73ecaed7e79c 192.168.23.210:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: b733301329cfb79c2fb06007262f1fb00a134409 192.168.23.213:6379
   slots: (0 slots) slave
   replicates 11147fea9d52437d3b26ca19f0689c3fc4f02d1f
S: 34a1c7e7c8fb5ccae1040db3e3032dc722b527e9 192.168.23.211:6379
   slots: (0 slots) slave
   replicates 1f60ae3203c794bb61c5cf066dff73ecaed7e79c
S: bc1b96e3fed105d4991e2bd14ad1071912fa6560 192.168.23.212:6379
   slots: (0 slots) slave
   replicates 35a9152a7abbf511d7867d43600598ae0b23e198
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

从上面 replicates 的值可以看到相对应的主从关系:192.168.23.211 是 192.168.23.210 的从、192.168.23.212 是 192.168.2.208 的从、192.168.23.213 是 192.168.23.209 的从。但是,这样创建的集群在生产环境可能会有一个问题,每一组的主从都是随机产生的。那随机产生的弊端就是,有些服务器性能参差不齐,一但主节点分配到性能不佳的服务器上,可能就会影响 Redis 集群整体的性能。

2.4、调整组的主从 

使用上述方法创建群集时的主从关系是随机生成的,下面介绍通过命令工具调整为如下表所示的主从对应关系。 

192.168.23.208 192.168.23.211
192.168.23.209 192.168.23.212
192.168.23.210 192.168.23.213

 主从 ip 分配

1)删除原有集群中的所有从节点 

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb del-node 192.168.23.211:6379 34a1c7e7c8fb5ccae1040db3e3032dc722b527e9
>>> Removing node 34a1c7e7c8fb5ccae1040db3e3032dc722b527e9 from cluster 192.168.23.211:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb del-node 192.168.23.212:6379 bc1b96e3fed105d4991e2bd14ad1071912fa6560
>>> Removing node bc1b96e3fed105d4991e2bd14ad1071912fa6560 from cluster 192.168.23.212:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb del-node 192.168.23.213:6379 b733301329cfb79c2fb06007262f1fb00a134409
>>> Removing node b733301329cfb79c2fb06007262f1fb00a134409 from cluster 192.168.23.213:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

2)删除节点配置文件和持久化配置文件 

三台从节点上操作

[root@slave1 ~]# cd /var/lib/redis/6379/
[root@slave1 6379]# ls
appendonly.aof  dump.rdb  nodes-6379.conf
[root@slave1 6379]# rm -rf *
[root@slave1 ~]# /etc/init.d/redis_6379 restart


[root@slave2 ~]# cd /var/lib/redis/6379/
[root@slave2 6379]# ls
appendonly.aof  dump.rdb  nodes-6379.conf
[root@slave2 6379]# rm -rf *
[root@slave2 6379]# /etc/init.d/redis_6379 restart


[root@slave3 ~]# cd /var/lib/redis/6379/
[root@slave3 6379]# ls
appendonly.aof  dump.rdb  nodes-6379.conf
[root@slave3 6379]# rm -rf *
[root@slave3 6379]# /etc/init.d/redis_6379 restart

3)重新添加从节点 

 master1上面操作

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb add-node --slave --master-id 35a9152a7abbf511d7867d43600598ae0b23e198 192.168.23.211:6379 192.168.23.208:6379

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb add-node --slave --master-id 11147fea9d52437d3b26ca19f0689c3fc4f02d1f 192.168.23.212:6379 192.168.23.209:6379

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb add-node --slave --master-id 1f60ae3203c794bb61c5cf066dff73ecaed7e79c 192.168.23.213:6379 192.168.23.210:6379

4)检查新的主从关系 

[root@master1 ~]# /usr/src/redis-4.0.9/src/redis-trib.rb check 192.168.23.208:6379
>>> Performing Cluster Check (using node 192.168.23.208:6379)
M: 35a9152a7abbf511d7867d43600598ae0b23e198 192.168.23.208:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 219aaf7419735dab06164c8c4da6b9467dad9eaf 192.168.23.212:6379
   slots: (0 slots) slave
   replicates 11147fea9d52437d3b26ca19f0689c3fc4f02d1f
M: 11147fea9d52437d3b26ca19f0689c3fc4f02d1f 192.168.23.209:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 1f60ae3203c794bb61c5cf066dff73ecaed7e79c 192.168.23.210:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: fe3ed99ec2b50c1fa909289fd5d31172c53f483c 192.168.23.211:6379
   slots: (0 slots) slave
   replicates 35a9152a7abbf511d7867d43600598ae0b23e198
S: d1ea841cb1ea17c9d6b75188029cc9dbecaf3928 192.168.23.213:6379
   slots: (0 slots) slave
   replicates 1f60ae3203c794bb61c5cf066dff73ecaed7e79c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

5)测试 Redis 集群 

测试 Redis 集群是否可以写入数据,这里随便挑选一个 192.168.23.208 实例插入 key 为 name、value 为 zhangsan 这条数据,可以清楚看到从 192.168.23.208 实例跳转到了 192.168.23.209 实例。也就是说 Redis 会根据不同的类型数据存储到不同的 slot 里面。在执行测试命令时添加-c 选项表示群集模式。  

[root@master1 ~]# /usr/local/redis/bin/redis-cli -c -h 192.168.23.208
192.168.23.208:6379> set name zhangsan
-> Redirected to slot [5798] located at 192.168.23.209:6379
OK

 在192.168.23.210实例上查看

[root@master3 ~]# /usr/local/redis/bin/redis-cli -c -h 192.168.23.210
192.168.23.210:6379> get name
-> Redirected to slot [5798] located at 192.168.23.209:6379
"zhangsan"

至此,Redis 群集就部署完成。 

相关推荐

  1. Redis-

    2024-03-27 16:50:05       39 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-27 16:50:05       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-27 16:50:05       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-27 16:50:05       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-27 16:50:05       18 阅读

热门阅读

  1. js实现base64转字符串

    2024-03-27 16:50:05       19 阅读
  2. Unity 中的特殊文件

    2024-03-27 16:50:05       15 阅读
  3. 掌握Qt开发技能:打造跨平台应用的利器

    2024-03-27 16:50:05       18 阅读
  4. 力扣4寻找两个正序数组的中位数

    2024-03-27 16:50:05       14 阅读
  5. C语言 如何定义和使用结构体?

    2024-03-27 16:50:05       16 阅读
  6. 前后端实时数据通信

    2024-03-27 16:50:05       16 阅读
  7. a链接下载zip压缩包

    2024-03-27 16:50:05       18 阅读
  8. 08 React 使用uuid示例

    2024-03-27 16:50:05       15 阅读
  9. React Context 的使用详解

    2024-03-27 16:50:05       17 阅读
  10. 云计算第1阶段_Linxu基础知识_day02

    2024-03-27 16:50:05       18 阅读