文章目录
Redis集群
Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
为什么要使用Redis集群?
因为单台的Redis服务器一旦宕机,就无法正常的提供服务了;
单台Redis服务器的读写性能有限,利用集群可以提高读写能力
总结起来使用集群的原因可以归为提高服务器的稳定性和提高读写能力
redis有三种集群模式,分别为主从模式,哨兵模式以及集群模式,其中主从是最常见的模式
1,主从复制
1.1 介绍
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器、前者为主节点(master/leadaer),后者称为从节点(slave/follower)
数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。
默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制原理
slave节点会向master发送一个SYNC的命令,master收到命令之后会生成数据快照。第二步把数据快照发送给slave节点,slave节点收到数据以后丢弃旧的数据并重新载入新的数据,并对外提供服务。
redis提供了全量复制和增量复制两种模式。
优点:
- 读写分离,性能扩展
- 容灾快速恢复
主从复制的主要作用
- 数据冗余:只从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,实际上时一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供给写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其时在写少读多的场景下,通过多个从节点分担读的负载,可以大大提高Redis服务器的并发量
- 高可用基石:除了上述作用意外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制时Redis高可用的基础。
1.2 环境搭建
info replication 查看当前库的信息
127.0.0.1:6379> info replication
# Replication
role:master # 角色 master主机 slave 从机
connected_slaves:0 # 连接的从机数
master_failover_state:no-failover
master_replid:19b4fce0b0197148f7abc416253a5c2824cb9eed
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
复制三个配置文件,并修改其对应信息
cat zabbix_server.conf | grep -Ev '#|^$'
- 端口
- pid进程名字
- log文件名字
- dump.rdb名字
port 6379
pidfile /var/run/redis_6379.pid
logfile "6379.log"
dbfilename dump6379.rdb
修改完就不能开启自启了,需要手动选择配置文件启动三个redis服务
然后用三个配置文件去启动启动之后用ps -ef|grep redis
查看是否开启
[root@192 redis-7.0.10]# systemctl stop redis
[root@192 redis-7.0.10]# redis-server ./redis-6379.conf
[root@192 redis-7.0.10]# redis-server ./redis-6380.conf
[root@192 redis-7.0.10]# redis-server ./redis-6381.conf
[root@192 redis-7.0.10]# ps -ef|grep redis
root 1529 1 0 19:03 ? 00:00:05 redis-server *:6379
root 1687 1 0 20:03 ? 00:00:00 redis-server *:6380
root 1693 1 0 20:03 ? 00:00:00 redis-server *:6381
root 1699 1062 0 20:03 pts/0 00:00:00 grep --color=auto redis
打开三个客户端口分别连接6379,6380,6381
[root@192 redis-7.0.10]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:19b4fce0b0197148f7abc416253a5c2824cb9eed
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
只配从库不用配主库!(默认情况下,每台Redis服务器都是主节点)
确定分配主机(6379)和从机(6380,6381)
在从机上执行客户端命令 指定主机
slaveof 127.0.0.1 6379
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> info replicarion
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_read_repl_offset:14
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:ee387d4084af80833043156c1cc372ef07509bdd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:
主机上查看信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2 #两台从机
slave0:ip=127.0.0.1,port=6380,state=online,offset=84,lag=0
slave1:ip=127.0.0.1,port=6381,state=wait_bgsave,offset=0,lag=0
master_failover_state:no-failover
master_replid:ee387d4084af80833043156c1cc372ef07509bdd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
127.0.0.1:6379>
也可以通过配置文件配置主机
# replicaof <masterip> <masterport>
replicaof 127.0.0.1 6379
主机写,从机度。主机写的数据会同步到从机上。从机如果写数据会报错
127.0.0.1:6379> set count 14
(error) READONLY You can't write against a read only replica.
如果连不上,关闭主机防火墙或开放端口 ,
如果主机有密码,则在从机的配置文件中配置
# masterauth <master-password>
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --reload
如果主机断开连接了,从机依旧是连接到主机的,但是写操作做不了了,但如果主机又回来了,从机依旧可以直接获取到主机写进去的信息!
如果从机断开了,从机就会变成主机。读不了主机数据了。只要从新配置主机信息即可。
Slave 启动成功连接到 master 后会发送一个sync同步命令
Master 接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步。
全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制: Master 继续将新的所有收集到的修改命令依次传给slave,完成同步
但是只要是重新连接master,一次完全同步(全量复制)将被自动执行! 我们的数据一定可以在从机中看到!
2,哨兵模式
在 Redis 主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,同时数据安全性也得不到保障,因此主从模式的可用性较低,不适用于线上生产环境。
Redis 官方推荐一种高可用方案,也就是 Redis Sentinel 哨兵模式,它弥补了主从模式的不足。Sentinel 通过监控的方式获取主机的工作状态是否正常,当主机发生故障时, Sentinel 会自动进行 Failover(即故障转移),并将其监控的从机提升主服务器(master),从而保证了系统的高可用性。
1.1 哨兵模式原理
哨兵模式是一种特殊的模式,Redis 为其提供了专属的哨兵命令,它是一个独立的进程,能够独立运行。下面使用 Sentinel 搭建 Redis 集群,基本结构图如下所示
在上图过程中,哨兵主要有两个重要作用:
- 第一:哨兵节点会以每秒一次的频率对每个 Redis 节点发送
PING
命令,并通过 Redis 节点的回复来判断其运行状态。 - 第二:当哨兵监测到主服务器发生故障时,会自动在从节点中选择一台将机器,并其提升为主服务器,然后使用 PubSub 发布订阅模式,通知其他的从节点,修改配置文件,跟随新的主服务器。
在实际生产情况中,Redis Sentinel 是集群的高可用的保障,为避免 Sentinel 发生意外,它一般是由 3~5 个节点组成,这样就算挂了个别节点,该集群仍然可以正常运转。其结构图如下所示:
上图所示,多个哨兵之间也存在互相监控,这就形成了多哨兵模式,现在对该模式的工作过程进行讲解,介绍如下:
1) 主观下线
主观下线,适用于主服务器和从服务器。如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”。比如 Sentinel1 向主服务发送了PING
命令,在规定时间内没收到主服务器PONG
回复,则 Sentinel1 判定主服务器为“主观下线”。
2) 客观下线
客观下线,只适用于主服务器。 Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果超过半数以上的 Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。
3) 投票选举
投票选举,所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订功能通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。
对上对述过程做简单总结:
Sentinel 负责监控主从节点的“健康”状态。当主节点挂掉时,自动选择一个最优的从节点切换为主节点。客户端来连接 Redis 集群时,会首先连接 Sentinel,通过 Sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互。当主节点发生故障时,客户端会重新向 Sentinel 要地址,Sentinel 会将最新的主节点地址告诉客户端。因此应用程序无需重启即可自动完成主从节点切换。
-
每个 Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的 Master 主服务器,Slave 从服务器以及其他 Sentinel(哨兵)进程发送一个 PING 命令。
-
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)。
-
如果一个 Master 主服务器被标记为主观下线(SDOWN),则正在监视这个 Master 主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认 Master 主服务器的确进入了主观下线状态。
-
当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认 Master 主服务器进入了主观下线状态(SDOWN), 则 Master 主服务器会被标记为客观下线(ODOWN)。
-
在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master 主服务器、Slave 从服务器发送 INFO 命令。
-
当 Master 主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master 主服务器的所有 Slave 从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
-
若没有足够数量的 Sentinel(哨兵)进程同意 Master 主服务器下线, Master 主服务器的客观下线状态就会被移除。若 Master 主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master 主服务器的主观下线状态就会被移除。
1.2 哨兵模式应用
(1)将服务器调整为一主二从模式,6379带着6380、6381
(2)在myredis目录下新建sentinel.conf文件【名字不能错!】
(3)在文件中写入以下内容
# 其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量。
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel monitor <master-name> <ip> <redis-port> <quorum>
#quorum 表示最少有几个哨兵认可客观下线,同意故障转移的法定票数
第二个配置项表示:让 sentinel 去监控一个地址为 ip:port 的主服务器,这里的 master-name 可以自定义; 是一个数字,表示当有多少个 sentinel 认为主服务器宕机时,它才算真正的宕机掉,通常数量为半数或半数以上才会认为主机已经宕机, 需要根据 sentinel 的数量设置。
(4)启动sentienl哨兵
redis-sentinel /myredis/sentinel.conf
方式一:
redis-sentinel sentinel.conf
方式二:
redis-server sentinel.conf --sentinel
如果主机挂掉,哨兵会自动在从机选举中产生新的主机。如果原主机上线,则会变成从机。
优先级在redis.conf中默认:slave-priority 100,值越小优先级越高
如果您想开启多个哨兵,只需配置要多个 sentinel.conf 文件即可,一个配置文件开启一个。
1.3 sentinel.conf配置项
下面对 Sentinel 配置文件的其他配置项做简单说明:
配置项 | 参数类型 | 说明 |
---|---|---|
dir | 文件目录 | 哨兵进程服务的文件存放目录,默认为 /tmp。 |
port | 端口号 | 启动哨兵的进程端口号,默认为 26379。 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 在指定的毫秒数内,若主节点没有应答哨兵的 PING 命令,此时哨兵认为服务器主观下线,默认时间为 30 秒。 |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个 Redis 服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求就越高。 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障转移允许的毫秒数,若超过这个时间,就认为故障转移执行失败,默认为 3 分钟。 |
sentinel notification-script | <服务名称><脚本路径> | 脚本通知,配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。 |
sentinel auth-pass | <服务器名称><密码> | 若主服务器设置了密码,则哨兵必须也配置密码,否则哨兵无法对主从服务器进行监控。该密码与主服务器密码相同。 |
Redis Sentinel 配置文件 (sentinel.conf
) 示例
下面是一个典型的 Redis Sentinel 配置文件示例,详细说明了如何设置一个监控Redis主从节点的哨兵实例。
1. 基本设置
-
设置哨兵实例运行的端口,默认为26379:
port 26379
-
设置哨兵的工作目录:
dir /tmp
2. 主节点监控配置
- 监控的Redis主节点的IP和端口:
# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。 # quorum 配置多少个sentinel哨兵统一认为master主节点失联 那么这时客观上认为主节点失联了 sentinel monitor mymaster 127.0.0.1 6379 2 # 注意这里的2表示至少需要两个哨兵同意才能触发故障转移
3. 安全设置
- 设置哨兵连接主从节点的密码,注意必须为主从设置一样的验证密码:
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd # 如果Redis启用了认证,则需配置此选项
4. 故障检测和处理
-
指定多少毫秒之后,如果主节点没有应答哨兵,此时哨兵主观上认为主节点下线(默认30秒):
sentinel down-after-milliseconds mymaster 30000 # 调整超时时间根据网络状况
-
在发生failover主备切换时,最多可以有多少个slave同时对新的master进行同步。这个数字越小,完成failover所需的时间就越长;但如果这个数字越大,就意味着越多的slave因为replication而不可用:
sentinel parallel-syncs mymaster 1 # 推荐设置为1以避免过多的从节点不可用
-
故障转移的超时时间(
failover-timeout
),可用于多个场景,默认为三分钟:sentinel failover-timeout mymaster 180000 # 单位为毫秒
5. 自动化脚本执行
-
当系统运行不正常时,通过邮件通知相关人员:
# sentinel notification-script <master-name> <script-path> sentinel notification-script mymaster /var/redis/notify.sh # 需要确保脚本存在且可执行
-
当一个master由于failover而发生改变时,通知相关的客户端关于master地址已经发生改变的信息:
# sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-script mymaster /var/redis/reconfig.sh # 通常由运维人员配置