当前位置: 首页 > web >正文

【golang长途旅行第37站】Redis连接池

什么是连接池

在介绍 Redis 连接池之前,首先要理解连接池的概念。连接池是一种用于管理数据库、缓存等网络连接的技术。其核心思想是:​在应用程序启动时预先创建并维护一组可用的连接对象,当需要与数据源交互时,从池中获取一个空闲连接,使用完毕后将其归还给池,而不是直接关闭

这样子的效率就远比一有请求就生成一个连接对象,用完就关闭的效率高的多

不使用连接池的简单连接方式存在几个严重问题:

  1. ​性能开销大​:每次操作 Redis 都经历 TCP 三次握手、TLS 握手(如果用了 SSL)、认证、执行命令、断开连接的过程。其中建立和断开 TCP 连接是非常耗时的操作,会带来巨大的性能瓶颈。

  2. 资源消耗高​:每个 TCP 连接都会占用系统的端口、内存、文件描述符等资源。频繁地创建和销毁连接会快速消耗这些有限的资源,可能导致系统不稳定。

  3. 并发能力差​:在高并发场景下,如果每个请求都创建一个新连接,Redis 服务器本身会因为处理大量连接请求而耗尽资源,无法处理正常的命令请求。

连接池就是为了解决这些问题而生的。它通过复用已建立的连接,避免了频繁的网络握手和资源分配,显著提升了应用程序的性能和稳定性。

Redis连接池

基本介绍

连接池的管理通常包含以下几个关键环节:
  1. 初始化​:应用程序启动时,连接池会根据配置(如最大连接数、最小空闲连接数)创建一定数量的连接,并将其置于“空闲”状态。

  2. ​获取连接​:
    当应用程序需要执行 Redis 命令时,它会向连接池请求一个连接。
    连接池会首先检查是否有空闲的、可用的连接。
    如果有,则直接分配给应用程序。
    如果没有空闲连接,但当前总连接数未达到配置的最大值,连接池会新建一个连接。
    如果已经达到最大连接数,请求可能会被阻塞一段时间(等待其他连接被释放),或者直接抛出异常(取决于配置)。

  3. ​使用连接​:应用程序使用获取到的连接与 Redis 服务器进行通信,执行命令。

  4. 归还连接​:命令执行完毕后,应用程序并不是真正关闭连接,而是将其归还给连接池。连接池会将该连接状态重置为空闲,并等待下一次被分配。

  5. 健康检查​:优秀的连接池还会定期对池中的连接进行健康检查(例如发送一个 PING命令),确保连接没有被服务器意外关闭(如 due to timeout)。如果发现无效连接,则会销毁它并创建新的健康连接来补充。

关键配置参数

虽然不同客户端的参数名略有差异,但核心含义相同:

  • ​最大连接数 (maxTotal, PoolSize)​​:连接池所能维持的最大连接数。设置过高会消耗客户端和服务器资源,设置过低可能成为瓶颈。需要根据实际并发量和服务器性能调整。

  • ​最大空闲连接数 (maxIdle)​​:连接池中允许存在的最大空闲连接数。保持一定的空闲连接可以快速响应请求,避免现建连接的延迟。

  • ​最小空闲连接数 (minIdle)​​:连接池中保证维持的最小空闲连接数。它有助于保持池的健康,防止突发请求时瞬间建连的压力。

  • ​最大等待时间 (maxWait)​​:当连接池耗尽时,新的请求等待可用连接的最大时间。超过这个时间会抛出异常。

  • ​连接最大存活时间 (maxConnAge)​​:一个连接的最大生命周期,超过后会被关闭重建。有助于连接 refresh。

  • ​空闲连接最大存活时间 (idleTimeout)​​:一个空闲连接在多长时间没有被使用后会被自动释放。有助于回收不必要的资源。

使用案例

package main

import (
“context”
“fmt”
“github.com/go-redis/redis/v8”
“time”
)

func main() {
// 初始化 Redis 客户端(自带连接池)
rdb := redis.NewClient(&redis.Options{
Addr: “localhost:6379”, // Redis 服务器地址
Password: “”, // 密码(没有密码则留空)
DB: 0, // 数据库编号(默认 0)

	// ========== 连接池相关配置 ==========PoolSize:     10,               // 最大连接数(默认是 CPU 数 * 10)MinIdleConns: 2,                // 最小空闲连接数(默认 0)MaxConnAge:   0,                // 连接的最大存活时间(0 表示不限制)PoolTimeout:  30 * time.Second, // 获取连接的超时时间IdleTimeout:  5 * time.Minute,  // 空闲连接的最大存活时间
})// 测试连接
ctx := context.Background()
pong, err := rdb.Ping(ctx).Result()
if err != nil {panic(err)
}
fmt.Println("Redis 连接成功:", pong)// 使用客户端执行命令
err = rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {panic(err)
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {panic(err)
}
fmt.Println("key:", val)// 关闭客户端(会同时关闭连接池)
defer rdb.Close()

}

http://www.xdnf.cn/news/20006.html

相关文章:

  • OCR 发票识别与验真接口:助力电子化发票新时代
  • 融云:当我们谈论 AI 重构业务时,我们到底在谈论什么
  • 【Android】SharedPreferences轻量级持久化存储
  • 【题解】洛谷P1776 宝物筛选 [单调队列优化多重背包]
  • C++----模板特化以及模板声明与定义分离问题
  • AT32网线拔插下,modbus tcp断线重连
  • Linux awk命令完全指南:从原理到实战,搞定文本处理难题
  • 【AI】人工智能 传统和现代 架构和算法的演变历史
  • windows安装谷歌浏览器地址
  • TypeScript `infer` 关键字详解(从概念到实战)
  • AGV 搬运小车路径规划:从地图构建到路径决策的技术全解析
  • 打通 Flutter 与原生状态管理:Android ViewModel 的运用
  • SpringBoot+PDF.js实现按需分片加载(包含可运行样例源码)
  • C++小游戏
  • 腾讯开源HunyuanWorld-Voyager突破性原生3D重建与视频扩散框架
  • 计算机大数据毕业设计选题:基于Spark+hadoop的全球香水市场趋势分析系统
  • 优思学院|5个为什么(5 Whys)分析法一文讲清楚
  • AI编写自动点击器 - 毫秒级精准鼠标连点器
  • kafka:【1】概念关系梳理
  • kvm 虚拟机如何安装 qemu-guest-agent
  • kali_linux
  • 【Linux】线程封装
  • 【FastDDS】Layer DDS之Domain ( 04-DomainParticipantFactory)
  • 采用基于模型的方法实现车辆SOA威胁分析自动化
  • wpf 自定义密码文本框,并且可以双向绑定
  • 吱吱企业通讯软件以安全为核心,构建高效沟通与协作一体化平台
  • 什么是Agent?小白如何学习使用Agent?一篇文档带你详细了解神秘的Agent
  • 容器tomcat镜像制作
  • 算法题2:动态规划
  • Python委托迭代完全指南:从基础到高级设计模式实践