CentOS 7.6 部署redis群集架构

一、实验环境

本次案例实验环境使用 redis 5.0.7(目前最新版本)为了实验环境简单明了、方便部署使用六台服务器,然后启动六个 Redis 实例组成集群,集群包括三组,每组都是一主一从的关系。在实际生产环境考虑到架构的高可用能,在实验环境至少需要六台服务器192.168.245.201-192.168.245.206,只在一台服务器上创建集群即可,所有服务器都安装并启动redis

二、实验步骤

1、安装启动redis

安装redis,安装之前需要安装c++编译工具

[root@localhost ~]# yum -y install gcc gcc-c++ make

解压tar包,编译安装二进制文件,指定安装路径

通常情况下,在 Linux 系统中进行源码编译安装,需要先执行./configure 进行环境检查与配置,从而生成 Makefile 文件,再执行 make && make install 命令进行编译安装。而 Redis 源码包中直接提供了 Makefile 文件,所以在解压完软件包后,可直接进入解压后的软件包目录,执行 make 与 make install 命令进行安装

[root@localhost opt]# tar xzvf redis-5.0.7.tar.gz 
[root@localhost opt]# cd redis-5.0.7/
[root@localhost opt]# make
[root@localhost redis-5.0.7]# make PREFIX=/usr/local/redis install

为命令建立软链接方便使用

[root@localhost redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin

make install 只是安装了二进制文件到系统中,并没有启动脚本和配置文件。软件包中默认提供了一个 install_server.sh 脚本文件,通过该脚本文件可以设置 Redis 服务所需要的相关配置文件。当脚本运行完毕,Redis 服务就已经启动,默认监听端口为 6379

[root@localhost redis-5.0.7]# cd /opt/redis-5.0.7/utils/

[root@localhost utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]    <---回车
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]   <---回车
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]   <---回车
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]  <---回车
Selected default - /var/lib/redis/6379
Please select the redis executable path [] /usr/local/redis/bin/redis-server   <---需要手动指定
Selected config:

Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

查看服务已启动

[root@localhost utils]# netstat -anpt | grep 6379
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      106064/redis-server

2、启用群集功能

修改配置文件,开启群集功能

[root@localhost utils]# vim /etc/redis/6379.conf 
70 #bind 127.0.0.1   <-----需要注释掉bind否则集群创建会失败,如果保护模式设置了yes,就不能注释
89 protected-mode no      <-----关闭保护模式,默认yes:redis只接收来自于bind里的ip的请求,如果不进行设置,那么将处理所有外部网络请求
833 cluster-enabled yes    <-----开启集群功能
841 cluster-config-file nodes-6379.conf  <-----此配置文件不能人工编辑,它是集群节点自动维护的文件,主要用于记录集群中有哪些节点、他们的状态以及一些持久化参数等,方便在重启时恢复这些状态。通常是在收到请求之后这个文件就会被更新
847 cluster-node-timeout 15000  <-----群集超时时间设置,默认是毫秒,这里设置15秒,意思是当master宕掉之后,slave尝试连接master的时间
700 appendonly yes    <-----开启aof持久化

重启服务

[root@localhost utils]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...

查看实例的数据目录,就多了appendonly.aof和nodes-6379.conf文件

[root@localhost utils]# cd /var/lib/redis/
[root@localhost redis]# cd 6379/
[root@localhost 6379]# ls
appendonly.aof  dump.rdb  nodes-6379.conf

3、创建群集

redis-trib.rb是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单、便捷、实用的操作工具。创建集群需要用到它,它是用ruby完成的,所以使用之前需要安装Ruby依赖环境,先安装Ruby语言环境和Ruby的包管理器Gems,然后使用gem安装Redis和Ruby的接口。

导入key文件

[root@localhost 6379]# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
gpg: 已创建目录‘/root/.gnupg’
gpg: 新的配置文件‘/root/.gnupg/gpg.conf’已建立
gpg: 警告:在‘/root/.gnupg/gpg.conf’里的选项于此次运行期间未被使用
gpg: 钥匙环‘/root/.gnupg/secring.gpg’已建立
gpg: 钥匙环‘/root/.gnupg/pubring.gpg’已建立
gpg: 下载密钥‘D39DC0E3’,从 hkp 服务器 keys.gnupg.net
gpg: /root/.gnupg/trustdb.gpg:建立了信任度数据库
gpg: 密钥 D39DC0E3:公钥“Michal Papis (RVM signing) <mpapis@gmail.com>”已导入
gpg: 没有找到任何绝对信任的密钥
gpg: 合计被处理的数量:1
gpg:           已导入:1  (RSA: 1)

安装rvm(Ruby Version Manager,Ruby版本管理器,包括Ruby的版本管理和Gem库管理(gemset)。目前支持Ruby的大多数版本)

[root@localhost 6379]# chmod +x rvm-installer.sh 
[root@localhost 6379]# 
[root@localhost 6379]# ./rvm-installer.sh  <---rvm的安装脚本,自己编写的
[root@localhost 6379]# source /etc/profile.d/rvm.sh 

安装ruby2.4.10

[root@localhost 6379]# rvm list known    <----列出所有的rvm
# 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[.8]
[ruby-]2.4[.10]
[ruby-]2.5[.8]
[ruby-]2.6[.6]
[ruby-]2.7[.1]
ruby-head

# for forks use: rvm install ruby-head-<name> --url https://github.com/github/ruby.git --branch 2.2

# JRuby
jruby-1.6[.8]
jruby-1.7[.27]
jruby-9.1[.17.0]
jruby[-9.2.13.0]
jruby-head

# Rubinius
rbx-1[.4.3]
rbx-2.3[.0]
rbx-2.4[.1]
rbx-2[.5.8]
rbx-3[.107]
rbx-4[.20]
rbx-5[.0]
rbx-head

# TruffleRuby
truffleruby[-20.2.0]

# Opal
opal

# Minimalistic ruby implementation - ISO 30170:2012
mruby-1.0.0
mruby-1.1.0
mruby-1.2.0
mruby-1.3.0
mruby-1[.4.1]
mruby-2.0.1
mruby-2[.1.1]
mruby[-head]

# Ruby Enterprise Edition
ree-1.8.6
ree[-1.8.7][-2012.02]

# Topaz
topaz

# MagLev
maglev-1.0.0
maglev-1.1[RC1]
maglev[-1.2Alpha4]
maglev-head

# Mac OS X Snow Leopard Or Newer
macruby-0.10
macruby-0.11
macruby[-0.12]
macruby-nightly
macruby-head

# IronRuby
ironruby[-1.1.3]
ironruby-head
[root@localhost 6379]# rvm install 2.4.10   <-----安装ruby2.4.10
省略下载过程,建议用移动网络

[root@localhost 6379]# rvm use 2.4.10   <------查看当前使用的ruby版本
Using /usr/local/rvm/gems/ruby-2.4.10

查看当前使用的ruby版本

[root@localhost 6379]# ruby -v
ruby 2.4.10p364 (2020-03-31 revision 67879) [x86_64-linux]

用gem安装Redis和Ruby的接口

Gem是一个管理Ruby库和程序的标准包,它通过Ruby Gem(如 http://rubygems.org/ )源来查找、安装、升级和卸载软件包,非常的便捷

[root@localhost 6379]# gem install redis
Fetching redis-4.2.2.gem
Successfully installed redis-4.2.2
Parsing documentation for redis-4.2.2
Installing ri documentation for redis-4.2.2
Done installing documentation for redis after 0 seconds
1 gem installed

创建集群

[root@redis04 opt]# redis-cli --cluster create 192.168.245.204:6379 192.168.245.205:6379 192.168.245.206:6379 192.168.245.201:6379 192.168.245.202:6379 192.168.245.203:6379 --cluster-replicas 1

在redis 5中redis-trib.rb的功能被集成到了redis-cli中,大大简化了redis的集群部署,加快了进群部署的速度,也方便后期维护与扩容。

create命令可选replicas参数,replicas表示1个master对应几个slave

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460     <-----给master分配slots
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.245.202:6379 to 192.168.245.204:6379    <----给master分配slave
Adding replica 192.168.245.203:6379 to 192.168.245.205:6379   
Adding replica 192.168.245.201:6379 to 192.168.245.206:6379
M: cdab8558d5278ed6901b25240efa3349fc820186 192.168.245.204:6379
   slots:[0-5460] (5461 slots) master
M: a6e13cf8a6b77b40765c36981c1a76cec0eaa457 192.168.245.205:6379
   slots:[5461-10922] (5462 slots) master
M: e662100ba129dd093cb4d80ce08aa4b8993a5880 192.168.245.206:6379
   slots:[10923-16383] (5461 slots) master
S: 4a01c1317fe504c0931272712d01c176a35cb5b0 192.168.245.201:6379
   replicates e662100ba129dd093cb4d80ce08aa4b8993a5880
S: 568d79cffdefd877b5e64e066a720db36d6949ca 192.168.245.202:6379
   replicates cdab8558d5278ed6901b25240efa3349fc820186
S: 53815ee3d3a4081f61a9e685bdbd1c7096b3ebb3 192.168.245.203:6379
   replicates a6e13cf8a6b77b40765c36981c1a76cec0eaa457
Can I set the above configuration? (type 'yes' to accept): yes  <---这里需要交互,输入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.245.204:6379)
M: cdab8558d5278ed6901b25240efa3349fc820186 192.168.245.204:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 568d79cffdefd877b5e64e066a720db36d6949ca 192.168.245.202:6379
   slots: (0 slots) slave
   replicates cdab8558d5278ed6901b25240efa3349fc820186
S: 53815ee3d3a4081f61a9e685bdbd1c7096b3ebb3 192.168.245.203:6379
   slots: (0 slots) slave
   replicates a6e13cf8a6b77b40765c36981c1a76cec0eaa457
S: 4a01c1317fe504c0931272712d01c176a35cb5b0 192.168.245.201:6379
   slots: (0 slots) slave
   replicates e662100ba129dd093cb4d80ce08aa4b8993a5880
M: e662100ba129dd093cb4d80ce08aa4b8993a5880 192.168.245.206:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: a6e13cf8a6b77b40765c36981c1a76cec0eaa457 192.168.245.205:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

创建集群的简要流程:

  • 首先为每个节点创建ClusterNode对象,包括连接每个节点
  • 检查传入的master节点数量是否大于等于3个,只有大于3个节点才能组成集群
  • 计算每个master需要分配的slot数量,以及给master分配slave
  • 打印出分配信息,并提示用户输入“yes”确认是否按照打印出来的分配方式创建集群
  • 输入“yes”后,会执行flush_nodes_config操作,该操作执行前面的分配结果,给master分配slot,让slave复制master
创建好的集群结构:
主:192.168.245.204----->备:192.168.245.202
主:192.168.245.205----->备:192.168.245.203
主:192.168.245.206----->备:192.168.245.201

创建好集群,集群结构ok之后,用ps查看进程,可以看到端口号后面多了一个[cluster]表示它属于一个集群了不是单实例了

[root@redis05 ~]# ps -ef | grep redis
root     106526      1  0 909 ?       00:00:35 /usr/local/redis/bin/redis-server *:6379 [cluster]

4、验证数据存取

第一种方式进入实例redis-cli(进入本地redis实例的传统模式)

进入204节点的redis实例,创建一个key,但是他分配到了205来存储它

[root@redis04 opt]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)

127.0.0.1:6379> set name zhangsan
(error) MOVED 5798 192.168.245.205:6379
127.0.0.1:6379> exit

所以要在205节点上来存储它,直接在204节点进入到205的redis实例

[root@redis04 opt]# redis-cli -h 192.168.245.205 -p 6379
192.168.245.205:6379> set name zhangsan
OK
192.168.245.205:6379> get name
"zhangsan"

但是这种方式只会告诉你去哪里存储去哪里查看,并不会直接查询到结果,因为203节点是205节点的slave,所以key同步了过来,但是却get不到

[root@redis03 opt]# redis-cli 
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
(error) MOVED 5798 192.168.245.205:6379

第二种方式(用redis-cli -c进入实例,-c选项表示启用集群模式,比较科学的方式)

在205节点上进入redis,存入数据haha的值为shengjie,他被存入到了204节点上,204节点上就有了这个key,并且直接跳到了204的redis实例中操作,能get到这个key的值

[root@redis05 ~]# redis-cli -c

127.0.0.1:6379> set haha shengjie
-> Redirected to slot [3662] located at 192.168.245.204:6379
OK
192.168.245.204:6379> keys *
1) "haha"
2) "score"
3) "address"
192.168.245.204:6379> get haha
"shengjie"

再回到205节点上,205节点上并没有这个key

[root@redis05 ~]# redis-cli -c
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "name"

因为202节点是204的slave,在进入202节点的redis实例查看,202节点也同步到了haha这个key

[root@redis02 ~]# redis-cli -c
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "address"
2) "score"
3) "haha"

总结:只有一对master和slave会同步各自的key和值,集群里的其他master和slave并不能同步到,但是都可以get到这个key的值,所以当一个master宕掉之后,并不会影响数据的存取

5、模拟故障

  • 模拟宕掉其中一个master的情况

查看日志:

[root@redis02 src]# tail -f  /var/log/redis_6379.log               

如图所示,查看202节点的日志,显示204是master,它本身是slave

在这里插入图片描述
查看204节点的日志,显示202是Replica副本即slave

在这里插入图片描述
接着,我们将204这台master模拟宕机,再查看202节点的日志,发现他成为了master,另外其他节点存取数据没有影响

在这里插入图片描述
而重新让这台204节点上线,它并没有抢占master,而是变成了202节点的slave

  • 模拟宕掉一对master和slave(201和206节点)

在这里插入图片描述
将201和206节点开机,两个节点又重新加入了集群,201为master,206为slave,集群又能正常存取了

在201节点上此刻所有节点master和slave的状态,可以看到哪些为master哪些为slave

[root@redis01 ~]# cd /var/lib/redis/6379/

[root@redis01 6379]# vim nodes-6379.conf 

4a01c1317fe504c0931272712d01c176a35cb5b0 192.168.245.201:6379@16379 myself,master - 0 1599682208000 8 connected 10923-16383
e662100ba129dd093cb4d80ce08aa4b8993a5880 192.168.245.206:6379@16379 slave 4a01c1317fe504c0931272712d01c176a35cb5b0 0 1599682209450 8 connected
53815ee3d3a4081f61a9e685bdbd1c7096b3ebb3 192.168.245.203:6379@16379 slave a6e13cf8a6b77b40765c36981c1a76cec0eaa457 0 1599682209892 6 connected
a6e13cf8a6b77b40765c36981c1a76cec0eaa457 192.168.245.205:6379@16379 master - 0 1599682209000 2 connected 5461-10922
568d79cffdefd877b5e64e066a720db36d6949ca 192.168.245.202:6379@16379 slave cdab8558d5278ed6901b25240efa3349fc820186 0 1599682208444 1 connected
cdab8558d5278ed6901b25240efa3349fc820186 192.168.245.204:6379@16379 master - 0 1599682207437 1 connected 0-5460
vars currentEpoch 8 lastVoteEpoch 0

在206节点上存入数据key=hahaha,value=sj

[root@redis06 ~]# redis-cli -c
127.0.0.1:6379> 
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set hahaha sj
-> Redirected to slot [12185] located at 192.168.245.201:6379
OK

可以看到key被存到了201节点上,同时206节点也同步到了

[root@redis06 ~]# redis-cli -c
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "hahaha"

随便进入另外一个redis实例203节点上,可以get到了新建的key

[root@redis03 bin]# redis-cli -c
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get hahaha
-> Redirected to slot [12185] located at 192.168.245.201:6379
"sj"

总结:同时宕掉一对master之后集群随即宕掉,无法存取数据,但是再次启动之后会立即加入集群,另外如果宕掉所有master之后,集群也是宕掉

猜你喜欢

转载自blog.csdn.net/shengjie87/article/details/108506056