欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis初探(6)——Redis集群

程序员文章站 2022-05-22 07:51:56
...

之前我们所学习的都是Redis的单机版,我们知道Redis之所以读取速度快是因为它是存储在内存中的。

内存的容量是有限的,单台Redis会碰到性能瓶颈,这就需要使用Redis集群(Redis-cluster)

一、集群原理

1.1 集群架构

Redis初探(6)——Redis集群

如上图所示,每一个蓝色圆圈就是一个Redis节点,这些节点组成了一个Redis集群(Redis-cluster)

节点之间使用Ping——Pong机制进行互联,其内部用二进制协议优化传输速度和带宽。

Redis客户端和节点直接连接即可,无需中间件,一台客户端连接一个节点即可。

Client访问时直接访问任意一个Redis节点即可。

1.2 负载均衡

当我们搭建了集群后,其是如何实现负载均衡的呢?

Redis集群中内置了16384个哈希槽(slot),它会把所有的物理节点都映射到[0,16383]的slot上。

当我们需要在Redis集群中放置了个key-value时,Redis先对key使用crc16算法得出一个结果,然后将结果对16384取余,这样每一个key都会对应一个编号在0~16383的哈希槽

Redis会根据节点数量大致均等的将哈希槽映射到不同的节点。例如我们有三个节点,其每个节点哈希槽范围为:0~5000,5001~10000,10001~16383。

Redis初探(6)——Redis集群

当我们存储一个名为Hello1的ley时,其通过crc16算法计算出的结果为1500,Redis集群就会将这个key放在对应1500的哈希槽中,又因为哈希槽0~5000被映射到了Server1,则Hello1就被放置在了Server1。

Redis初探(6)——Redis集群

1.3 容错机制

通过上面的负载均衡的原理,知道其实每一台 Redis客户端保存的内容都是不一样的,那么当Redis集群中任意一个节点挂掉(连接失败)时,整个集群就挂了

为了实现Redis的高可用,需要为每一个节点添加备用机,即主备机制

一般集群都有集群管理工具,但是Redis集群没有,它是通过投票机制来实现的。

以下图为例简单说一下投票机制:

  1. 当黄色节点发现无法ping通红色节点,它就觉得红色节点可能挂掉了,于是它会发起投票
  2. 其他节点会尝试去ping红色节点,只要有超过半数的节点无法ping通红色节点,就判定红色节点挂掉(即使它实际上可能并没有挂掉)。
  3. 当红色节点被判定挂掉后,会启动该节点的备用机。如果该节点不存在备用机,或备用机也挂掉,那么整个Redis集群就挂掉了

Redis初探(6)——Redis集群


二、搭建集群

Redis集群为了实现容错机制,最少需要三个节点(一个出错,另外两个投票),又因为每个节点至少要有一台备份机,因此一个最简单的Redis集群需要6个Redis客户端

这里只是演示一下,使用伪集群,即6台Redis搭建在一台Linux上,仅使用端口号进行区分,设端口号范围为7001~7006。

2.1 准备原始Redis

注:Redis初探(1)——Redis的安装这篇文章中源码和安装后的文件是在同一文件夹下,本篇文章不使用这种方法。

准备一个Redis安装包,将源码解压到当前文件夹:

wxs@ubuntu:~$ ls
Desktop  redis-4.0.8.tar.gz
wxs@ubuntu:~$ tar zxvf redis-4.0.8.tar.gz 

进入解压后文件夹,执行make编译:

wxs@ubuntu:~$ cd redis-4.0.8/
wxs@ubuntu:~/redis-4.0.8$ make

注:所有源码安装需要自行编译的都需要gcc、g++等相关软件支持

将其安装到/usr/local/redis目录下:

wxs@ubuntu:~/redis-4.0.8$ sudo make install PREFIX=/usr/local/redis

该目录下只有一个bin目录,存放redis的可执行文件,我们从源码包中拷贝一份redis配置文件过来:

wxs@ubuntu:/usr/local/redis$ ls
bin
wxs@ubuntu:/usr/local/redis$ sudo cp ~/redis-4.0.8/redis.conf .
wxs@ubuntu:/usr/local/redis$ ls
bin  redis.conf

编辑该配置文件:

(1)修改bind端口号为0.0.0.0,使其支持远程访问。
Redis初探(6)——Redis集群

(2)开启后端模式。
Redis初探(6)——Redis集群

(3)设置日志文件位置
Redis初探(6)——Redis集群

(4)开启AOF持久化
Redis初探(6)——Redis集群

2.2 准备Redis集群客户端

注意:用来做集群的客户端必须是干净的客户端,像备份文件dump.rdbappendonly.aof等应当先删除掉,避免不必要的错误。

/usr/local中创建redis-cluster文件夹,拷贝六份原始Redis:

wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis01
wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis02
wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis03
wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis04
wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis05
wxs@ubuntu:/usr/local/redis-cluster$ sudo cp -r ../redis redis06
wxs@ubuntu:/usr/local/redis-cluster$ ls
redis01  redis02  redis03  redis04  redis05  redis06

以redis01为例,编辑其redis.conf文件:

(1)修改端口号为7001
Redis初探(6)——Redis集群

(2)修改pidfile
Redis初探(6)——Redis集群

(3)开启集群开关
Redis初探(6)——Redis集群

依次修改其他客户端,端口号范围从7001~7006。

编写一个启动这些客户端的批处理startup.sh

cd redis01/bin
sudo ./redis-server ../redis.conf
cd ../../
cd redis02/bin
sudo ./redis-server ../redis.conf
cd ../../
cd redis03/bin
sudo ./redis-server ../redis.conf
cd ../../
cd redis04/bin
sudo ./redis-server ../redis.conf
cd ../../
cd redis05/bin
sudo ./redis-server ../redis.conf
cd ../../
cd redis06/bin
sudo ./redis-server ../redis.conf
cd ../../

执行脚本,启动成功:
Redis初探(6)——Redis集群

编写一个关闭这些客户端的批处理shutdown.sh

cd redis01/bin
sudo ./redis-cli -p 7001 shutdown
cd ../../
cd redis02/bin
sudo ./redis-cli -p 7002 shutdown
cd ../../
cd redis03/bin
sudo ./redis-cli -p 7003 shutdown
cd ../../
cd redis04/bin
sudo ./redis-cli -p 7004 shutdown
cd ../../
cd redis05/bin
sudo ./redis-cli -p 7005 shutdown
cd ../../
cd redis06/bin
sudo ./redis-cli -p 7006 shutdown
cd ../../

执行脚本,关闭成功:
Redis初探(6)——Redis集群

目录结构如下:

wxs@ubuntu:/usr/local/redis-cluster$ ls
redis01  redis02  redis03  redis04  redis05  redis06  shutdown.sh  startup.sh

2.3 搭建集群

从redis源码的src目录中拷贝redis-trib.rb过来:

aaa@qq.com:/usr/local/redis-cluster$ sudo cp ~/redis-4.0.8/src/redis-trib.rb .
aaa@qq.com:/usr/local/redis-cluster$ ls
redis01  redis03  redis05  redis-trib.rb  startup.sh
redis02  redis04  redis06  shutdown.sh

因为这是一个Ruby文件,需要安装Ruby和Ruby包管理器:

wxs@ubuntu:/usr/local/redis-cluster$ sudo apt-get install ruby rubygems

安装Ruby关于Redis的库,可以执行gem install redis或者前往官网下载安装包后安装。

wxs@ubuntu:/usr/local/redis-cluster$ sudo gem install redis
Fetching: redis-4.0.1.gem (100%)
Successfully installed redis-4.0.1
Parsing documentation for redis-4.0.1
Installing ri documentation for redis-4.0.1
Done installing documentation for redis after 0 seconds
1 gem installed

执行redis-trib.rb时需要附带参数,格式如下:
Redis初探(6)——Redis集群

先启动所有客户端,然后执行脚本:

wxs@ubuntu:/usr/local/redis-cluster$ ./startup.sh 
wxs@ubuntu:/usr/local/redis-cluster$ ./redis-trib.rb create --replicas 1 192.168.30.155:7001 192.168.30.155:7002 192.168.30.155:7003 192.168.30.155:7004 192.168.30.155:7005  192.168.30.155:7006

Redis初探(6)——Redis集群

创建成功:
Redis初探(6)——Redis集群

最后说两句:

  1. 如果你不是伪集群,真的在服务器上搭建了集群,即真集群,那么只需要在任意一台上执行redis-trib.rb即可。
  2. 在真集群的情况下,除了在配置文件中要bind 0.0.0.0以外,还要注意关闭防火墙,不然无法搭建。
  3. 如果关闭所有redis客户端后,想要重新开启集群,在客户端都启动后,进入任意客户端执行cluster nodes即可。
  4. 如果想要重新生成集群,需要删除每个Redis中生成的持久化文件。

三、使用redis-cli连接集群

使用任意一个redis-cli(以redis01的为例),使用-h指定ip地址(默认连接127.0.0.1),使用-p参数指定端口号(默认连接原始的端口为6379的redis),使用-c参数指定是集群(不加会导致无法将key放入对应的客户端中)。

wxs@ubuntu:/usr/local/redis-cluster$ ./redis01/bin/redis-cli -h 192.168.30.155 -p 7001 -c

当我在7001中添加了一个name jitwxs后,它计算出key的哈希槽为5798,这个范围在7002中,因此这个key被移动到了7002中,并且当前连接重定向到了7002。

Redis初探(6)——Redis集群

192.168.30.155:7002> keys *
1) "name"
192.168.30.155:7001> keys *
(empty list or set)
相关标签: Redis 集群