如何配置 go-redis 连接池

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 如何配置 go-redis 连接池

连接池是各种服务绕不过去的模块,它在调用链路的上下游之间建立了一个缓冲区。客户端可以从连接池中获取连接来执行数据库操作,完成后将连接返回给连接池,而不是每次都建立新的连接。

连接池的作用显而易见:

  1. 提高性能:连接池可以减少连接的创建和销毁过程,避免了频繁地与服务端建立物理连接的开销,从而提高了客户端的性能和响应速度。
  2. 节省资源:服务端连接是一种有限的资源,每个连接都占用着内存等系统资源。连接池可以限制连接的数量,避免过多的连接导致资源的浪费,提高了系统的资源利用率。
  3. 连接的复用:连接池可以重复利用已经建立的连接,避免了频繁地创建和销毁连接的开销,提高了服务端的并发性能。

但是,连接池配置众多,根据业务特征调整好连接池并不容易。

go-redis 连接池的配置参数包括:

- DialTimeout  # Dial timeout for establishing new connections.
- ReadTimeout  # Timeout for socket reads. If reached, commands will fail with a timeout instead of blocking.
- WriteTimeout  # Timeout for socket writes. If reached, commands will fail with a timeout instead of blocking.
- PoolFIFO  # Type of connection pool. true for FIFO pool, false for LIFO pool.
- PoolSize  # Maximum number of socket connections.
- PoolTimeout  # Amount of time client waits for connection if all connections are busy before returning an error.
- MinIdleConns  # Minimum number of idle connections which is useful when establishing new connection is slow.
- MaxIdleConns  # Maximum number of idle connections.
- ConnMaxIdleTime  # ConnMaxIdleTime is the maximum amount of time a connection may be idle.
- ConnMaxLifetime  # Expired connections may be closed lazily before reuse.

误区一: DialTimeout 设置过小

DialTimeout(拨号超时)用于指定建立网络连接的超时时间。当客户端尝试连接到服务端时,如果在 DialTimeout 指定的时间内无法建立连接,连接操作将超时失败。它通常包括域名解析、建立 TCP 连接等步骤的超时时间。

DialTimeout 设置过小,可能会导致服务由于无法成功建立连接,启动失败。尤其是使用 DNS 作为服务发现以及跨 IDC 调用的场景下。

go-redis 默认是 5 s。3~5 s 是比较合适的,可以直接使用默认值。

误区二: PoolSize 设置不合理

如果连接池的大小设置过小,无法满足应用程序的并发需求,可能会导致连接不足的问题,影响应用程序的性能和响应速度。

如果连接池的大小设置过大,最大连接总数超过服务端最大连接数。在业务请求峰值时,会出现新建连接失败导致的请求失败。

那怎么评估连接池大小呢?

假如请求服务端的平均延迟是 duration ms,客户端进程的峰值 QPS 是 qps。单个连接 1 秒(1000)能否处理的请求总数是 1000 / duration;同时,预留一定的 Buffer 连接数 buffer 给请求变慢或请求量因为需求变化增加等场景。那么合适的连接池大小为:

PoolSize = qps / (1000 / duration) + buffer

误区三:ConnMaxLifetime 设置不当

如果连接生存时间设置得过短,则可能频繁地创建和销毁连接,影响性能。此问题比较容易理解。

如果连接生存时间设置得过长,可能会导致连接过期或失效。举个极端的例子,不设置连接生存时间。

考虑以下场景

场景一:

服务端新版本发布。假如该服务有两个实例 A、B。考虑发布过程,首先,A 升级重启,连接全部请求到 B。然后,B 升级重启,连接全部回到 A。因为没有设置连接生存时间,调用 A 不出现错误的前提下,连接永远不均匀。

场景二:

客户端到服务端短暂网络异常。假如该服务有两个实例 A、B,新建连接的机制是 Round Robin。考虑到 B 的网络异常,导致请求全部断开。然后客户端开始新建连接,到 B 的连接全部失败,最终连接池的中的连接全部连接到 A。因为没有设置连接生存时间,调用 A 不出现错误的前提下,连接永远不均匀。

go-redis 该设置默认关闭。为避免类似问题,连接生存时间一般建议配置为小时级,既避免频繁地创建和销毁连接,影响性能;同时也避免连接不均匀。

误区四:PoolFIFO 设置不当

在连接池中连接到服务端每个实例的连接数大致均匀的前提下。客户端从连接池获取连接发起请求,本质来说是一个负载均衡的问题。常见的负载均衡算法包括:

  • Round-Robin(FIFO)
  • Random
  • Weighted Round Robin
  • Weighted Random
  • Hashing

很显然,go-redis 默认使用的 LIFO 并不在列。

LIFO 并不适合作为负载均衡算法的选择。因为 LIFO 会优先处理最近使用过的连接,这可能会导致某些服务实例负载过重,而其他的服务实例却得不到充分的利用。这种不均衡的分配会影响系统的可用性、性能和容错能力。

因此,在使用 go-redis 时,PoolFIFO 应永远设置为 true。

附:连接池图例

连接使用:获取/释放流程图

连接管理:连接状态机

本文作者 : cyningsun

本文地址https://www.cyningsun.com/06-05-2023/go-redis-connection-pool.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!

# 数据库

  1. 深入理解 Redis cluster GOSSIP 协议
  2. 如何使用 Redis 存储对象
  3. Redis cluster 细节与技术选型
  4. etcd 实现与选型分析
  5. MySQL 设计与查询规范

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
缓存 弹性计算 NoSQL
【Azure Redis 缓存 Azure Cache For Redis】Redis连接池
【Azure Redis 缓存 Azure Cache For Redis】Redis连接池
|
19天前
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
1月前
|
存储 NoSQL Redis
Redis 配置
10月更文挑战第14天
24 1
|
1月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
57 1
|
2月前
|
关系型数据库 MySQL Go
go抽取mysql配置到yaml配置文件
go抽取mysql配置到yaml配置文件
|
1月前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
131 0
|
1月前
|
Unix Linux Go
Linux 使用Yum安装Go和配置环境
Linux 使用Yum安装Go和配置环境
|
1月前
|
NoSQL Ubuntu Linux
redis的基本安装配置启动使用
redis的基本安装配置启动使用
34 0
|
1月前
|
缓存 NoSQL 数据处理
原生php实现redis缓存配置和使用方法
通过上述步骤,你可以在PHP项目中配置并使用Redis作为高性能的缓存解决方案。合理利用Redis的各种数据结构和特性,可以有效提升应用的响应速度和数据处理效率。记得在实际应用中根据具体需求选择合适的缓存策略,如设置合理的过期时间,以避免内存过度消耗。
51 0
|
3月前
|
Unix 编译器 Go