Redis如何应对海量访问请求?
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
回答话术
如果想让 Redis 应对海量流量访问,可以在客户端和 Redis 真实节点之间,加上一层代理服务。
具体流程如下:
- 负责在客户端和 Redis 节点之间转发请求和响应:客户端只和代理服务打交道,代理收到客户端的请求之后,再转发到对应的 Redis 节点上,节点返回的响应再经由代理转发返回给客户端;
- 负责监控集群中所有 Redis 节点状态:如果发现有问题节点,及时进行主从切换;
- 维护集群的元数据:这个元数据主要就是集群所有节点的主从信息,以及槽和节点关系映射表。
像开源的 Redis 集群方案 twemproxy 和 Codis,都是这种架构的。另外像分库分表中间件 ShardingSphere Proxy 原理同样如此。
这个架构最大的优点是对客户端透明,在客户端视角来看,整个集群和一个超大容量的单节点 Redis 是一样的。并且,由于分片算法是代理服务控制的,扩容也比较方便,新节点加入集群后,直接修改代理服务中的元数据就可以完成扩容。
不过,这个架构的缺点也很突出,增加了一层代理转发,每次数据访问的链路更长了,必然会带来一定的性能损失。而且,代理服务本身又是集群的一个单点,当然,我们可以把代理服务也做成一个集群来解决单点问题。
扩展文章,得物 Redis 缓存架构,基本上与上面讲的架构模型一致,详情查看:得物 Redis 设计与实践 sourl.cn/TUC2Lt
问题详解
1. 客户端嵌入寻址服务
除了上面这种架构外,还有另外一种方式是,不用这个代理服务,把代理服务的寻址功能前移到客户端中去。客户端在发起请求之前,先去查询元数据,就可以知道要访问的是哪个分片和哪个节点,然后直连对应的 Redis 节点访问数据。JAVA 客户端 Jedis 就支持这个功能。
当然,客户端不用每次都去查询元数据,因为这个元数据是不怎么变化的,客户端可以自己缓存元数据,这样访问性能基本上和单机版的 Redis 是一样的。
如果某个分片的主节点宕机了,新的主节点被选举出来之后,更新元数据里面的信息。对集群的扩容操作也比较简单,除了迁移数据的工作必须要做以外,更新一下元数据就可以了。
虽然说,这个元数据服务仍然是一个单点,但是它的数据量不大,访问量也不大,相对就比较容易实现。我们可以用 ZooKeeper、etcd 甚至 MySQL 都能满足要求。
这个方案应该是最适合超大规模 Redis 集群的方案了,在性能、弹性、高可用几方面表现都非常好,缺点是整个架构比较复杂,客户端不能通用,需要开发定制化的 Redis 客户端,只有规模足够大的企业才负担得起。
2. 抬头看世界,云厂商都怎么做?
为了贴合真实场景,我直接看了对应云厂商的集群版本。看完之后,心里久久不能平静。不得不说,钱到位,给你安排的明明白白的。
国内几个大的云厂商,比如阿里、腾讯等部署架构我也看了,基本就上和咱们回答话术中说的一致,通过添加代理服务解决海量访问等问题。