**数据冗余:**主从复制实现了数据的热备份,是持久化之外的一个种数据冗余方式。
**故障恢复:**解决单点故障,当主节点出现故障时,可以让从节点提供服务,实现快速的故障恢复
**读写分离:**可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载均衡能力,同时可以根据需要的变化,改变从库的数量。
**负载均衡:**在主从复制的基础上,配合读写分离,可以又主节点提供数据的修改,由从节点提供读服务(即写redis数据时应用连接主节点),读redis数据时应用连通多个从节点分担读负载,可以大大提高redis服务器的并发量。
**高可用基础:**redis的主从复制和MySQL主从复制一样,是其他高可用解决方案的基础。
主从复制工作分为建立连接阶段、数据同步阶段和命令传播阶段。
建立连接阶段:建立slave到master的连接,使master能够识别slave,并保存slave端口号。
数据同步阶段:在slave初次连接master后,会复制master中的所有数据到slave。
命令传播阶段:当master数据库被修改后,导致主从服务器数据数据不一致,此时需要让主从数据同步到一致的状态,同步的动作称为命令传播。
首先在slave设置master的地址和端口,由slave向master发送请求
然后master与slave建立socket连接
只有slave开始周期性的给master发送ping命令,master响应ping命令,确保期间slave和master连通性。
如果由认证的话,则需要slave向master发送认证信息,master给slave进行授权。
最后slave将自己的接口信息发送个master,master将slave接口信息保存。
最终目的实现:master保存slave信息,slave保存了master信息。
slave向master发送sync同步数据请求
master会fork一个子进程,然后产生RDB文件(完备)的过程
在完备的阶段,master是在持续写入数据的,这个阶段会使用AOF进行备份
slave接受到RDB文件后,会将RDB文件载入的内存中,实现与master的数据同步。
RDB持久化完成后,master会将AOF缓存起来的命令发送给slave,复制推送完成后,master会持续的同步操作命令。
slave将接收到的AOF缓存的命令执行,实现与主库的实时同步。
在下一台Redis接入主从复制的集群之前,会持续利用AOF的方式进行备份。
从设备新接入主设备后的数据同步的过程就是数据同步阶段,在后续主设备使用AOF对从设备进行实时同步的过程是命令传播阶段。
Redis官网:https://redis.io/
这里安装的是redis-5.0.7版本
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
yum -y install gcc gcc-c++ make
cd /opt
#将软件包传至该目录下
tar zxvf redis-5.0.7.tar.gz -C /opt/
cd redis-5.0.7/
make -j 4 && make PREFIX=/usr/local/redis install
cd /opt/redis-5.0.7/utils/
./install_server.sh
#回车,直到出现以下选项,手动修改为“/usr/local/redis/bin/redis-server”
Please select the redis executable path [/usr/local/bin/redis-server] /usr/local/redis/bin/redis-server
ln -s /usr/local/redis/bin/* /usr/local/bin/
netstat -natp | grep "redis"
#当 install_server.sh 脚本运行完毕,Redis 服务就已经启动,默认侦听端口为 6379
可以执行安装脚本:
vim /opt/install_redis.sh
//以下为脚本内容
#!/bin/bash
#stop firewall
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#install
yum -y install gcc gcc-c++ make expect
cd /opt
tar zxvf redis-5.0.7.tar.gz -C /opt/
cd /opt/redis-5.0.7/
core=`grep -c "core id" /proc/cpuinfo`
if [ $core -gt 2 ] ; then
let core--
fi
make -j $core
make PREFIX=/usr/local/redis install
cd /opt/redis-5.0.7/utils/
/usr/bin/expect <<-EOF
spawn ./install_server.sh
expect "Please select the redis port for this instance"
send "\r"
expect "Please select the redis config file name"
send "\r"
expect "Please select the redis log file name"
send "\r"
expect "Please select the data directory for this instance"
send "\r"
expect "Please select the redis executable path"
send "/usr/local/redis/bin/redis-server\r"
expect "Is this ok? Then press ENTER to go on or Ctrl-C to abort."
send "\r"
expect eof
EOF
#init bash
ln -s /usr/local/redis/bin/* /usr/local/bin/
a=`netstat -natp | grep -c "redis"`
clear
if [ $a -ne 0 ] ; then
echo "redis install ok!"
else
echo "redis install fail!!"
fi
//执行脚本
chmod +x /opt/install_redis.sh
./opt/install_redis.sh
Master:
vim /etc/redis/6379.conf
bind 0.0.0.0 #70行,修改监听地址为 0.0.0.0,默认监听所有网卡
daemonize yes #137行,开启守护进程
logfile /var/1og/redis_ 6379.1og #172行,指定日志文件目录
dir /var/lib/redis/6379 #264行,指定工作目录
appendonly yes #700行,开启 AOF 持久化功能
slave:
vim /etc/redis/6379. conf
bind 0.0.0.0 #70行,修改监听地址为 0.0.0.0
daemonize yes #137行,开启守护进程
logfile /var/log/redis_ 6379. log #172行,指定日志文件目录
dir /var/lib/redis/6379 #264行,指定工作目录
replicaof 192.168.10.11 6379 #288行,指定要同步的 Master 节点 IP 和端口
appendonly yes #700行,开启 AOF 持久化功能
/etc/init.d/redis_6379 restart
#重启服务使配置生效
在Master上看日志:
tail -f /var/log/redis_6379.log
在master上验证从节点:
redis-cli info replication
哨兵(sentinel)是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。
注:
监控阶段:
获取各个sentine的状态(确认是否在线),这期间是利用ping命令进行测试,sentinel中信息的获取都是通过master来获取的,第一个sentinel先向master发送info指令并建立socket连接专门用来发命令,与此同时获取到了其他哨兵的状态以及其他从属服务器的信息,然后根据获取到的slave信息去连接每一个slave,第二个sentinel同样也会发命令连接master同时获取到了其他与master有关哨兵的信息,并与其他哨兵发布订阅,以保证与其他哨兵信息同步。
通知阶段:
当多个哨兵经过监控阶段组成了一个小的群体,彼此之间进行信息的互通,哨兵会时时刻刻通过他们之间已经建立的socket连接去获取他们对应的工作状态,不管是哪位哨兵获取到,都会将信息回传,在哨兵内部的网络中进行信息的互换。
故障转移:
sentinel1向master发送确认指令,master无回应,并且持续一定时间以后,sentinel1就会确认master已宕机,并将master标记为SRI_S_DOWN,之后将master指令传递到哨兵群体的内网中,传播master已宕机的消息,其他sentinel得到指令后,就会不断的向master发出确认,确定他是真的宕机了,确认完毕也分别将信息传播进内网里。
sdown和odown两种失败状态
sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机。
odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机。
sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机。
sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机。
vim /opt/redis-5.0.7/sentinel.conf
protected- mode no #17行,关闭保护模式
port 26379 #21行,Redis哨兵默认的监听端口
daemonize yes #26行,指定sentinel为后台启动
logfile "/var/log/sentinel.log" #36行,指定日志存放路径
dir "/var/lib/redis/6379" #65行,指定数据库存放路径
sentinel monitor mymaster 192.168.10.11 6379 2
#84行,修改,指定该哨兵节点监控 192.168.10.11:6379 这个主节点,该主节点的名称是 mymaster
#最后的 2 的含义与主节点的故障判定有关:至少需要 2 个哨兵节点同意,才能判定主节点故障并进行故障转移
sentinel down-after -milliseconds mymaster 30000#113行,判定服务器 down 掉的时间周期,默认 30000毫秒 (30秒)
sentinel failover-timeout mymaster 180000 #146行,故障节点的最大超时时间为 180000 (180秒)
先启动Master,再启动slave
cd /opt/redis-5.0.7/
redis-sentinel sentinel.conf &
redis-cli -p 26379 info sentinel
ps -elf | grep "redis" | grep -v "grep"
#查看 redis-server 的进程号
kill -9 [进程号]
#杀死 Master 节点上的 redis-server 的进程号
tail /var/log/sentinel.log
redis-cli -p 26379 info Sentinel
数据分片是集群的核心功能之一
集群讲数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加,另外一方面每个主节点都可以对外提供读服务,大大提供了集群的响应能力。
哈希槽
模式 | 版本 | 优点 | 缺点 |
---|---|---|---|
主从模式 | redis2.8之前 | 1、解决数据备份问题2、做到读写分离,提高服务器性能 | 1、master故障,无法自动故障转移,需人工介入2、master无法实现动态扩容 |
哨兵模式 | redis2.8级之后的模式 | 1、Master 状态监测2、master节点故障,自动切换主从,故障自愈3、所有slave从节点,随之更改新的master节点 | 1、slave节点下线,sentinel不会对一进行故障转移,连接从节点的客户端因为无法获取到新的可用从节点 2、master无法实行动态扩容 |
redis cluster模式 | redis3.0版本之后 | 1、有效的解决了redis在分布式方面的需求 2、遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的 3、可实现动态扩容 4、P2P模式,无中心化 5、通过Gossip协议同步节点信息 6、自动故障转移、Slot迁移中数据可用 7、自动分割数据到不同的节点上 8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令 | 1、架构比较新,最佳实践较少 2、为了性能提升,客户端需要缓存路由表信息 3、节点发现、reshard操作不够自动化 4、不支持处理多个keys的命令,因为这需要在不同的节点间移动数据 5、Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令 |
机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的
3、可实现动态扩容
4、P2P模式,无中心化
5、通过Gossip协议同步节点信息
6、自动故障转移、Slot迁移中数据可用
7、自动分割数据到不同的节点上
8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令 | 1、架构比较新,最佳实践较少
2、为了性能提升,客户端需要缓存路由表信息
3、节点发现、reshard操作不够自动化
4、不支持处理多个keys的命令,因为这需要在不同的节点间移动数据
5、Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令 |