如何配置 go-redis 连接池

本文涉及的产品
云数据库 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
目录
相关文章
|
19天前
|
前端开发 JavaScript Linux
Sublime Text 3配置Go语言开发环境
【4月更文挑战第13天】本篇文章 Huazie 向大家介绍使用 Sublime Text 3搭建Go语言开发环境,并演示编译运行 Go语言代码
49 8
Sublime Text 3配置Go语言开发环境
|
1月前
|
Linux Go iOS开发
掌握Go语言:配置环境变量、深入理解GOPATH和GOROOT(1)
掌握Go语言:配置环境变量、深入理解GOPATH和GOROOT(1)
|
2月前
|
NoSQL Java Redis
Springboot从2.x升级到3.x以后redis默认配置调整
Springboot从2.x升级到3.x以后redis默认配置调整
52 0
|
3月前
|
NoSQL Redis
若依管理系统去掉Redis相关配置
若依管理系统去掉Redis相关配置
|
3月前
|
NoSQL Redis 数据安全/隐私保护
Docker中Redis的安装与配置
本文主要讲解如何在Docker环境中搭建Redis环境,并进行相关配置
258 5
Docker中Redis的安装与配置
|
2月前
|
NoSQL Linux Redis
Linux系统中安装redis+redis后台启动+常见相关配置
Linux系统中安装redis+redis后台启动+常见相关配置
|
3月前
|
NoSQL Redis Docker
在docker中安装redis,并且阿里云服务器配置
在docker中安装redis,并且阿里云服务器配置
192 1
|
3月前
|
NoSQL Java 数据库连接
springboot整合Redis中连接池jedis与lettuce的对比和实现
springboot整合Redis中连接池jedis与lettuce的对比和实现
369 0
|
10天前
|
安全 Go 网络安全
【Go语言专栏】Go语言中的HTTPS与TLS配置
【4月更文挑战第30天】本文介绍了在Go语言中配置HTTPS服务器和处理TLS证书的方法。首先,TLS证书由证书颁发机构(CA)颁发,用于验证服务器身份和加密通信。接着,展示了如何使用`crypto/tls`包加载自签名证书启动HTTPS服务器。在生产环境中,通常使用CA签名的证书,这需要获取证书链和私钥。为了自动续期证书,可以利用Go的`acme/autocert`包与ACME服务交互。掌握这些技能对于确保Web服务的安全至关重要。
|
17天前
|
Go 开发工具 开发者
Intellij IDEA 配置 Go 语言开发环境
【4月更文挑战第14天】本篇文章 Huazie 向大家介绍使用 Intellij IDEA 搭建 Go 语言开发环境,并演示编译运行Go语言代码
28 1
Intellij IDEA 配置 Go 语言开发环境

热门文章

最新文章