几种常见高可用架构
1、一主多从
读写分离
2、主备(Active-Standby)
正常情况下只有主机在工作,当主机故障通过keepalived切换到备机
- 热备:备库实时同步主库数据,同城多活
- 冷备:备库只有在主库挂了才会启动,异地容灾
3、多主
双活:active-active
双活一般用于建设数据中心,包含一个主数据中心
和一个备份数据中心。
主数据中心承载用户数据,备份数据中心为了备份主数据中心数据和配置等。备份数据中心分为三种热备、冷备和多背,热备会对主数据中心进行实时性备份,从而主数据宕机可以快速切换; 冷备不会对数据中心进行实时性备份,会有数据丢失…
双活数据中心主要的目的是让主备数据中心一同工作,既不浪费资源,又会让用户的业务不被轻易的中断,工作时仍然是主数据中心负载多点,备数据中心起到防御的工作,占少一半。
双活就是Active-Active,故名思义就是两边都是活动在线提供服务的,是相对于传统的主备模式Active-Standby模式的。一个真正的双活方案是应该涵盖基础设施、中间件、应用程序各个层次的。
主主架构
配置两台主机,互为主备,互相监控对方二进制日志文件进行同步
多主多从架构:
4、无中心架构
一、主从同步
实现读写分离,主节点和从节点进行全量+增量(offset)同步,通过rdb方式(bgsave)同步,即便redis服务本地并未开启rdb优点
:
- 1、读写分离
- 2、从服务器保证读请求的高可用,某台从服务器挂了,其他从服务器还能接收请求
- 3、通过扩展从服务器可以提高读请求的并发量
缺点
:
- 1、无法保证写入请求高可用,当主节点故障只能通过人工切换
- 2、当数据量增大,主服务器压力增大,无法进行水平扩容
二、哨兵机制(redis自带)
非中心化架构,客户端连接到一个哨兵节点,通过哨兵节点转发到master节点(哨兵节点会连接所有redis节点),哨兵节点对redis节点进行监控实现故障转移
哨兵主要配置:
1、监控的redis节点,选举master所需票数?
2、心跳超时时间,超时判断redis节点下线
- 主观下线:
客观下线:
通过raft协议选举一个哨兵节点去选举redis的master节点,哨兵节点之间通过redis的pub/sub进行通信
优点
:解决了单点故障的问题,当master节点挂了,可以通过哨兵节点实现故障转移缺点
:由于只有一个master,当主从切换的时候势必会丢失部分数据;同主从架构,无法进行水平扩容
三、数据分片
1、Codis(服务端代理类)
设计理念同mycat和sharding-proxy,主要有以下3个角色
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个槽)
?
支持在线扩缩容,基于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