Redis如何应对海量访问请求?
作者:程序员马丁
在线博客:https://open8gu.com
note
大话面试,技术同学面试必备的八股文小册,以精彩回答应对深度问题,助力你在面试中拿个offer。
回答话术
如果想让 Redis 应对海量流量访问,可以在客户端和 Redis 真实节点之间,加上一层代理服务。
具体流程如下:
- 负责在客户端和 Redis 节点之间转发请求和响应:客户端只和代理服务打交道,代理收到客户端的请求之后,再转发到对应的 Redis 节点上,节点返回的响应再经由代理转发返回给客户端;
- 负责监控集群中所有 Redis 节点状态:如果发现有问题节点,及时进行主从切换;
- 维护集群的元数据:这个元数据主要就是集群所有节点的主从信息,以及槽和节点关系映射表。
像开源的 Redis 集群方案 twemproxy 和 Codis,都是这种架构的。另外像分库分表中间件 ShardingSphere Proxy 原理同样如此。
这个架构最大的优点是对客户端透明,在客户端视角来看,整个集群和一个超大容量的单节点 Redis 是一样的。并且,由于分片算法是代理服务控制的,扩容也比较方便,新节点加入集群后,直接修改代理服务中的元数据就可以完成扩容。
不过,这个架构的缺点也很突出,增加了一层代理转发,每次数据访问的链路更长了,必然会带来一定的性能损失。而且,代理服务本身又是集群的一个单点,当然,我们可以把代理服务也做成一个集群来解决单点问题。
扩展文章,得物 Redis 缓存架构,基本上与上面讲的架构模型一致,详情查看:得物 Redis 设计与实践 sourl.cn/TUC2Lt
问题详解
1. 客户端嵌入寻址服务
除了上面这种架构外,还有另外一种方式是,不用这个代理服务,把代理服务的寻址功能前移到客户端中去。客户端在发起请求之前,先去查询元数据,就可以知道要访问的是哪个分片和哪个节点,然后直连对应的 Redis 节点访问数据。JAVA 客户端 Jedis 就支持这个功能。
当然,客户端不用每次都去查询元数据,因为这个元数据是不怎么变化的,客户端可以自己缓存元数据,这样访问性能基本上和单机版的 Redis 是一样的。