数据库----Redis群集搭建

前言:

  • redis群集有三种模式,分别是主从同步/复制、哨兵模式、Cluster,下面会讲解一下三种模式的工作方式,以及如何搭建Cluster群集

一、Redis群集介绍

  • redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群

  • redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;

  • 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有一个投票容错机制:

    如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;

  • 判断集群是是否正常:

    如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;

  • 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了:

    因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。

  • 综上所述,每个Redis集群理论上最多可以有16384个节点。

二、Redis三种模式介绍

2.1 主从模式

在这里插入图片描述

  • 通过持久化功能,redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中的数据保存到硬盘上,重启会从硬盘上加载数据,但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务,为此,redis提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。
  • 在复制的概念中,数据库分为两类,一类是主数据库(master),另一类是从数据(slave)。主数据可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库,而从数据库一般是只读的,并接受主数据同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库
2.1.1 主从复制原理、流程
  • 主从复制原理图
    在这里插入图片描述

  • 主从复制流程

    ① 若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。

    ② 无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。

    ③ 后台进程完成缓存操作之后,Maste机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。

    ④ Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Mater同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。

2.2 哨兵模式(Sentinel)
2.2.1 哨兵模式集群架构

在这里插入图片描述

  • 哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题。

  • 哨兵模式主要功能

    ① 集群监控:负责监控Redis master和slave进程是否正常工作

    ② 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员

    ③ 故障转移:如果master node挂掉了,会自动转移到slave node上

    ④ 配置中心:如果故障转移发生了,通知client客户端新的master地址

2.2.2 哨兵模式实现高可用原理

在这里插入图片描述

  • 使用一个或者多个哨兵(Sentinel)实例组成的系统,对redis节点进行监控,在主节点出现故障的情况下,能将从节点中的一个升级为主节点,进行故障转义,保证系统的可用性。

  • 哨兵们监控整个系统节点的过程

    ① 首先主节点的信息是配置在哨兵(Sentinel)的配置文件中

    ② 哨兵节点会和配置的主节点建立起两条连接命令连接订阅连接

    ③ 哨兵会通过命令连接每10s发送一次INFO命令,通过INFO命令,主节点会返回自己的run_id和自己的从节点信息

    ④ 哨兵会对这些从节点也建立两条连接命令连接和订阅连接

    ⑤ 哨兵通过命令连接向从节点发送INFO命令,获取到他的一些信息

    • run_id
    • role
    • 从服务器的复制偏移量 offset
    • 其他

    ⑥ 通过命令连接向服务器的_sentinel:hello频道发送一条消息,内容包括自己的ip端口、run_id、配置纪元(后续投票的时候会用到)等

    ⑦ 通过订阅连接对服务器的_sentinel:hello频道做了监听,所以所有的向该频道发送的哨兵的消息都能被接受到

    ⑧ 解析监听到的消息,进行分析提取,就可以知道还有那些别的哨兵服务节点也在监听这些主从节点了,更新结构体将这些哨兵节点记录下来

    ⑨ 向观察到的其他的哨兵节点建立命令连接----没有订阅连接

  • 哨兵模式下的故障迁移

    主观下线

    哨兵(Sentinel)节点会每秒一次的频率向建立了命令连接的实例发送PING命令,如果在down-after-milliseconds毫秒内没有做出有效响应包括(PONG/LOADING/MASTERDOWN)以外的响应,哨兵就会将该实例在本结构体中的状态标记为SRI_S_DOWN主观下线

    客观下线

    当一个哨兵节点发现主节点处于主观下线状态是,会向其他的哨兵节点发出询问,该节点是不是已经主观下线了。如果超过配置参数quorum个节点认为是主观下线时,该哨兵节点就会将自己维护的结构体中该主节点标记为SRI_O_DOWN客观下线
    询问命令SENTINEL is-master-down-by-addr

    master选举

    在认为主节点客观下线的情况下,哨兵节点节点间会发起一次选举,命令为:SENTINEL is-master-down-by-addr ,只是run_id这次会将自己的run_id带进去,希望接受者将自己设置为主节点。如果超过半数以上的节点返回将该节点标记为leader的情况下,会有该leader对故障进行迁移

    故障迁移

    ① 在从节点中挑选出新的主节点

    • 通讯正常
    • 优先级排序
    • 优先级相同是选择offset最大的

    ② 将该节点设置成新的主节点 SLAVEOF no one,并确保在后续的INGO命令时,该节点返回状态为master

    ③ 将其他的从节点设置成从新的主节点复制, SLAVEOF命令

    ④ 将旧的主节点变成新的主节点的从节点

  • 优缺点

    优点

    • 高可用,哨兵模式是基于主从模式的,所有主从模式的优点,哨兵模式都具有;主从可以自动切换,系统更健壮,可用性更高

    缺点

    • redis比较难支持在线扩容,在群集容量达到上限时在线扩容会变得很复杂
2.3 Cluster群集
  • redis的哨兵模式基本已经可以实现高可用、读写分离,但是在这种模式每台redis服务器都存储相同的数据,很浪费内存资源,所以在redis3.0上加入了Cluster群集模式,实现了redis的分布式存储,也就是说每台redis节点存储着不同的内容
  • 根据官方推荐,集群部署至少要3台以上的master节点,最好使用3主3从六个节点的模式。
  • Cluster群集由多个redis服务器组成的分布式网络服务群集,群集之中有多个master主节点,每一个主节点都可读可写,节点之间会相互通信,两两相连,redis群集无中心节点

在这里插入图片描述

  • 在redis-Cluster群集中,可以给每个一个主节点添加从节点,主节点和从节点直接遵循主从模型的特性,当用户需要处理更多读请求的时候,添加从节点可以扩展系统的读性能
  • redis-cluster的故障转移:redis群集的主机节点内置了类似redis sentinel的节点故障检测和自动故障转移功能,当群集中的某个主节点下线时,群集中的其他在线主节点会注意到这一点,并且对已经下线的主节点进行故障转移
  • 集群进行故障转移的方法和redis sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以群集不必另外使用redis sentinel

三、Redis群集搭建

3.1 实验目的、环境
  • 部署Redis服务
  • 构建Redisu群集
  • 验证Redis群集功能
  • 环境:
  • 官网文档描述:至少三个master节点、三个slave(副本)节点,本次实验实用俩个centos虚拟机 三张网卡简易实现此要求
  • master节点
    • IP ens33 192.168.226.200
    • IP ens37 192.168.226.210
    • IP ens38 192.168.226.220
    • 软件包:redis-5.0.7.tar.gz rvm-1.29.9.tar.gz
  • slave节点
    • ens33 192.168.226.120
    • ens36 192.168.226.130
    • ens37 192.168.226.140
    • 软件包:redis-5.0.7.tar.gz
3.2 实验过程
3.2.1 安装redis
  • 所有服务器
#仅展示master节点操作
#安装环境包
[root@master ~]# yum install gcc gcc-c++ make -y
#安装vsftpd(FTP服务器软件)
[root@master ~]# yum install vsftpd -y
......省略部分内容

#wget自动下载文件的工具,下载redis软件包
[root@master ~]# wget http://download.redis.io/releases/redis-5.0.7.tar.gz
#解压
[root@master ~]# tar zxvf redis-5.0.7.tar.gz -C /opt
[root@master ~]# cd /opt/redis-5.0.7/
[root@master redis-5.0.7]# make
......省略部分内容
[root@master redis-5.0.7]# make PERFIX=/usr/local/redis install
......省略部分内容

#执行安装脚本,选择安装配置
[root@master redis-5.0.7]# /opt/redis-5.0.7/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!
    
#创建软链接,让redis命令便于系统管理    
[root@master redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin

#查看服务状态
[root@master redis-5.0.7]# netstat -natp | grep 6379
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      38905/redis-server  
3.2.2 修改配置文件
  • 所有服务器
[root@master redis-5.0.7]# vim /etc/redis/6379.conf
#70行,注释bind功能,(bind 127地址表示监听所有地址)
#bind 127.0.0.1

#89行,关闭保护模式
protected-mode no

#93行,确认端口6379为开启状态
port 6379

#137行,确认以独立进程启动项也为开启状态
daemonize yes

#833行 取消注释,开启群集功能,切记要功cluster要顶头,否则功能不生效
cluster-enabled yes

#841行 取消注释,此功能为群集节点配置文件设置(启动后会在目录下生成此文件)
cluster-config-file nodes-6379.conf

#847行 取消注释,此项功能为群集超时时间设置
cluster-node-timeout 15000

#700行 开启AOF持久化功能,为了今天同步操作
appendonly yes
-----》wq

#重启服务
[root@slave redis-5.0.7]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...

#appendonly.aof aof持久化文件 
#dump.rdb rdb快照文件
#nodes-6379.conf 是重启后生成的节点配置文件
[root@slave redis-5.0.7]# ls /var/lib/redis/6379
appendonly.aof  dump.rdb  nodes-6379.conf
3.2.3 master服务器配置
  • 安装rvm工具、RUBY组件
  • RUBY用来控制群集功能
  • rvm是安装RUBY的前提条件
  • 装rvm之前需要导入一个key密钥文件
    • 此密钥需要加载github,所以导入时间较长
  • 操作如下:
#如果首次导入失败,可以重新再导入一次
[root@master redis-5.0.7]# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
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/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
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) <[email protected]>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

#安装rvm
#PS:执行curl -sSL https://get.rvm.io | bash -s stable时可能会出现curl: (7) Failed connect to get.rvm.io:443; 拒绝连接错误
#此项问题可以关闭虚拟机防火墙,安全性功能,也有也可能时网络比较差,此外也可以把https换成http试试
[root@master redis-5.0.7]# curl -sSL https://get.rvm.io | bash -s stable
Downloading https://github.com/rvm/rvm/archive/1.29.9.tar.gz
Downloading https://github.com/rvm/rvm/releases/download/1.29.9/1.29.9.tar.gz.asc
gpg: Signature made Wed 10 Jul 2019 04:31:02 PM CST using RSA key ID 39499BDB
gpg: Can't check signature: No public key
GPG signature verification failed for '/usr/local/rvm/archives/rvm-1.29.9.tgz' - 'https://github.com/rvm/rvm/releases/download/1.29.9/1.29.9.tar.gz.asc'! Try to install GPG v2 and then fetch the public key:
....省略部分内容

#复制https://github.com/rvm/rvm/archive/1.29.9.tar.gz 下载rvm软件并解压到/opt目录下
[root@master opt]# ls
redis-5.0.7  rh  rvm-1.29.9
  • 安装RUBY
[root@master opt]# cd rvm-1.29.9/
#安装
[root@master rvm-1.29.9]# ./install
.....省略部分内容

#执行环境变量
[root@master rvm-1.29.9]# source /etc/profile.d/rvm.sh 

#查看可以安装的ruby版本
[root@master rvm-1.29.9]# 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]
.....省略部分内容

#安装RUBY2.4.1版本,时间较长,耐心等待
[root@master rvm-1.29.9]# rvm install 2.4.1

#查看当前ruby版本
[root@master rvm-1.29.9]# ruby -v

#再次安装redis
[root@master rvm-1.29.9]# gem install redis
[root@master rvm-1.29.9]# gem install redis
Fetching redis-4.1.3.gem
Successfully installed redis-4.1.3
Parsing documentation for redis-4.1.3
Installing ri documentation for redis-4.1.3
Done installing documentation for redis after 1 seconds
1 gem installed
  • 在主服务器添加两张网卡(NAT模式)
#master节点:
ens33 192.168.226.200
ens37 192.168.226.210
ens38 192.168.226.220

#slave节点
ens33 192.168.226.120
ens36 192.168.226.130
ens37 192.168.226.140
  • 关闭所有服务器防火墙、selinux功能
[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0
[root@master ~]# 
  • 创建集群
[root@master rvm-1.29.9]# redis-cli --cluster create 192.168.226.200:6379 192.168.226.210:6379 192.168.226.220:6379 192.168.226.120:6379 192.168.226.130:6379 192.168.226.140:6379 --cluster-replicas 1
#主从是随机绑定的,创建完成后可以在master节点看到所有节点状态(netstat -natp | grep 6379)

在这里插入图片描述

四、验证群集功能

[root@localhost ~]# redis-cli -h 192.168.226.220 -p 6379
192.168.226.220:6379> keys *
(empty list or set)
192.168.226.220:6379> set user changzhi
OK
192.168.226.220:6379> keys *
1) "user"
192.168.226.220:6379> get user
"changzhi"
192.168.226.220:6379> exit
[root@localhost ~]# redis-cli -h 192.168.226.130 -p 6379
192.168.226.130:6379> keys *
1) "user"
192.168.226.130:6379> get user
(error) MOVED 5474 192.168.226.200:6379	  #提示移动到了200节点
192.168.226.130:6379> exit
[root@localhost ~]# redis-cli -h 192.168.226.200 -p 6379
192.168.226.200:6379> get user
"changzhi"
192.168.226.200:6379> 

总结:

本次实验最好在实验开始时就关闭防火墙和增强性安全功能,不然可能会导致任何向外下载或同步的操作失败。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章