几种常见高可用架构

redis双活方案 redis双中心双活_redis

1、一主多从

读写分离

2、主备(Active-Standby)

正常情况下只有主机在工作,当主机故障通过keepalived切换到备机

  • 热备:备库实时同步主库数据,同城多活
  • 冷备:备库只有在主库挂了才会启动,异地容灾

3、多主

双活:active-active

双活一般用于建设数据中心,包含一个主数据中心
和一个备份数据中心。
主数据中心承载用户数据,备份数据中心为了备份主数据中心数据和配置等。备份数据中心分为三种热备、冷备和多背,热备会对主数据中心进行实时性备份,从而主数据宕机可以快速切换; 冷备不会对数据中心进行实时性备份,会有数据丢失…

双活数据中心主要的目的是让主备数据中心一同工作,既不浪费资源,又会让用户的业务不被轻易的中断,工作时仍然是主数据中心负载多点,备数据中心起到防御的工作,占少一半。
双活就是Active-Active,故名思义就是两边都是活动在线提供服务的,是相对于传统的主备模式Active-Standby模式的。一个真正的双活方案是应该涵盖基础设施、中间件、应用程序各个层次的。

主主架构

配置两台主机,互为主备,互相监控对方二进制日志文件进行同步

多主多从架构:

redis双活方案 redis双中心双活_客户端_02

4、无中心架构

一、主从同步

实现读写分离,主节点和从节点进行全量+增量(offset)同步,通过rdb方式(bgsave)同步,即便redis服务本地并未开启rdb
优点

  • 1、读写分离
  • 2、从服务器保证读请求的高可用,某台从服务器挂了,其他从服务器还能接收请求
  • 3、通过扩展从服务器可以提高读请求的并发量

缺点

  • 1、无法保证写入请求高可用,当主节点故障只能通过人工切换
  • 2、当数据量增大,主服务器压力增大,无法进行水平扩容

二、哨兵机制(redis自带)

非中心化架构,客户端连接到一个哨兵节点,通过哨兵节点转发到master节点(哨兵节点会连接所有redis节点),哨兵节点对redis节点进行监控实现故障转移

redis双活方案 redis双中心双活_redis_03

哨兵主要配置:
1、监控的redis节点,选举master所需票数?
2、心跳超时时间,超时判断redis节点下线

  • 主观下线:
    客观下线:

通过raft协议选举一个哨兵节点去选举redis的master节点,哨兵节点之间通过redis的pub/sub进行通信

优点:解决了单点故障的问题,当master节点挂了,可以通过哨兵节点实现故障转移
缺点:由于只有一个master,当主从切换的时候势必会丢失部分数据;同主从架构,无法进行水平扩容

三、数据分片

1、Codis(服务端代理类)

设计理念同mycat和sharding-proxy,主要有以下3个角色

redis双活方案 redis双中心双活_数据中心_04

1、codis proxy:无状态代理服务,仅需数据同步,实现了redis协议,这样客户端可以直接连接到codis proxy转发到redis节点进行通信
2、codis-redis-group:一个group代表一个数据分片,包含了一主多从的redis节点
3、coordinator(zk或ETCD):用来管理proxy之间的数据同步

proxy转发:将请求的key进行hash取模至各个槽点的分发(CRC32 hash算法,Codis默认1024个槽,可根据节点数量自行配置),槽位间信息同步给coordinator管理
缺点:增加了proxy作为中转层,所以网络开销上会比单个redis节点性能有所下降,可以通过增加proxy数量来尽可能减少这块性能损耗

2、Redis Cluster(官方,服务端)

无中心架构
每个节点都保存数据和整个集群的节点状态
每个节点都和集群中的其它节点保持连接
使用gossip协议传播信息以及发现新的节点
节点不作为client请求的代理,client应该根据节点返回的错误信息重定向到目标client

gossip:病毒传播协议
master-slave:主备高可用
通过对key的CRC16算法得到hash值,然后hash值跟hash槽数(默认16384)取模得到slot槽号,从而算出分布到哪个slot hash槽。每个分片槽数是平均的(N个redis分片均分16384个槽)
![在这里插入图片描述](https://img-blog.csdnimg.cn/ff857283992947b18091340e95eaeeb9.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaXpodWxpdXNz,size_16,color_FFFFFF,t_70

新增或下线Master节点,数据如何迁移(重新分配)?

支持在线扩缩容,基于slot的数据分布方式大大降低了迁移成本,只需将数据slot从一个redis node迁移到另一个redis node即可完成迁移工作 。

当slot从一个Node A向另一个Node B迁移时,Node A和Node B都会有这个slot,Node A上slot的状态设置为migrating(迁移),Node B上的状态被设置为importing(引入)。此时当客户端请求时,所有key在Node A上的请求都由A来处理,所有不在A上的key都由Node B来处理。同时,Node A上将不会创建新的key。

客户端重定向

127.0.0.1:7291>set name xh
(error)MOVED 13724 127.0.0.1:7293

比如在7291端口的Redis的redis-cli客户端操作,服务端返回MOVED,也就是根据key计算出来的slot不归7291端口管理,而是7293端口管理,服务端返回MOVED告诉客户端去7293端口操作。
解决方案:Jedis等客户端会在本地维护一份slot-node映射关系,大部分时候不需要重定向

使用这个配置,查询过程中,我们就无需管数据具体落在哪个主节点上了

spring.redis.cluster.nodes=ip:7291,ip:7292,ip:7293
spring.redis.cluster.max-redirects=2
spring.redis.cluster.timeout=5000
spring.redis.cluster.max-attempts=3

缺点:client端不支持多key操作(mget,mset等),但当keys集合对应的slot相同时支持mget操作。参考:http://www.redis.io/commands/cluster-keyslot