Redis作为存储服务,高可用、高可靠肯定跑不了,Redis最简单方式就是主从模式,主用来扛流量,从用来做数据备份,基本就ok了,如果想要更高级别的保障呢,还有哨兵模式跟集群模式,我们接下来主要分析下这三种模式
主从模式
主从模式本质上就是个数据同步,先配置好主从,当slave启动时,会向master发送同步请求,master会创建快照,然后将快照发送给slave,slave加载快照,此时完成了全量同步,但是在全量同步的过程中master还在扛线上的流量,可能还会有源源不断的命令进来,master不仅会执行这些命令,还会缓存起来,然后同步给slave,slave执行这些命令,这就是增量同步过程,后续有新命令也是重复增量同步过程。slave还会保存一个master的运行id,当slave断开重连后,会将这个运行id发送给master,master拿到运行id后会复制偏移量给slave完成数据同步。
总结一些主从模式的关键词:
- 全量同步
- 增量同步
- 运行id
- 复制偏移量
哨兵模式
哨兵可以看做是监控,会不断地检查Master和Slave是否运行正常,如果发现异常,会通知管理员和客户端,当然,通知肯定不管用,还会有故障转移,自动切换主从,更新配置信息
上图是Redis哨兵模式的架构图,当Master故障后,哨兵会进行故障转移切换主从,客户端收到哨兵通知后还需要从哨兵集群获取新的master信息,然后重新建立链接,这样对客户端还不是特别的友好,这个地方其实我们可以改进一下,架构图如下
当哨兵需要切换主从的时候,通知VIP,修改VIP的映射,飘到相应的节点,这种情况主从切换对Client来说是透明的,也会舒服很多。
集群模式
集群模式就不需要哨兵了,是个分布式方案,支持水平扩容,空间不够了可以添加分组,扩展slot
集群模式下客户端不支持批量操作,客户端同时查多个key,但是不知道多个key分别落在哪组主从里,只能一个个查询,这是个天然的问题,而且客户端要知道key在哪个slot,需要通过计算才能知道,知道在哪个slot,但是不知道slot在那组主从,这个对客户端很不友好,那么客户端一般会怎么访问呢,看下图:
客户端先向集群任意一个Master发送请求,Master收到请求后进行计算,判断数据是否在自身,如果是,则执行命令,如果不是,则重定向,告诉客户端访问哪个节点,客户端拿到节点信息,访问真正的目标redis。虽然集群模式与哨兵模式相比,可以水平扩展,但问题是路由这块客户端是搞不定的,需要请求任意节点才能知道真正的目标节点,大概率会产生两次交互(因为集群里有很多分组,目标只是其中之一,集群分组越多,两次交互概率越大),存在一定的性能问题。接下来让我们看下redis的分布式解决方案(集群也是分布式解决方案,但是我们刚才分析了集群模式存在的问题,不支持批量操作,有两次交互),Codis
Codis的最底层codis-redis-group其实就是一组一组的Redis主从,如果空间不足可以随时水平扩展,上一层是codis-proxy,其实就是支持redis协议的代理,所有的客户端请求都由porxy处理,路由也由proxy搞定,多了一层代理,性能会稍微差一点,但是会比集群好很多,Codis优点:
- 数据分片策略对客户端透明
- zk作为name server
- 提供支持Redis协议的Proxy
- Proxy支持Redis协议