什么是 Redis 主从同步?
Redis 的主从同步(replication)机制,允许 Slave 从 Master 那里,通过网络传输拷贝到完整的数据备份,从而达到主从机制。
主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据。
一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。
第一次同步时,主节点做一次 bgsave 操作,并同时将后续修改操作记录到内存 buffer ,待完成后将 RDB 文件全量同步到复制节点,复制节点接受完成后将 RDB 镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
好处
通过 Redis 的复制功,能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。
Redis 主从同步,是很多 Redis 集群方案的基础,例如 Redis Sentinel、Redis Cluster 等等。
分类1:主从复制 Replication
镜像:增删改在主节点(主<退化到单节点>);查询负载到从节点
- Master的高可用:Sentinel(哨兵):如果发现master宕机,立马将一个从节点变成master
- 一个Redis服务可以有多个该服务的复制品,这个Redis服务称为Master,其他复制品称为Slaves
- 只要网络连接正常,Master会一直将自己的数据更新同步给Slaves,保持主从同步
- 只有Master可以执行写命令,Slaves只能执行读命令
1.1 主从复制创建
- redis-server --slaveof ,配置当前服务称为某Redis服务的Slave
- redis-server --port 6380 以主身份启动
- redis-server --port 6380 --slaveof 127.0.0.1 6379 以从身份启动
- SLAVEOF host port命令,将当前服务器状态从Master修改为别的服务器的Slave
- redis > SLAVEOF 192.168.1.1 6379,将服务器转换为Slave
- redis > SLAVEOF NO ONE ,将服务器重新恢复到Master,不会丢弃已同步数据
- 配置方式:启动时,服务器读取配置文件,并自动成为指定服务器的从服务器
- slaveof
- slaveof 127.0.0.1 6379
1.2 哨兵
高可用 Sentinel
- 官方提供的高可用方案,可以用它管理多个Redis服务实例
- 编译后产生redis-sentinel程序文件
- Redis Sentinel是一个分布式系统,可以在一个架构中运行多个Sentinel进程
监控 Monitoring
- Sentinel会不断检查Master和Slaves是否正常
- 每一个Sentinel可以监控任意多个Master和该Master下的Slaves
Sentinel网络
- 监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监视服务器的信息,将主服务器判断为下线失效至少需要2个Sentinel同意,如果多数Sentinel同意才会执行故障转移
Sentinel 配置文件 - 至少包含一个监控配置选项,用于指定被监控Master的相关信息。
- Sentinel monitor,例如sentinel monitor mymaster 127.0.0.1 6379 2
监视mymaster的主服务器,服务器ip,端口,将这个主服务器判断为下线失效至少需要2个Sentinel同意,如果多数Sentinel同意才会执行故障转移 - Sentinel会根据Master的配置自动发现Master的Slaves
- Sentinel默认端口号为26379
Sentinel 总结 - 主从复制,解决了读请求的分担,从节点下线,会使得读请求能力有所下降
- Master只有一个,写请求单点问题
- Sentinel会在Master下线后自动执行Failover操作,提升一台Slave为Master,并让其他Slaves重新成为新Master的Slaves
- 主从复制+哨兵Sentinel只解决了读性能和高可用问题,但是没有解决写性能问题
Redis 哨兵集群实现高可用
分类2:分布式
redis 集群模式的工作原理
twemproxy:切片 集群 Cluster
自动将数据进行分片,每个 master 上放一部分数据
提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的
- 由多个Redis服务器组成的分布式网络服务集群
- 每一个Redis服务器称为节点Node,节点之间会互相通信。两两相连
- Redis集群无中心节点
- 每个节点既是主节点,又是哨兵
2.1 Redis集群分片
- 集群将整个数据库分为16384个槽位slot,所有key数据储存在这些slot中的一个,key的槽位计算公式为slot_number=crc16(key)%16384,其中crc16为16位的循环冗余校验和函数
- 集群中的每个主节点都可以处理0个至16383个槽,当16384个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求
2.2 Redis集群节点复制
- Redis集群的每个节点都有两种角色可选:主节点master node、从节点slave node。其中主节点用于存储数据,而从节点则是某个主节点的复制品
- 当用户需要处理更多读请求的时候,添加从节点可以扩展系统的读性能,因为Redis集群重用了单机Redis复制特性的代码,所以集群的复制行为和我们之前介绍的单机复制特性的行为是完全一样的
2.3 Redis集群故障转移 - Redis集群的主节点内置了类似Redis Sentinel的节点故障检测和自动故障转移功能,当集群中的某个主节点下线时,集群中的其他在线主节点会注意到这一点,并对已下线的主节点进行故障转移
- 集群进行故障转移的方法和Redis Sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以集群不必另外使用Redis Sentinel
举例
三个主节点7000、7001、7002平均分片16384个slot槽位 - 节点7000指派的槽位为0到5060
- 节点7001指派的槽位为5461到10022
- 节点7002指派的槽位为10923到16383
- 节点7003指派的槽位为5061到5460,10023-10922
2.4 Redis集群Redirect转向
- 由于Redis集群无中心节点,请求会发给任意主节点
- 主节点只会处理自己负责槽位的命令请求,其它槽位的命令请求,该主节点会返回客户端一个转向错误
- 客户端根据错误中包含的地址和端口重新向正确的负责的主节点发起命令请求
2.3 Redis集群搭建
- 创建多个主节点
- 为每一个节点指派slot槽位,将多个节点连接起来,组成一个集群
- 槽位分片完成后,集群进入上线状态
- 6个节点:3个主节点,每一个主节点有一个从节点(由rubby手动指定谁是主谁是从)
2.4 Redis集群总结
- Redis集群是一个由多个节点组成的分布式服务集群,它具有复制、高可用和分片特性
- Redis的集群没有中心节点,并且带有复制和故障转移特性,这可用避免单个节点成为性能瓶颈,或者因为某个节点下线而导致整个集群下线
- 集群中的主节点负责处理槽(储存数据),而从节点则是主节点的复制品
- Redis集群将整个数据库分为16384个槽,数据库中的每个键都属于16384个槽中的其中一个
- 集群中的每个主节点都可以负责0个至16384个槽,当16384个槽都有节点在负责时,集群进入上线状态,可以执行客户端发送的数据命令
- 主节点只会执行和自己负责的槽有关的命令,当节点接收到不属于自己处理的槽的命令时,它将会处理指定槽的节点的地址返回给客户端,而客户端会向正确的节点重新发送
- 如果需要完整地分片、复制和高可用特性,并且要避免使用代理带来的性能瓶颈和资源消耗,那么可以选择使用Redis集群;如果只需要一部分特性(比如只需要分片,但不需要复制和高可用等),那么单独选用twemproxy、Redis的复制和Redis Sentinel中的一个或多个