背景
几乎所有系统都是在业务不断推进中演进的,包括淘宝、京东等,我们使用的组件自身也在不断的升级和完善,Redis亦是如此,为了支持更多的场景,更好的性能和吞吐等,其架构也在不断演进:
- 单机;
- 主从;
- 高可用;
- 集群;
我这里只说常见的上面几种。
单机模式
单机模式是客户端直连一个redis实例即可,有以下优缺点:
优点:
- 简单(架构简单,部署简单);
- 方便(开发方便,直接连上redis-server就行);
缺点:
- 单点问题;
- 性能瓶颈;
- 可靠性弱;
主从模式
在分布式系统中为了解决单点问题,通常会把数据复制多个Replication(称为 ‘副本’)部署到其他机器,满足故障恢复和负载均衡等需求。Redis亦是如此,它为我们提供了复制功能,实现了相同数据的多个Redis副本。
Redis的复制模式结构可以支持单层或多层复制关系,分为以下三种:
- 一主一从
- 一主多从
- 树状主从
一主一从结构
一主一从结构
这种结构是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持。当应用写命令并发量较高且需要持久化时,可以只在从节点上开启AOF,这样既保证数据安全性同时也避免了持久化对主节点的性能干扰。但是需要注意的是,当主节点关闭持久化功能时,如果主节点脱机要避免自动重启操作。因为主节点之前没有开启持久化功能自动重启后数据集为空,这时从节点如果继续复制主节点会导致从节点数据也被清空的情况,丧失了持久化的意义。安全的做法是在从节点上执行 slaveof no one 断开与主节点的复制关系,再重启主节点从而避免这一问题。
一主多从结构
一主多从结构
一主多从结构(又称为星形拓扑结构)使得应用端可以利用多个从节点实现读写分离。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点的压力。同时在日常开发中如果需要执行一些比较耗时的读命令,如:keys、sort等,可以在其中一台从节点上执行,防止慢查询对主节点造成阻塞从而影响线上服务的稳定性。对于写并发量较高的场景,多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,同时也加重了主节点的负载,影响服务的稳定性。
树状主从结构
树状主从结构
这种结构使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主节点继续向下层复制。通过引入复制中间层,可以有效降低主节点负载和需要传送给从节点的数据量。当主节点需要挂载多个从节点时为了避免对主节点的性能干扰,可以采用树状结构降低主节点压力。
优点:
- 高可用
- 读写分离
缺点:
- 故障恢复需要人工接入
- 主节点的单机风险
高可用模式
高可用结构
Redis主从复制模式下,一旦主节点出现了故障,需要人工干预进行故障转移,无论对于Redis的应用方还是运维方都带来了很大的不便。
Redis Sentinel是一个分布式机构,其中包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行‘协商’,当大多数Sentinel节点都认为主节点不可达时,它们会选举一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。整个过程都是自动的,不需要人工来介入。
优点:
- Redis Sentinel 解决 Redis 主从模式下的高可用问题
缺点:
- 不能解决负载均衡问题
集群模式
集群模式
Redis Cluster 是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。
优点:
- 无中心架构。
- 数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
- 可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除。
- 高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升。
- 降低运维成本,提高系统的扩展性和可用性。
缺点:
- Key 批量操作限制,如使用 mset、mget 目前只支持具有相同 slot 值的 Key 执行批量操作。对于映射为不同 slot 值的 Key 由于 Keys 不支持跨 slot 查询,所以执行 mset、mget、sunion 等操作支持不友好。
- Key 事务操作支持有限,只支持多 key 在同一节点上的事务操作,当多个 Key 分布于不同的节点上时无法使用事务功能。
- Key 作为数据分区的最小粒度,不能将一个很大的键值对象如 hash、list 等映射到不同的节点。
- 其他