Redis主从复制
概念
- 主从复制,是指将一台redis服务的数据,复制到其他的 redis 服务器。前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower),数据的复制是单向的,只能由主节点复制到从节点(主节点以写为主、从节点以读为主)。
- 默认情况下,每台 Redis 服务器都是主节点,一个主节点可以有 0 个或者多个从节点,但是每个从节点只能有一个主节点。
作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余的方式。
- 故障恢复:当主节点故障时,从节点可以暂时替代主节点提供服务,是一种服务冗余的方式。
- 负载均衡:在主从复制的基础上,配合读写分离,有主节点进行写操作,从节点进行读操作,分担服务器的负载;尤其是在多读少写的情境下,通过多个从节点分担负载,提高并发量。
- 高可用基石:主从复制还有哨兵和集群能都实施的基础。
为什么使用集群
- 单台服务器难以负载大量的请求
- 单台服务器故障率高,系统崩坏概率大
- 单台服务器内存容量有限
环境配置
我们在讲解配置文件的时候,注意到有一个 replication 模块
查看当前库的信息: info replication
1 | 127.0.0.1:6379> info replication |
既然需要启动多个服务,就需要多个配置文件。每个配置文件对应修改一下信息:
- 端口号
- pid 文件名
- 日志文件名
- rdb 文件名
启动单机多服务集群:
1 | [root@localhost redis-5.0.4]# ps -aux | grep redis |
一主二从配置
默认情况下,每台 Redis 服务器都是主节点; 我们一般情况下只用配置从机就好了!
使用 REPLICAOF host port 就可以为从机配置主机了。
redis 6380
1 | 127.0.0.1:6380> replicaof 127.0.0.1 6379 |
redis 6381
1 | 127.0.0.1:6381> REPLICAOF 127.0.0.1 6379 |
然后主机上也能看到从机的状态
redis 6379
1 | 127.0.0.1:6379> info Replication |
我们这里使用命令搭建,是暂时的,真实开发中应该在从机配置文件中进行过配置,这样的话就是永久的。
使用规则
从机只读,不能写,主机可读可写但是多用于写。
1
2
3
4
5
6
7
8
9
10
11
12
13
14127.0.0.1:6380> set name yangl
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380>
127.0.0.1:6381> set name yangl
(error) READONLY You can't write against a read only replica.
127.0.0.1:6381>
127.0.0.1:6379> set name yangl
OK
127.0.0.1:6379> get name
"yangl"
127.0.0.1:6379>当主机断电宕机后,默认情况下从机的角色不会发生变化,集群中只是丢失了写操作,当主机恢复以后,又会连上从机恢复原状。
当从机宕机后,若不是使用配置的配置的从机,再次启动后作为主机是无法获取之前主机的数据的,若此次重新配置称为从机,又可以获取到主机的所有数据。这里就是提到一个同步原理。
第二条中提到,默认情况下,主机故障后,不会出现新的主机,有两种方式可以产生新的主机:
- 从机手动执行命令 REPLICAOF no one,这样执行以后从机独立出来称为一个主机
- 使用哨兵模式(自动选举)
如果没有老大了,这个时候能不能选择出来一个老大呢?手动?
如果主机断开了连接,我们可以使用 REPLICAOF no one 让自己变成主机!其他的节点就可以手动连接到最新的主节点(手动)!如果这个时候老大恢复了,那么就重新连接!
哨兵模式
主从切换技术的方法是:当主机宕机后,需要手动把一台服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多的时候,我们优先考虑哨兵模式。
单机单个哨兵
- 通过发送命令,让 Redis 服务器返回监控其运行状态,包括主服务器和从服务器。
- 当哨兵检测到 master 宕机,会自动将 slave 切换成 master , 然后通过 发布订阅模式 通知其他从服务器,修改配置文件,让它们切换成主机。
多哨兵模式
哨兵的核心配置
配置项 | 参数类型 | 作用 |
---|---|---|
port | 整数 | 启动哨兵进程端口 |
dir | 文件夹目录 | 哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒) |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟 |
sentinel notification-script | <服务名称><脚本路径> | 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用 |
1 | sentinel monitor mymaster 127.0.0.1 6379 1 |
- 数字1表示:当一个哨兵主观认为主机断开,就可以客观认为主机故障,然后开始选举新的主机。
测试
1 | redis-sentinel xxx/sentinel.conf |
成功启动哨兵模式
// TOOD
此时哨兵模式监视着我们的主机6379,当我们断开主机后:
// TOOD
哨兵的优缺点
优点
- 哨兵集群,基于主从复制模式,所有的主从复制的优点,他都有
- 主从可以切换,故障可以转移,系统的可用性好
- 哨兵模式是主从模式的升级,手动到自动,更加健壮
缺点
- Redis 不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦
- 实现哨兵模式的配置其实是很麻烦的,里面有很多配置项
哨兵模式的全部配置
完整的哨兵模式配置文件 sentinel.conf
1 | # Example sentinel.conf |
redis 红锁(redlock)
关于分布式锁,一般有三种选择,
- redis
- zk
- DB锁(悲观锁、乐观锁)
其中用的最多的应该是redis。
redis 常用的方式有单节点、主从模式、哨兵模式、集群模式。
单节点在生产环境基本上不会使用,因为不能达到高可用,且连 RDB 或 AOF 备份都只能放在 master 上,所以基本上不会使用。
另外几种模式都无法避免两个问题:
- 异步数据丢失。
- 脑裂问题。
所以redis官方针对这种情况提出了红锁(Redlock)的概念。
假设有5个redis节点,这些节点之间既没有主从,也没有集群关系。客户端用相同的key和随机值在5个节点上请求锁,请求锁的超时时间应小于锁自动释放时间。当在3个(超过半数)redis上请求到锁的时候,才算是真正获取到了锁。如果没有获取到锁,则把部分已锁的redis释放掉。