Redis 高可用方案 官方-cluster

Posted 高国藩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 高可用方案 官方-cluster相关的知识,希望对你有一定的参考价值。

Redis 集群简介

Redis 是一个开源的 key-value 存储系统,由于出众的性能,大部分互联网企业都用来做服务器端缓存。Redis 在3.0版本前只支持单实例模式,虽然支持主从模式、哨兵模式部署来解决单点故障,但是现在互联网企业动辄大几百G的数据,可完全是没法满足业务的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。

Redis 集群采用了P2P的模式,完全去中心化。Redis 把所有的 Key 分成了 16384 个 slot,每个 Redis 实例负责其中一部分 slot 。集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新。
Redis 客户端可以在任意一个 Redis 实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。

随随便便搭建一个集群

安装部署任何一个应用其实都很简单,只要安装步骤一步一步来就行了。下面说一下 Redis 集群搭建规划,由于集群至少需要6个节点(3主3从模式),所以,没有这么多机器给我玩,我本地也起不了那么多虚拟机(电脑太烂),现在计划是在一台机器上模拟一个集群,当然,这和生产环境的集群搭建没本质区别。

我现在就要在已经有安装了 Redis 的一个 CentOS 下开始进行集群搭建,如果你还不是很清楚 Linux 下如何安装 Redis ,可以去看这一篇文章《了解一下 Redis 并在 CentOS 下进行安装配置》。请注意,下面所有集群搭建环境都基于已安装好的 Redis 做的。

创建文件夹 

集群模式的最小化配置文件如下:

port 9001(每个节点的端口号)
daemonize yes
bind 192.168.119.131(绑定当前机器 IP)
dir /root/redis-4.0.11/redis-cluster/9001/data/(数据文件存放位置)
pidfile /var/run/redis_9001.pid(pid 9001和port要对应)
cluster-enabled yes(启动集群模式)
cluster-config-file nodes-9001.conf(9001和port要对应)
cluster-node-timeout 15000
appendonly yes

在redis-cluster下创建 /9001/data/~9006六个文件夹

cd redis-cluster/
mkdir -p 9001/data 9002/data 9003/data 9004/data 9005/data 9006/data

复制执行脚本

在 redis-cluster 下创建 bin 文件夹,用来存放集群运行脚本,并把安装好的 Redis 的 src 路径下的运行脚本拷贝过来。看命令:

mkdir bin
cd /root/redis-4.0.11/src
cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-cli redis-server redis-trib.rb /root/redis-4.0.11/redis-cluster/bin

复制一个新 Redis 实例

我们现在从已安装好的 Redis 中复制一个新的实例到 9001 文件夹,并修改 redis.conf 配置。

cp /root/redis-4.0.11/* /root/redis-4.0.11/redis-cluster/9001

注意,修改 redis.conf 配置和单点唯一区别是下图部分,其余还是常规的这几项:

port 9001(每个节点的端口号)
daemonize yes
bind 192.168.119.131(绑定当前机器 IP)
dir /root/redis-4.0.11/redis-cluster/9001/data/(数据文件存放位置)
pidfile /var/run/redis_9001.pid(pid 9001和port要对应)
cluster-enabled yes(启动集群模式)
cluster-config-file nodes-9001.conf(9001和port要对应)
cluster-node-timeout 15000
appendonly yes

再复制出五个新 Redis 实例

我们已经完成了一个节点了,其实接下来就是机械化的再完成另外五个节点,其实可以这么做:把 9001 实例 复制到另外五个文件夹中,唯一要修改的就是 redis.conf 中的所有和端口的相关的信息即可,其实就那么四个位置。开始操作。

到这里,我们已经把最基本的环境搞定了,接下来就是启动了。看一下目录结构图:

其实我们已经几乎搭建好了

启动 9001-9006 六个节点

/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9001/redis.conf 
/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9002/redis.conf 
/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9003/redis.conf 
/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9004/redis.conf 
/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9005/redis.conf 
/root/redis-4.0.11/redis-cluster/bin/redis-server /root/redis-4.0.11/redis-cluster/9006/redis.conf 

全部启动成功后,我们使用节点进行测试:

[root@izwz92ul9j927yw7cd6nlxz bin]# redis-cli -p 9001
127.0.0.1:9001> get 1
(error) CLUSTERDOWN Hash slot not served
127.0.0.1:9001> 

连接成功了,但好像报错了阿???

(error) CLUSTERDOWN Hash slot not served

这是什么鬼?这是因为虽然我们配置并启动了 Redis 集群服务,但是他们暂时还并不在一个集群中,互相直接发现不了,而且还没有可存储的位置,就是所谓的slot(槽)

安装集群所需软件

由于 Redis 集群需要使用 ruby 命令,所以我们需要安装 ruby 和相关接口。

yum install ruby
yum install rubygems
gem install redis 

但是这里会有一个提示错误,redis requires Ruby version >= 2.2.2.

解决方法是先安装rvm,再升级ruby版本。

curl -L get.rvm.io | bash -s stable

如果遇到以下报错,则执行报错中的gpg2 --recv-keys的命令。

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   194  100   194    0     0    205      0 --:--:-- --:--:-- --:--:--   205
100 24361  100 24361    0     0   9900      0  0:00:02  0:00:02 --:--:-- 50228
Downloading https://github.com/rvm/rvm/archive/1.29.4.tar.gz
Downloading https://github.com/rvm/rvm/releases/download/1.29.4/1.29.4.tar.gz.asc
gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/pubring.gpg' created
gpg: Signature made Mon 02 Jul 2018 03:41:26 AM CST using RSA key ID BF04FF17
gpg: Can't check signature: No public key
Warning, RVM 1.26.0 introduces signed releases and automated check of signatures when GPG software found. Assuming you trust Michal Papis import the mpapis public key (downloading the signatures).

GPG signature verification failed for '/usr/local/rvm/archives/rvm-1.29.4.tgz' - 'https://github.com/rvm/rvm/releases/download/1.29.4/1.29.4.tar.gz.asc'! Try to install GPG v2 and then fetch the public key:

    gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

or if it fails:

    command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -

the key can be compared with:

    https://rvm.io/mpapis.asc
    https://keybase.io/mpapis

NOTE: GPG version 2.1.17 have a bug which cause failures during fetching keys from remote server. Please downgrade or upgrade to newer version (if available) or use the second method described above.

执行其中的错误命令:

gpg: keyring `/root/.gnupg/secring.gpg' created
[root@izwz92ul9j927yw7cd6nlxz bin]# gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
gpg: requesting key D39DC0E3 from hkp server keys.gnupg.net
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key D39DC0E3: public key "Michal Papis (RVM signing) <mpapis@gmail.com>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

再次执行命令curl -L get.rvm.io | bash -s stable 即可成功。然后执行加载命令:

source /usr/local/rvm/scripts/rvm

查看ruby版本信息:

rvm list known
[root@izwz92ul9j927yw7cd6nlxz bin]# rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.7[-head] # security released on head
[ruby-]1.9.1[-p431]
[ruby-]1.9.2[-p330]
[ruby-]1.9.3[-p551]
[ruby-]2.0.0[-p648]
[ruby-]2.1[.10]
[ruby-]2.2[.10]
[ruby-]2.3[.7]
[ruby-]2.4[.4]
[ruby-]2.5[.1]
[ruby-]2.6[.0-preview2]

对ruby进行相关升级操作:

#安装ruby
rvm install  2.4.0
#使用新版本
rvm use  2.4.0
#移除旧版本
rvm remove 2.0.0
#查看当前版本
ruby --version

再次安装gem

[root@izwz92ul9j927yw7cd6nlxz bin]# rvm remove 2.0.0
ruby-2.0.0-p648 - #already gone
Using /usr/local/rvm/gems/ruby-2.4.0
[root@izwz92ul9j927yw7cd6nlxz bin]# ruby --version
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
[root@izwz92ul9j927yw7cd6nlxz bin]# ruby --version
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
[root@izwz92ul9j927yw7cd6nlxz bin]# gem install redis
Fetching: redis-4.0.2.gem (100%)
Successfully installed redis-4.0.2
Parsing documentation for redis-4.0.2
Installing ri documentation for redis-4.0.2
Done installing documentation for redis after 1 seconds
1 gem installed

这才是真正的创建集群

/root/redis-4.0.11/redis-cluster/bin/redis-trib.rb create --replicas 1 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005 127.0.0.1:9006

简单解释一下这个命令:调用 ruby 命令来进行创建集群,--replicas 1 表示主从复制比例为 1:1,即一个主节点对应一个从节点;然后,默认给我们分配好了每个主节点和对应从节点服务,以及 solt 的大小,因为在 Redis 集群中有且仅有 16383 个 solt ,默认情况会给我们平均分配,当然你可以指定,后续的增减节点也可以重新分配。

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:9001
127.0.0.1:9002
127.0.0.1:9003
Adding replica 127.0.0.1:9005 to 127.0.0.1:9001
Adding replica 127.0.0.1:9006 to 127.0.0.1:9002
Adding replica 127.0.0.1:9004 to 127.0.0.1:9003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 20648308eaa0d5de420f990a42b0f54bc4511dbe 127.0.0.1:9001
   slots:0-5460 (5461 slots) master
M: 23970d59c50fc2e3434174ad54521a6a03c2483d 127.0.0.1:9002
   slots:5461-10922 (5462 slots) master
M: ef9b7de3fdeab2402ed7c6f6358102df46e15d85 127.0.0.1:9003
   slots:10923-16383 (5461 slots) master
S: 10154685c5c444409ee9f5c4992caa4ba446fff3 127.0.0.1:9004
   replicates 20648308eaa0d5de420f990a42b0f54bc4511dbe
S: ab4d4b448ef22c812a58b9898502aa3386d4a4de 127.0.0.1:9005
   replicates 23970d59c50fc2e3434174ad54521a6a03c2483d
S: 0813aa0535a1bb6bcacbdb5f5c3658394d8c429e 127.0.0.1:9006
   replicates ef9b7de3fdeab2402ed7c6f6358102df46e15d85

M:20648308eaa0d5de420f990a42b0f54bc4511dbe 为主节点Id

S: 10154685c5c444409ee9f5c4992caa4ba446fff3 127.0.0.1:9004 replicates 20648308eaa0d5de420f990a42b0f54bc4511dbe 从节点下对应主节点Id

目前来看,9001-9003 为主节点,9004-9006 为从节点,并向你确认是否同意这么配置。输入 yes 后,会开始集群创建。

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 127.0.0.1:9001)
M: 20648308eaa0d5de420f990a42b0f54bc4511dbe 127.0.0.1:9001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 23970d59c50fc2e3434174ad54521a6a03c2483d 127.0.0.1:9002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: ef9b7de3fdeab2402ed7c6f6358102df46e15d85 127.0.0.1:9003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 0813aa0535a1bb6bcacbdb5f5c3658394d8c429e 127.0.0.1:9006
   slots: (0 slots) slave
   replicates ef9b7de3fdeab2402ed7c6f6358102df46e15d85
S: 10154685c5c444409ee9f5c4992caa4ba446fff3 127.0.0.1:9004
   slots: (0 slots) slave
   replicates 20648308eaa0d5de420f990a42b0f54bc4511dbe
S: ab4d4b448ef22c812a58b9898502aa3386d4a4de 127.0.0.1:9005
   slots: (0 slots) slave
   replicates 23970d59c50fc2e3434174ad54521a6a03c2483d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

上图则代表集群搭建成功啦!!!

验证一下:
依然是通过客户端命令连接上,通过集群命令看一下状态和节点信息等。

redis-cli -c -h 127.0.0.1 -p 9001
cluster info
cluster nodes
[root@izwz92ul9j927yw7cd6nlxz bin]# redis-cli -p 9001
127.0.0.1:9001> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:249
cluster_stats_messages_pong_sent:271
cluster_stats_messages_sent:520
cluster_stats_messages_ping_received:266
cluster_stats_messages_pong_received:249
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:520
127.0.0.1:9001> cluster nodes
23970d59c50fc2e3434174ad54521a6a03c2483d 127.0.0.1:9002@19002 master - 0 1535440627000 2 connected 5461-10922
ef9b7de3fdeab2402ed7c6f6358102df46e15d85 127.0.0.1:9003@19003 master - 0 1535440626012 3 connected 10923-16383
20648308eaa0d5de420f990a42b0f54bc4511dbe 127.0.0.1:9001@19001 myself,master - 0 1535440626000 1 connected 0-5460
0813aa0535a1bb6bcacbdb5f5c3658394d8c429e 127.0.0.1:9006@19006 slave ef9b7de3fdeab2402ed7c6f6358102df46e15d85 0 1535440629020 6 connected
10154685c5c444409ee9f5c4992caa4ba446fff3 127.0.0.1:9004@19004 slave 20648308eaa0d5de420f990a42b0f54bc4511dbe 0 1535440628000 4 connected
ab4d4b448ef22c812a58b9898502aa3386d4a4de 127.0.0.1:9005@19005 slave 23970d59c50fc2e3434174ad54521a6a03c2483d 0 1535440628017 5 connected
127.0.0.1:9001> 

通过命令,可以详细的看出集群信息和各个节点状态,主从信息以及连接数、槽信息等。这么看到,我们已经真的把 Redis 集群搭建部署成功啦!

 

总结一下

接下来可能就是动态扩容、增加节点和减少节点,重新分配槽大小等,当然,还有最重要的就是怎么和我们程序结合起来,以及如何更好的把 Redis 缓存集群发挥出应有的效果,这些才是最重要的。

以上是关于Redis 高可用方案 官方-cluster的主要内容,如果未能解决你的问题,请参考以下文章

Redis高可用集群方案(主从复制,哨兵模式,Redis集群)

redis架构演变与redis-cluster群集读写方案

redis 系列26 Cluster高可用

高可用Redis:Redis Cluster

redis专题之redis cluster高可用集群

redis cluster初探之部署