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个节点。
主从复制流程
① 若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。
② 无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。
③ 后台进程完成缓存操作之后,Maste机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
④ Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Mater同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。
哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题。
哨兵模式主要功能
① 集群监控:负责监控Redis master和slave进程是否正常工作
② 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
③ 故障转移:如果master node挂掉了,会自动转移到slave node上
④ 配置中心:如果故障转移发生了,通知client客户端新的master地址
使用一个或者多个哨兵(Sentinel)实例组成的系统,对redis节点进行监控,在主节点出现故障的情况下,能将从节点中的一个升级为主节点,进行故障转义,保证系统的可用性。
哨兵们监控整个系统节点的过程
① 首先主节点的信息是配置在哨兵(Sentinel)的配置文件中
② 哨兵节点会和配置的主节点建立起两条连接命令连接和订阅连接
③ 哨兵会通过命令连接每10s发送一次INFO命令,通过INFO命令,主节点会返回自己的run_id和自己的从节点信息
④ 哨兵会对这些从节点也建立两条连接命令连接和订阅连接
⑤ 哨兵通过命令连接向从节点发送INFO命令,获取到他的一些信息
⑥ 通过命令连接向服务器的_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对故障进行迁移
故障迁移
① 在从节点中挑选出新的主节点
② 将该节点设置成新的主节点 SLAVEOF no one,并确保在后续的INGO命令时,该节点返回状态为master
③ 将其他的从节点设置成从新的主节点复制, SLAVEOF命令
④ 将旧的主节点变成新的主节点的从节点
优缺点
优点
缺点
#仅展示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
[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
#如果首次导入失败,可以重新再导入一次
[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) " 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
[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
#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
[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>
本次实验最好在实验开始时就关闭防火墙和增强性安全功能,不然可能会导致任何向外下载或同步的操作失败。