go-redis 从v8版本开始支持通过PoolFIFO参数设置连接池策略。本文将介绍FILO和FIFO两种管理策略的优缺点,以及在go-redis中如何实现。

链接池与负载不均匀

某公司Redis集群架构

  • 后端存储使用原生redis cluster
  • 前面有一层proxy做请求分发

不均衡现象

  • 不同proxy节点QPS不均衡
  • 同一台节点的不同进程的QPS也不均匀现象。

问题定位

定位原因如下:

  • 使用go-redis v6,默认FILO策略
  • FILO容易导致连接使用不均衡
  • 固定连接仅在创建时分配到进程
  • 链接使用不均衡导致请求分配不均,进而导致进程负载不均衡

解决方案

采用FIFO策略的连接池,解决连接使用不均衡问题。

不同链接池策略

FILO

FILO全称为First In Last Out,也就是后进先出的策略, 也即最新放入链接池 的链接 会被优先返回使用。
优点:

  • 利用连接缓存,提升性能
  • 快速淘汰老连接
    缺点:
  • 链接使用不够公平
  • 难以保持连接属性。

FIFO

FIFO 全称为 First In First Out,即先进先出的策略,也即是最先进入池中的链接会被先使用,新创建(放入)的链接最后被使用。

优点:

  • 更加公平
  • 有利于保持连接性质
    缺点:
  • - 新连接无法利用缓存
  • 可能造成资源浪费

go-redis 连接池策略

使用不同策略

go-redis v8以上通过PoolFIFO参数配置策略:

  • true: FIFO策略
  • false: FILO策略

连接池策略

  • Put方法把用完的链接放进链接池,实际上是保留在idleConns切片中
  • Get方法获取可用链接时,调用popIdle()优先尝试从缓存的链接获取
  • popIdle()根据PoolFIFO参数,决定从切片头部或者尾部取,实现FIFO或者FILO