如何配置 go-redis 连接池

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 如何配置 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 设计与查询规范

目录
相关文章
|
9月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
626 4
|
9月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
877 25
|
12月前
|
NoSQL 安全 Linux
设置Redis在CentOS7上的自启动配置
这些步骤总结了在CentOS 7系统上设置Redis服务自启动的过程。这些命令提供了一个直接且明了的方式,确保Redis作为关键组件在系统启动时能自动运行,保障了依赖于Redis服务的应用的稳定性和可用性。
832 9
|
JSON 安全 Go
Go语言项目工程化 —— 日志、配置、错误处理规范
本章详解Go语言项目工程化核心规范,涵盖日志、配置与错误处理三大关键领域。在日志方面,强调其在问题排查、性能优化和安全审计中的作用,推荐使用高性能结构化日志库zap,并介绍日志级别与结构化输出的最佳实践。配置管理部分讨论了配置分离的必要性,对比多种配置格式如JSON、YAML及环境变量,并提供viper库实现多环境配置的示例。错误处理部分阐述Go语言显式返回error的设计哲学,讲解标准处理方式、自定义错误类型、错误封装与堆栈追踪技巧,并提出按调用层级进行错误处理的建议。最后,总结各模块的工程化最佳实践,助力构建可维护、可观测且健壮的Go应用。
|
Shell Go 开发工具
【环境】Rocky8使用gvm配置Go多版本管理的微服务开发环境(go-zero)
通过本文的介绍,我们详细讲解了如何在Rocky8上使用gvm来管理多个Go版本,并配置go-zero框架的开发环境。通过gvm的灵活管理,开发者可以轻松切换不同的Go版本,以适应不同项目的需求。同时,go-zero框架的使用进一步提升了微服务开发的效率和质量。希望本文能帮助开发者构建高效的Go语言开发环境,提高项目开发的灵活性和稳定性。
520 63
|
NoSQL Ubuntu 网络安全
在 Ubuntu 20.04 上安装和配置 Redis
在 Ubuntu 20.04 上安装和配置 Redis 的步骤如下:首先更新系统包,然后通过 `apt` 安装 Redis。安装后,启用并启动 Redis 服务,检查其运行状态。可选配置包括修改绑定 IP、端口等,并确保防火墙设置允许外部访问。最后,使用 `redis-cli` 测试 Redis 功能,如设置和获取键值对。
693 1
|
存储 监控 NoSQL
NoSQL与Redis配置与优化
通过合理配置和优化Redis,可以显著提高其性能和可靠性。选择合适的数据结构、优化内存使用、合理设置持久化策略、使用Pipeline批量执行命令、以及采用分布式集群方案,都是提升Redis性能的重要手段。同时,定期监控和维护Redis实例,及时调整配置,能够确保系统的稳定运行。希望本文对您在Redis的配置与优化方面有所帮助。
268 23
|
存储 监控 NoSQL
NoSQL与Redis配置与优化
通过合理配置和优化Redis,可以显著提高其性能和可靠性。选择合适的数据结构、优化内存使用、合理设置持久化策略、使用Pipeline批量执行命令、以及采用分布式集群方案,都是提升Redis性能的重要手段。
303 7
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
存储 NoSQL Redis
Redis 配置
10月更文挑战第14天
365 1