Fastapi教程:使用 aioredis 连接池执行Redis 的高效异步操作
在构建高性能的 Web 应用时,缓存系统是一个至关重要的组成部分。Redis 是最常见的缓存系统之一,它提供了高效的存储与读取机制。然而,在与 Redis 进行频繁交互时,创建和销毁连接可能会成为瓶颈。为了优化这一问题,我们可以使用 Redis 连接池。
在本篇博客中,我们将介绍如何在 FastAPI 中使用 aioredis 连接池进行 Redis 的高效异步操作,并讲解如何设置连接池的大小来优化 Redis 操作。
为什么使用 Redis 连接池?
Redis 连接池提供了以下优势:
- 高效的连接复用:通过连接池,多个请求可以复用 Redis 连接,避免了频繁地创建和销毁连接,提升性能。
- 资源管理:连接池可以限制最大连接数,防止过多的连接导致 Redis 服务器过载。
- 简化代码:与每次手动创建 Redis 连接相比,连接池能够自动管理连接生命周期,简化代码。
aioredis 是一个 Python 异步 Redis 客户端,它支持 asyncio,能够在 FastAPI 这样的异步框架中高效工作。
环境准备
首先,确保安装了 fastapi
和 aioredis
:
pip install fastapi
pip install uvicorn
pip install aioredis
创建 Redis 连接池依赖
我们将使用依赖注入来管理 Redis 连接池。通过定义一个依赖函数,FastAPI 可以在每个请求生命周期内为我们提供 Redis 连接池。
1. 创建 Redis 连接池
在创建 Redis 连接池时,我们可以设置连接池的最大连接数和最小连接数。aioredis.create_redis_pool
函数提供了这些参数。通过设置适当的连接池大小,我们可以优化 Redis 的使用,避免连接数过多导致 Redis 服务器负载过高。
minsize
:连接池的最小连接数。即使没有请求,连接池也会保持至少这么多连接。maxsize
:连接池的最大连接数。当连接池中连接数达到最大值时,新的请求将被阻塞,直到有连接空闲。
创建带有连接池大小配置的 Redis 连接池
import aioredis
from fastapi import FastAPI, Depends
from typing import AsyncGenerator# Redis 配置
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
REDIS_POOL_MIN_SIZE = 10 # 最小连接数
REDIS_POOL_MAX_SIZE = 50 # 最大连接数# FastAPI 应用实例
app = FastAPI()# Redis 连接池依赖函数
async def get_redis_pool() -> AsyncGenerator[aioredis.Redis, None]:"""创建并返回 Redis 连接池。通过依赖注入管理 Redis 连接池。"""redis = await aioredis.create_redis_pool((REDIS_HOST, REDIS_PORT),db=REDIS_DB,encoding="utf-8",minsize=REDIS_POOL_MIN_SIZE, # 设置最小连接数maxsize=REDIS_POOL_MAX_SIZE # 设置最大连接数)try:yield redisfinally:redis.close()await redis.wait_closed()
在上述代码中,我们设置了最小连接数 (REDIS_POOL_MIN_SIZE
) 为 10,最大连接数 (REDIS_POOL_MAX_SIZE
) 为 50。根据应用的并发需求,可以调整这些值来平衡性能和资源消耗。
2. 定义路由并使用依赖注入
接下来,我们将依赖注入 Redis 连接池到 FastAPI 的路由处理函数中。这样,Redis 连接池将作为一个参数传入每个需要与 Redis 交互的路由。
示例 1:设置缓存
@app.post("/cache/{key}")
async def cache_data(key: str, value: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""设置缓存数据"""try:await redis.set(key, value)return {"message": "Data cached successfully", "key": key, "value": value}except Exception as e:return {"error": str(e)}
示例 2:获取缓存
@app.get("/cache/{key}")
async def get_cached_data(key: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""获取缓存数据"""try:value = await redis.get(key)if value is None:return {"message": "Key not found"}return {"key": key, "value": value}except Exception as e:return {"error": str(e)}
示例 3:删除缓存
@app.delete("/cache/{key}")
async def delete_cached_data(key: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""删除缓存数据"""try:result = await redis.delete(key)if result == 0:return {"message": "Key not found"}return {"message": f"Data with key {key} deleted successfully"}except Exception as e:return {"error": str(e)}
在这些路由中,redis: aioredis.Redis = Depends(get_redis_pool)
表示 FastAPI 会自动调用 get_redis_pool
来提供一个 Redis 连接池实例。通过这种方式,我们可以避免手动管理 Redis 连接池,并保持代码的简洁和模块化。
3. 启动和关闭事件
为了确保 Redis 连接池在 FastAPI 应用启动时创建并在关闭时清理,我们需要在 @app.on_event("startup")
和 @app.on_event("shutdown")
事件中进行相应的管理。这个管理已经在 get_redis_pool
函数中实现,因为 Redis 连接池会在 yield
语句之后关闭。
因此,我们不需要在 FastAPI 中显式管理 Redis 连接池的启动和关闭,FastAPI 会自动处理。
完整代码示例
以下是完整的代码示例,展示了如何在 FastAPI 中使用 Redis 连接池和依赖注入,并设置连接池大小:
import aioredis
from fastapi import FastAPI, HTTPException, Depends
from typing import AsyncGenerator# Redis 配置
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
REDIS_POOL_MIN_SIZE = 10 # 最小连接数
REDIS_POOL_MAX_SIZE = 50 # 最大连接数# FastAPI 应用实例
app = FastAPI()# Redis 连接池依赖函数
async def get_redis_pool() -> AsyncGenerator[aioredis.Redis, None]:"""创建并返回 Redis 连接池。通过依赖注入管理 Redis 连接池。"""redis = await aioredis.create_redis_pool((REDIS_HOST, REDIS_PORT),db=REDIS_DB,encoding="utf-8",minsize=REDIS_POOL_MIN_SIZE, # 设置最小连接数maxsize=REDIS_POOL_MAX_SIZE # 设置最大连接数)try:yield redisfinally:redis.close()await redis.wait_closed()@app.post("/cache/{key}")
async def cache_data(key: str, value: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""设置缓存数据"""try:await redis.set(key, value)return {"message": "Data cached successfully", "key": key, "value": value}except Exception as e:return {"error": str(e)}@app.get("/cache/{key}")
async def get_cached_data(key: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""获取缓存数据"""try:value = await redis.get(key)if value is None:return {"message": "Key not found"}return {"key": key, "value": value}except Exception as e:return {"error": str(e)}@app.delete("/cache/{key}")
async def delete_cached_data(key: str, redis: aioredis.Redis = Depends(get_redis_pool)):"""删除缓存数据"""try:result = await redis.delete(key)if result == 0:return {"message": "Key not found"}return {"message": f"Data with key {key} deleted successfully"}except Exception as e:return {"error": str(e)}
总结
在本篇博客中,我们介绍了如何在 FastAPI 中使用 aioredis
连接池来实现异步 Redis 操作,并且讲解了如何配置连接池的最小连接数和最大连接数。通过设置合适的连接池大小,可以有效管理 Redis 连接,提升性能并避免 Redis 服务器过载。
使用 Redis 连接池的主要优势是提升性能、简化代码并合理管理资源。在构建高并发的 Web 应用时,连接池是优化 Redis 使用的重要工具。
相关文章:
Fastapi教程:使用 aioredis 连接池执行Redis 的高效异步操作
在构建高性能的 Web 应用时,缓存系统是一个至关重要的组成部分。Redis 是最常见的缓存系统之一,它提供了高效的存储与读取机制。然而,在与 Redis 进行频繁交互时,创建和销毁连接可能会成为瓶颈。为了优化这一问题,我们…...

配置mysqld(读取选项内容,基本配置),数据目录(配置的必要性,目录下的内容,具体文件介绍,修改配置)
目录 配置mysqld 读取选项内容 介绍 启动脚本 基本配置 内容 端口号 数据目录的路径 配置的必要性 配置路径 mysql数据目录 具体文件 修改配置时 权限问题 配置mysqld 读取选项内容 介绍 会从[mysqld] / [server] 节点中读取选项内容 优先读取[server] 虽然服务…...

docker 容器相互访问
目前采用 network 方式 1. 创建自定义网络 docker network create network-group 如下 2. 相互访问的容器更改(目前演示redis 以及netcore api 访问redis ) //redis 原有容器删除 跟之前区别就是加入 --network network-group docker run \ -p 6379:…...

算法1(蓝桥杯18)-删除链表的倒数第 N 个节点
问题: 给你一个链表,删除链表的倒数第 n 个节点,并且返回链表的头节点。 输入:head 1 -> 2 -> 3 -> 4 -> 5 -> null, n 2 输出:1 -> 2 -> 3 -> 5 -> null输入:head 1 ->…...
【PyTorch】动态调整学习率 torch.optim.lr_scheduler.StepLR 调度器
文章目录 1. torch.optim.lr_scheduler.StepLR 官方文档详解2. 使用示例2.1 官方提供使用示例2.2 自己写代码测试方法2.2.1 get_last_lr() 方法2.2.2 state_dict() 方法2.2.3 load_state_dict() 保存和加载调度器 3. 思考3.1 为什么需要state_dict()3.2 get_lr() 与 get_last_l…...
AIGC drug design 人工智能生成式药物设计:基于 GPT 的 SMILES 生成与应用
人工智能生成式药物设计:基于 GPT 的 SMILES 生成与应用 1. 人工智能生成模型:解密 GPT 的工作原理 目录 引言 1.1 背景介绍 1.2 人工智能生成模型的兴起 1.3 GPT 系列模型的地位与影响 GPT 模型概述 2.1 什么是 GPT 2.2 GPT 的发展历程 2.3 GPT 与其…...
Python面试常见问题及答案4
一、内存管理相关 问题:Python中的垃圾回收机制是如何工作的? 答案:Python主要使用引用计数来进行垃圾回收,当对象的引用计数为0时,该对象就会被垃圾回收器回收。此外,Python还有一个循环垃圾收集器来处理循…...

开启第二阶段---蓝桥杯
一、12.10--数据类型的范围及转化 今天是刚开始,一天一道题 对于这道题我想要记录的是Java中的整数默认是 int 类型,如果数值超出了 int 的范围,就会发生溢出错误。为了避免这个问题,可以将数字表示为 long 类型,方法…...

npm内存溢出
项目过大运行项目内存溢出 报错代码 运行内存溢出 increase-memory-limit ‘“node --max-old-space-size8192”’ 不是内部或外部命令,也不是可运行的程序 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of m…...

回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测
回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 CNN-BiGRU,即卷积神经网络(CNN)与双…...
Android系统卡启动问题排查
Android系统启动正常来说会涉及到如下几个过程: 引导加载程序(Bootloader)Linux内核(Kernel),负责硬件抽象、内存管理、进程管理、网络堆栈等init进程 init进程读取init.rc配置文件,用于启动各…...

STP(生成树协议)
STP的基本概念 概述 STP是一个用于局域网中消除环路的协议。运行该协议的设备通过彼此交互信息而发现网络中的环路,并对某些接口进行阻塞以消除环路。STP在网络中运行后会持续监控网络的状态,当网络出现拓扑变更时,STP能够感知并且进行自动…...
【前端面试】随机、结构赋值、博弈题
解构赋值(Destructuring Assignment)是 JavaScript ES6 引入的一项非常有用的特性,它允许我们快速地从数组或对象中提取值,并将它们赋给变量。这种方式使得代码更加简洁、易读,并且能够减少重复的访问和赋值操作。 1.…...
Volta——开箱即用的Node.js 版本管理工具
Volta volta 是一个较新的 Node.js 版本管理器,旨在简化 Node.js 和其他工具的安装和管理,在 2019 年出世,仍在积极开发中。Volta 采用了与 nvm 不同的方法:它不是管理 Node.js 的多个版本,而是管理项目及其依赖项。当…...

ubuntu 磁盘空间满,找不到占用文件的目录
解决方法: 检查磁盘空间: 执行 df -h 查看各分区磁盘使用情况。 查找大文件或目录: 执行 du -sh /* 2>/dev/null 查找根目录下的大文件或目录,再逐一进入子目录使用相同命令查找。 清理缓存和临时文件: 清理 /t…...
1. 机器学习基本知识(5)——练习题(参考答案)
20.🔗本章代码笔记📓链接(需要🪜):(01_the_machine_learning_landscape.ipynb - Colab (google.com)) 如果你不想通过上面的官方网址下载本章的笔记,还可以在本篇博文的…...
spark-sql 备忘录
wordcount sc.textFile("../data/data.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(__).collect 读取json 文件 并通过sql 执行 join 查询 public static void main(String[] args) {SparkSession session SparkSession.builder().master(&qu…...
基于softmax回归的多分类
基于softmax回归的多分类任务是机器学习领域中的一种常见应用。softmax回归,又称多项逻辑回归或多类逻辑回归,是逻辑回归在多分类问题上的推广。以下是对基于softmax回归的多分类任务的详细解释: 一、softmax回归的原理 softmax回归的核心思想是通过softmax函数将输入数据…...

bs4基本运用
1. bs4基本使用 1.1. 简介 bs4的全称为 BeautifulSoup。和lxml一样,是一个html的解析器,主要功能也是解析数据和提取数据 。 本模块作为了解模块,实际开发中很少用这个模块去解析数据,大家可能会想为什么这个模块会逐渐被淘汰&…...
MySQL 时区参数 time_zone 详解
文章目录 前言1. 时区参数影响2. 如何设置3. 字段类型选择 前言 MySQL 时区参数 time_zone 有什么用?修改它有什么影响?如何设置该参数,本篇文章会详细介绍。 1. 时区参数影响 time_zone 参数影响着 MySQL 系统函数还有字段的 DEFAULT CUR…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...