在云数据库Redis的集群和读写分离架构中,代理服务器(Proxy)承担着路由转发、负载均衡与故障转移等职责。通过了解Proxy的路由转发规则和特定命令的处理方式,有助于您设计更高效的业务系统。

Proxy介绍

图 1. 集群和读写分离架构图
集群和读写分离架构图

代理服务器(Proxy)是Redis实例中的一个组件(单节点架构),不会占用数据分片的资源,通过多个Proxy节点实现负载均衡及故障转移。

Proxy能力 说明
负载均衡和路由转发 Proxy与后端的数据分片建立长连接,负责请求负载均衡和路由转发操作,关于转发规则的介绍,请参见Proxy的路由转发规则
管理只读节点流量 Proxy会实时探测只读节点的状态,当出现下述情况时,Proxy会执行流量管控动作:
  • 只读节点处于异常状态:Proxy会降低该节点的服务权重,如果多次无法连接该节点,Proxy会停止该节点的服务(即不再将流量转发至该节点),待该异常被修复后重新启用该节点。
  • 只读节点处于全量同步状态:Proxy会暂时停止该节点的服务,直到该节点完成全量同步。
缓存热点Key信息 开启代理查询缓存功能(Proxy Query Cache)后,Proxy会缓存热点Key对应的请求和返回信息,当在有效时间内收到同样的请求时直接返回结果至客户端,无需和后端的数据分片交互,可更好地改善对热点Key的发起大量读请求导致的访问倾斜。更多信息,请参见通过Proxy Query Cache优化热点Key问题
说明 该功能仅在集群架构的企业版( 性能增强型)实例中支持。
说明 由于Proxy的演进,Proxy的个数并不完全代表Proxy处理能力,阿里云会保证集群规格中Proxy的配比符合规格说明的要求。

Proxy的路由转发规则

说明 关于各类命令的介绍,请参见 Redis命令支持概览
架构 转发规则 说明
集群架构 基础转发规则
  • 对于操作单个Key的命令,Proxy会根据Key所属的Slot(槽)将请求发送给所属的数据分片。
  • 对于操作多个Key的命令,如果这些Key是储存在不同的数据分片,Proxy会将命令拆分成多个命令分别发送给对应的分片。
特定命令转发规则
  • 发布订阅类命令

    对于PUBLISHSUBSCRIBE等发布订阅命令,Proxy会根据channel name进行Hash计算,并分片至对应数据分片。

    说明 您可以在控制台的性能监控页面选择 数据节点,然后将自定义监控项设置为 Pub/Sub监控组,即可查看各数据分片(默认展示第一个数据分片)中发布与订阅(Pub/Sub)相关命令的监控信息。具体操作,请参见 自定义监控项(旧版)
  • 阿里云自研的命令

    使用阿里云自研的命令(例如IINFOISCAN等)时,如果通过idx参数指定了数据分片ID,Proxy会将这些命令发送到指定的数据分片。更多信息,请参见阿里云自研的Redis命令

读写分离架构 基础转发规则
  • 写请求:Proxy将其直接转发到Master节点。
  • 读请求:Proxy将读请求平均分配到主节点和只读节点,暂不支持自定义控制。例如拥有3个只读节点的实例,主节点和3个只读的读权重均为25%。
    说明 SLOWLOGDBSIZE也属于读命令。
特定命令转发规则
  • SCAN类命令

    Proxy会将HSCANSSCANZSCAN命令发送到到 第一个只读节点 ,当所有只读节点均出现异常时,这些命令会被转发至主节点。

  • 阿里云自研的命令

    使用阿里云自研的命令(例如RIINFORIMONITOR等)时,可通过ro_slave_idx参数指定该命令要转发到的只读节点,通过idx参数指定该命令要转发到的数据分片。更多信息,请参见阿里云自研的Redis命令

  • 其他命令

    Proxy会将事务命令(MULTIEXEC)、Lua脚本命令 (EVALEVALSHA)、SCANINFO、发布订阅命令(PUBLISHSUBSCRIBE等)转发至主节点。

连接数使用说明

通常情况下,Proxy通过与数据分片建立长连接来处理请求,当请求中包含以下命令时,Proxy会根据命令的处理需求在相应的数据分片上创建额外的连接,您需要合理使用下述命令,避免连接数超限。

说明 代理模式下,社区版实例每个数据分片的连接数上限为10,000,企业版实例每个数据分片的连接数上限为30,000。
  • 阻塞类命令:BRPOPBRPOPLPUSHBLPOPBZPOPMAXBZPOPMIN
  • 事务类命令:MULTIEXECWATCH
  • MONITOR类命令:MONITORIMONITORRIMONITOR
  • 订阅命令:SUBSCRIBEUNSUBSCRIBEPSUBSCRIBEPUNSUBSCRIBE
  • SCAN命令:同时在多个DB(数据库)中执行SCAN操作。

常见问题

  • Q:代理(Proxy)模式下,支持哪些跨Slot的多Key命令?

    A:具体为DELEXISTSMGETMSETSDIFFSDIFFSTORESINTERSINTERSTORESUNIONSUNIONSTOREUNLINK

  • Q:对于只进行读操作的Lua脚本,支持将流量分摊至只读节点吗?

    A:支持。您需要将实例的readonly_lua_route_ronode_enable的值设置为1,即仅包含读操作的Lua脚本会被转发到只读副本处理。具体操作,请参见设置实例参数

  • Q:代理(Proxy)模式和直连模式有什么区别,推荐使用什么模式?
    A:推荐使用代理模式,介绍与区别如下:
    • 集群架构和读写分离架构的实例默认提供代理(Proxy)连接地址,客户端的请求由代理节点转发至数据分片,可享受代理节点带来的负载均衡、读写分离、故障转移、代理查询缓存、长连接等特性能力。
    • 对于集群架构的实例,可申请直连地址,通过该地址可绕过代理,直接访问后端的数据分片(类似连接原生Redis集群)。相比代理模式,直连模式节约了通过代理处理请求的时间,可以在一定程度上提高Redis服务的响应速度。
  • Q:如果后端的某个数据分片出现异常,对数据读写有什么影响?
    A: 数据分片均采用主备高可用架构,当主节点发生故障后,系统会自动进行主备切换保证服务高可用。在特别极端场景下某个数据分片出现异常后,对数据的影响及优化方案如下。
    场景 影响与优化方案
    图 2. 多Key命令场景
    多Key命令场景
    • 影响:

      客户端通过4个连接发送4个请求,当数据分片2处于异常状态时,仅有请求1(GET Key1可正常读取到数据),其他请求会访问到数据分片2会返回超时。

    • 优化方案:
      • 降低多Key命令(例如MGET)的使用频率,或降低一次请求中包含的Key的数量,避免因单个数据分片异常导致该请求全部返回失败。
      • 降低事务类命令的使用频率或降低事务大小,避免因某个子事务失败导致整个事务失败。
    图 3. 单连接场景
    单连接场景
    • 影响:

      客户端通过1个连接分别发送2个请求,当数据分片2处于异常状态时,请求2(GET Key2)将返回超时,同时由于请求1(GET Key1)和请求2共用同一连接,导致请求1也无法正常返回。

    • 优化方案:
      • 避免或降低对pipeline的使用。
      • 避免使用单连接的客户端(例如Lettuce),推荐使用连接池的客户端,例如Jedis客户端(需设置合理的超时时间和连接池大小)。