Redis集群与优化

416 阅读16分钟

Redis集群

Redis集群模式

主从复制 就是将主节点(master)redis的数据同步到其他从节点(slave)redis数据库上

  1. 主从模式是最为简单的redis集群模式
  2. 主要工作模式是主从复制。主数据库可以执行读写功能,而从数据库只能执行读功能。主数据库数据发生变化,会自动同步到从数据库。
  3. 主数据库为master,从数据库为slave,一个master可以有多个slave,一个slave只能有一个master,slave挂了,重新启动会从master同步数据;master挂了,服务器只能进行读功能,不能执行写功能,直到master重新启动同步数据后,才能提供写服务。

缺陷

  • 故障恢复无法自动化
  • 写操作无法负载均衡
  • 存储能力受到单机的限制。

哨兵模式 就是监控所有节点的动向

  1. 可以解决主从模式的弊端:master挂掉之后不能提供写功能。
  2. 哨兵模式是建立在主从模式的
  3. 当master挂掉之后,会自动从slave中选一个作为master。若master重新启动,master则会转化为现有的master下的一个slave
  4. 当slave切换时,会通过发布订阅方式,将slave所对应的master更改
  5. 因为哨兵也是一个进程,所以也有挂掉的可能,需要配置多个哨兵互相监督。一个哨兵可以监督多个主从数据库。同样,一个主从数据库可以被多个哨兵监督。

缺陷

  • 写操作无法负载均衡;存储能力受到单机的限制
  • 哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,需要对从节点做额外的监控、切换操作。

集群 主节点负责读写请求和集群信息的维护,从节点只进行主节点数据和状态信息的复制

  1. redis cluster是Redis的分布式解决方案,在3.0版本推出后有效地解决了redis分布式方面的需求,自动将数据进行分片,每个master上放一部分数据提供内置的高可用支持,部分master不可用时,还是可以继续工作的
  2. 支撑N个redis master node,每个master node都可以挂载多个slave node
  3. 高可用,因为每个master都有salve节点,那么如果mater挂掉,redis cluster这套机制,就会自动将某个slave切换成master

Redis之主从复制

为什么需要Redis主从复制

单机状态的问题:

  1. 服务器宕机,可能会导致数据直接丢失
    
  2. 一台服务器的内存一定会达到高峰值,不能无限的对服务器进行升级
    

主从复制可以将数据保存在多个服务器上,并且每个服务器的数据是同步的,有一个服务器宕机了,也不会影响用户的使用,并且Redis可以实现高可用和数据的冗余备份

主从复制的作用

  • 数据备份:可以实现数据的热备份,与持久化不同的数据备份方式
  • 故障恢复:就是主节点故障时,从节点会提供服务,实现故障恢复(实际是一种服务的冗余)
  • 负载均衡:主从复制的基础上,搭建读写分离,主节点提供写服务,从节点提供度服务,这样可以分摊压力
  • 高可用基础:主从复制是哨兵和集群能够实施的基础,因此可以说主从复制是redis高可用的基础。

主从复制的过程

  1. slave服务器连接到master服务器,便开始进行数据同步,发送psync命令。
  2. master服务器收到psync命令之后,开始执行bgsave命令生成RDB快照文件并使用缓存区记录此后执行的所有写命令。
  3. master服务器bgsave执行完之后,就会向所有Slava服务器发送快照文件,并在发送期间继续在缓冲区内记录被执行的写命令。
  4. slave服务器收到RDB快照文件后,会将接收到的数据写入磁盘,然后清空所有旧数据,在从本地磁盘载入收到的快照到内存中,同时基于旧的数据版本对外提供服务。
  5. master服务器发送完RDB快照文件之后,便开始向slave服务器发送缓冲区中的写命令。
  6. slave服务器完成对快照的载入,开始接受命令请求,并执行来自主服务器缓冲区的写命令;
  7. 如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF。

image.png

搭建Redis主从复制

环境

  • master节点:192.168.42.11
  • slave1节点:192.168.42.12
  • slave2节点:192.168.42.13
systemctl stop firewalld
setenforce 0
#一定记得的关闭防火墙

安装Redis(master、slave1、slave2)

这边拿master服务器做例子

[root@master ~]# yum install -y gcc gcc-c++ make
#安装编译依赖包
[root@master ~]# cd /opt/
#将安装包下载奥opt目录下
[root@master opt]# tar zxvf redis-5.0.7.tar.gz
[root@master opt]# cd redis-5.0.7/
[root@master redis-5.0.7]# make
[root@master redis-5.0.7]# make PREFIX=/usr/local/redis install
#安装
[root@master redis-5.0.7]# cd utils/
[root@master utils]# ./install_server.sh
#运行脚本,一直回车4次,到第五次
····················
#第四次回车后,在path后面添加内容,再回车
Please select the redis executable path [] /usr/local/redis/bin/redis-server
[root@master utils]# ln -s /usr/local/redis/bin/* /usr/local/bin/
#做软连接

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

修改master节点的配置文件

[root@master ~]# vim /etc/redis/6379.conf
··············
70 bind 0.0.0.0  #修改监听地址为0.0.0.0
··············
137 daemonize yes  #开启守护进程
··············
172 logfile /var/log/redis_6379.log  #指定日志文件目录
··············
264 dir /var/lib/redis/6379  #指定工作目录
··············
700 appendonly yes  #开启AOF持久化功能
··············

[root@master ~]# /etc/init.d/redis_6379 restart
#重启Redis服务
[root@master ~]# lsof -i:6379
#查看端口是否开启

image.png

image.png

image.png

image.png image.png

image.png

image.png

修改slave配置文件(slave1与slave2一样)

这边拿slave1做例子

[root@slave1 ~]# vim /etc/redis/6379.conf
···············
70 bind 0.0.0.0
···············
137 daemonize yes
···············
172 logfile /var/log/redis_6379.log
···············
264 dir /var/lib/redis/6379
···············
288 replicaof 192.168.42.11 6379
···············
700 appendonly yes
···············

[root@slave1 ~]# /etc/init.d/redis_6379 restart
#重启服务
[root@slave1 ~]# lsof -i:6379
#查看是否打开

image.png

image.png

image.png

image.png

image.png

image.png

image.png

验证主从复制效果

master节点查看日志
[root@master ~]# tail -f /var/log/redis_6379.log
#实时查看master节点日志
·············
6719:M 05 Dec 2022 18:30:43.311 * Synchronization with replica 192.168.42.12:6379 succeeded
·············
6719:M 05 Dec 2022 18:34:27.580 * Synchronization with replica 192.168.42.13:6379 succeeded

image.png

image.png

从master节点上验证从节点
[root@master ~]# redis-cli info replication

image.png

Redis之哨兵模式

为什么需要哨兵模式

当服务器宕机后,需要手动一台从机切换为主机,这需要人工干预,不仅费时费力而且还会造成一段时间内服务不可用。为了解决主从复制的缺点,就有了哨兵机制。

哨兵模式的工作原理

  • 哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:在所有的从节点竞选出新的主节点。每一个哨兵都是一个独立的sentinel进程,作为进程,它会独立运行。
  • 当master挂掉之后,哨兵会自动从slave中选一个作为master,若master重新启动,master则会转化为现有的master下的一个slave,当slave切换时,会通过发布订阅方式,将slave所对应的master更改。
  • 哨兵本身也有单点故障的问题,所以在一个一主多从的Redis系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。

哨兵模式的作用

  • 监控: 哨兵会不断地检查你的Master和Slave是否运作正常。
  • 提醒: 当被监控的某个Redis节点出现问题时,哨兵可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移: 当一个Master不能正常工作时,哨兵会进行自动故障迁移操作,将失效Master的其中一个Slave升级为新的Master,并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用新Master代替失效Master。

主节点的选择

哨兵leader根据以下规则从客观下线的主服务器的从服务器中选择出新的主服务器。

  1. 过滤掉主观下线的节点
  2. 选择slave-priority最高的节点,如果由则返回没有就继续选择
  3. 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没有就继续
  4. 选择run_id最小的节点,因为run_id越小说明重启次数越少

哨兵模式的缺点

  • redis 采用异步复制的方式,意味着当主节点挂掉时,从节点可能没有收到全部的同步消息,这部
  • 分未同步的消息将丢失。如果主从延迟特别大,那么丢失可能会特别多。sentinel 无法保证消息完
  • 全不丢失,但是可以通过配置来尽量保证少丢失。

哨兵模式的构成

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

搭建Redis哨兵模式

哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式

环境

  • Master节点:192.168.10.11
  • Slave1节点:192.168.10.12
  • Slave2节点:192.168.10.13

image.png

systemctl stop firewalld
setenforce 0

修改配置文件(master、slave1、slave2)

这边拿master示例

[root@master ~]# vim /opt/redis-5.0.7/sentinel.conf
·················
17 protected-mode no  #关闭保护模式(取消注释)
·················
21 port 26379  #Redis哨兵默认的监听端口
·················
26 daemonize yes  #指定sentinel为后台启动
·················
36 logfile "/var/log/sentinel.log"  #指定日志存放路径
·················
65 dir "/var/lib/redis/6379"  #指定数据库存放路径
·················
84 sentinel monitor mymaster 192.168.42.11 6379 2  #指定该哨兵节点监控192.168.42.11:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移
·················
113 sentinel down-after-milliseconds mymaster 15000  #判定服务器down掉的时间周期,默认30000毫秒,这边修改为15146 sentinel failover-timeout mymaster 180000  #故障节点的最大超时时间为180000180秒)

启动哨兵模式中,先启动master节点的,在启动slave节点的
[root@master ~]# cd /opt/redis-5.0.7/
[root@master redis-5.0.7]# redis-sentinel sentinel.conf &
#后台启动哨兵模式
[root@master redis-5.0.7]# lsof -i:45436
#查看进程
[root@master redis-5.0.7]# lsof -i:26379
#查看端口
[root@master redis-5.0.7]# redis-cli -p 26379 info Sentinel
#查看哨兵信息

image.png

image.png

image.png

image.png

image.png

image.png

image.png

故障模拟(master)

[root@master redis-5.0.7]# ps -ef | grep redis
#查看redis-server进程号
[root@master redis-5.0.7]# kill -9 6719
#杀死master节点上的Redis-server的进程号

image.png

验证结果

[root@master redis-5.0.7]# tail -f /var/log/sentinel.log
#实时查看日志
其中一个故障,哨兵节点检测到,就选举其他的节点为哨兵(这边就一个哨兵,所以直接换其他的)
[root@master redis-5.0.7]# redis-cli -p 26379 INFO Sentinel
#查看哨兵信息

image.png

image.png

Redis集群模式

为什么需要Redis集群

单实例存Redis缓存会存在的几个问题:

  • 基本上大多是写都是在一个master节点上,压力太大
  • 海量数据的存储压力

对于这些问题,Redis集群提供了较为完善的方案,解决了存储能力受到单机限制,写操作无法负载均衡的问题。

集群什么时候不可以使用

  1. 无主从备份,某一节点宕机
  2. 某一节点主从全部宕机
  3. 超半数主节点宕机

什么是Redis集群

Redis集群实现了在多个Redis节点之间进行数据分片和数据复制。基于Redis集群的数据自动分片能力,我们能够方便地对Redis集群进行横向扩展,以提高Redis集群的吞吐量。基于Redis集群的数据复制能力,在集群中的一部分节点失效或无法进行通信时,Redis仍然可以基于副本数据对外提供服务,这提高了集群的可用性。

哈希算法

  • Redis集群需要用到哈希算法在数据分布中
  • Redis集群采用的算法是哈希槽分区算法。Redis集群中有16384个哈希槽(槽的范围是 0 -16383,哈希槽),将不同的哈希槽分布在不同的Redis节点上面进行管理,也就是说每个Redis节点只负责一部分的哈希槽。在对数据进行操作的时候,集群会对使用CRC16算法对key进行计算并对16384取模(slot = CRC16(key)%16383),得到的结果就是 Key-Value 所放入的槽,通过这个值,去找到对应的槽所对应的Redis节点,然后直接到这个对应的节点上进行存取操作。

哈希算法特点

  • 解耦数据和节点之间的关系,简化了扩容和收缩难度;
  • 节点自身维护槽的映射关系,不需要客户端代理服务维护槽分区元数据
  • 支持节点、槽、键之间的映射查询,用于数据路由,在线伸缩等场景

Redis集群原理

  • 所有Redis节点彼此都通过PING-PONG机制互联,内部使用二进制协议优化传输速度和带宽。
  • 在集群中超过半数的节点检测到某个节点Fail后将该节点设置为Fail状态。
  • 客户端与Redis节点直连,客户端连接集群中任何一个可用节点即可对集群进行操作。
  • Redis-Cluster把所有的物理节点都映射到0-16383的slot(槽)上,Cluster负责维护每个节点上数据槽的分配。Redis的具体数据分配策略为:在Redis集群中内置了16384个散列槽;需要在Redis集群中放置一个Key-Value时,Redis会先对Key使用CRC16算法算出一个结果,然后把结果对16384求余数,这样每个Key都会对应一个编号0-16383的散列槽;Redis会根据节点的数量大致均等地将散列槽映射到不同的节点。

集群的作用

  • 数据分区:集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加;另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。
  • 高可用:集群支持主从复制和主节点的自动故障转移(与哨兵类似);当任一节点发生故障时,集群仍然可以对外提供服务。

image.png

Redis集群搭建

环境

redis的集群一般需要6个节点,3主3从。方便起见,这里所有节点在同一台服务器上模拟:

  • 以端口号进行区分:3个主节点端口号:6001/6002/6003,对应的从节点端口号:6004/6005/6006。
  • master:192.168.42.11,主从复制

创建端口文件夹

[root@master ~]# cd /etc/redis/
[root@master redis]# mkdir -p redis-cluster/redis600{1..6}
#创建端口号redis6001...redis6006

for i in {1..6}
do
cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i
cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis600$i
done
#执行脚本

image.png

image.png

开启群集功能

用6001端口配置为例,后面5-6一样

[root@master redis-cluster]# cd /etc/redis/redis-cluster/redis6001
#6个端口文件夹都需要这样开启
[root@master redis6001]# vim redis.conf
················
69 #bind 127.0.0.1  #注释掉bind 项,默认监听所有网卡
················
88 protected-mode no  #关闭保护模式
················
92 port 6001  #修改,redis监听端口
···············
136 daemonize yes  #开启守护进程,以独立进程启动
···············
699 appendonly yes  #修改,开启AOF持久化
···············
832 cluster-enabled yes  #取消注释,开启群集功能
···············
840 cluster-config-file nodes-6001.conf  #取消注释,群集名称文件设置
···············
846 cluster-node-timeout 15000  #取消注释群集超时时间设置
···············

image.png image.png

image.png

image.png

image.png

启动Redis节点

1,可以分别进入端口的6个文件夹执行:
redis-server redis.conf
启动
2,也可以使用函数启动
for d in {1..6}
do
cd /etc/redis/redis-cluster/redis600$d
redis-server redis.conf
done

[root@master redis6006]# ps -ef | grep redis
#查看Redis

image.png

image.png

启动集群

[root@master redis6006]# redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1
六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点。下面交互的时候 需要输入 yes 才可以创建。
--replicas 1 表示每个主节点有1个从节点。

image.png

测试集群

[root@master redis6006]# redis-cli -p 6001 -c
#-c表示节点之间可以相互转换
127.0.0.1:6001> cluster slots
#查看节点的哈希槽编号范围
127.0.0.1:6001> set name zhangsan
#在6001上设置一个name键,名字叫zhangsan
127.0.0.1:6002> cluster keyslot name
#自动跳转到6002
127.0.0.1:6002> exit
#退出
[root@master redis6006]# redis-cli -p 6004 -c
#再次登录
127.0.0.1:6004> keys *
#查看键

image.png

总结

Redis有三种模式:Redis主从复制模式、Redis哨兵模式、Redis集群模式

Redis主从复制模式

将一台Redis服务器的数据,复制到其他服务器上。

作用:

  • 数据冗余
  • 故障恢复
  • 负载均衡
  • 高可用基石

缺点:

  • 故障恢复无法自动化
  • 写操作无法负载均衡
  • 存储能力受到单机的限制

Redis哨兵模式

哨兵节点作为监控,当有服务器宕机时候,哨兵节点就引入了主节点的自动故障转移

哨兵模式原理:

  • 哨兵(sentinel):是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的 Master并将所有slave连接到新的 Master。所以整个运行哨兵的集群的数量不得少于3个节点。

作用:

  • 监控
  • 自动故障转移
  • 通知或者提醒

缺点:

  • 写操作无法负载均衡:存储能力受到单机的限制

哨兵结构:

  • 哨兵节点
  • 数据节点

主节点选举:

  • 不要下线的
  • 从节点的优先级在配置中最高的
  • 复制偏移量大的

Redis集群模式

集群由多个节点(Node)组成,Redis的数据分布在这些节点中。集群中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。

作用:

  • 数据分区
  • 高可用

缺点:

  • 暂时不知道,等待大家一起发掘!!!