MST

星途 面试题库

面试题:缓存设计之中等难度:缓存扩容策略的具体实现方式

在后端开发中,假设你使用Redis作为缓存,当业务增长需要对缓存进行扩容时,你会采用哪些常见的策略?请详细说明每种策略的实现步骤以及优缺点。
19.1万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

1. 垂直扩容策略

  • 实现步骤:增加Redis服务器的硬件资源,如增加内存、CPU核心数等。对于云服务提供商(如阿里云Redis),可在控制台直接调整实例规格,选择更高配置的机型。对于自建Redis服务器,需要关闭Redis服务,更换硬件设备后重新启动Redis服务。
  • 优点:实现简单,不涉及对业务架构和代码的大量修改,能快速提升单个Redis实例的性能和存储容量。
  • 缺点:受限于硬件物理资源,成本较高,且提升空间有限。当业务持续增长时,可能很快又会达到硬件瓶颈。

2. 水平扩容策略 - 主从复制 + 读写分离

  • 实现步骤
    • 配置主从关系:在从服务器的配置文件(redis.conf)中设置 slaveof <master_ip> <master_port>,重启从服务器使其成为主服务器的副本。例如,有一台主服务器A,IP为192.168.1.100,端口6379,配置从服务器B为其副本,在B的redis.conf中添加 slaveof 192.168.1.100 6379 并重启。
    • 读写分离:在业务代码中,将读操作路由到从服务器,写操作路由到主服务器。例如,在Java中使用Jedis客户端,可创建两个Jedis实例,一个连接主服务器用于写,另一个连接从服务器用于读。
  • 优点:提升了读性能,可应对大量读请求场景,同时增加了数据冗余,提高了数据安全性。
  • 缺点:存在数据同步延迟问题,从服务器数据可能与主服务器不一致,对于数据一致性要求极高的场景不太适用。写操作仍集中在主服务器,可能成为性能瓶颈。

3. 水平扩容策略 - 分片(Sharding)

  • 实现步骤
    • 客户端分片:在客户端代码中实现分片逻辑。例如,在Python使用Redis - Py库,可根据键的哈希值对分片数量取模来决定数据存储在哪个Redis实例。假设存在3个Redis实例,对键 key1,计算 hash('key1') % 3,根据结果选择对应的实例存储数据。
    • 代理分片(如Twemproxy):安装并配置Twemproxy,在配置文件(如nutcracker.yml)中定义Redis实例列表和分片规则。Twemproxy会作为客户端和Redis实例之间的代理,接收客户端请求并根据配置的规则将请求转发到相应的Redis实例。
    • Redis Cluster(集群分片):搭建Redis Cluster集群,至少需要3个主节点和3个从节点。使用 redis - trib.rb 工具(Redis 3.0及以上版本)创建集群,例如 redis - trib.rb create --replicas 1 <ip1:port1> <ip2:port2> <ip3:port3> <ip4:port4> <ip5:port5> <ip6:port6>,其中前3个为主节点,后3个为从节点。集群会自动分配哈希槽(0 - 16383)到各个主节点,根据键的CRC16值对16384取模来决定键所在的哈希槽,进而确定存储的节点。
  • 优点:有效提升存储容量和读写性能,可扩展性强,能应对大规模数据和高并发请求。
  • 缺点:实现相对复杂,客户端分片需要在每个客户端代码中维护分片逻辑;代理分片增加了代理层的维护成本;Redis Cluster对集群管理和故障转移有一定复杂性,需要额外学习和管理成本。同时,跨分片操作(如跨节点的事务)相对复杂甚至不支持。