Fastapi教程:使用 aioredis 连接池执行Redis 的高效异步操作

在构建高性能的 Web 应用时,缓存系统是一个至关重要的组成部分。Redis 是最常见的缓存系统之一,它提供了高效的存储与读取机制。然而,在与 Redis 进行频繁交互时,创建和销毁连接可能会成为瓶颈。为了优化这一问题,我们可以使用 Redis 连接池。

在本篇博客中,我们将介绍如何在 FastAPI 中使用 aioredis 连接池进行 Redis 的高效异步操作,并讲解如何设置连接池的大小来优化 Redis 操作。

为什么使用 Redis 连接池?

Redis 连接池提供了以下优势:

  • 高效的连接复用:通过连接池,多个请求可以复用 Redis 连接,避免了频繁地创建和销毁连接,提升性能。
  • 资源管理:连接池可以限制最大连接数,防止过多的连接导致 Redis 服务器过载。
  • 简化代码:与每次手动创建 Redis 连接相比,连接池能够自动管理连接生命周期,简化代码。

aioredis 是一个 Python 异步 Redis 客户端,它支持 asyncio,能够在 FastAPI 这样的异步框架中高效工作。

环境准备

首先,确保安装了 fastapiaioredis

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 使用的重要工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

激活函数-swiGLU

swiGLU(Switch Gated Linear Unit)简介 swiGLU 是一种改进的激活函数模块,主要用于深度学习中的 Transformer 模型和其他神经网络架构。它在 GLU(Gated Linear Unit) 的基础上进行了修改,以提升模型的表现…

Unix 传奇 | 谁写了 Linux | Unix birthmark

注:本文为 “左耳听风”陈皓的 unix 相关文章合辑。 皓侠已走远,文章有点“年头”,但值得一阅。 文中部分超链已沉寂。 Unix 传奇 (上篇) 2010 年 04 月 09 日 陈皓 了解过去,我们才能知其然,更知所以然。总结过去…

记一个framebuffer显示混乱的低级错误

记一个framebuffer显示混乱的低级错误 由于framebuffer的基础知识不扎实,这个任务上我多卡了两天,差点把我搞死,于此记录为后鉴。 打算用awtk做一个多进程项目,计划把framebuffer的内容通过websocket输出到浏览器上去显示画面, …

常用的前端框架介绍

在前端开发中,有许多流行的框架能够帮助开发者更高效地构建用户界面和交互 1. React: • React是一个由Facebook开发的JavaScript库,用于构建用户界面。 • 它使用组件化的思想,将UI拆分成可复用的组件,每个组件都有自…

Kaggler日志-Day4

进度24/12/14 昨日复盘: Pandas课程完成 Intermediate Mechine Learning2/7 今日记录: Intermediate Mechine Learning之类型变量 读两篇讲解如何提问的文章,在提问区里发起一次提问 实战:自己从头到尾首先Housing Prices Compe…

【21天学习AI底层概念】day5 机器学习的三大类型不能解决哪些问题?

机器学习的三大类型——监督学习、无监督学习和强化学习,虽然可以应用于许多问题,但并非所有问题都能通过这些方法有效解决。每种类型的机器学习都有其局限性,具体如下: 1. 监督学习 (Supervised Learning) 监督学习是通过训练数…

【常考前端面试题总结】---2025

React fiber架构 1.为什么会出现 React fiber 架构? React 15 Stack Reconciler 是通过递归更新子组件 。由于递归执行,所以更新一旦开始,中途就无法中断。当层级很深时,递归更新时间超过了 16ms,用户交互就会卡顿。对于特别庞…

二三(Node2)、Node.js 模块化、package.json、npm 软件包管理器、nodemon、Express、同源、跨域、CORS

1. Node.js 模块化 1.1 CommonJS 标准 utils.js /*** 目标:基于 CommonJS 标准语法,封装属性和方法并导出*/ const baseURL "http://hmajax.itheima.net"; const getArraySum (arr) > arr.reduce((sum, item) > (sum item), 0);mo…

Java爬虫设计:淘宝商品详情接口数据获取

1. 概述 淘宝商品详情接口(如Taobao.item_get)允许开发者通过编程方式,以JSON格式实时获取淘宝商品的详细信息,包括商品标题、价格、销量等。本文档将介绍如何设计一个Java爬虫来获取这些数据。 2. 准备工作 在开始之前&#x…

LeetCode-hot100-73

https://leetcode.cn/problems/largest-rectangle-in-histogram/description/?envTypestudy-plan-v2&envIdtop-100-liked 84. 柱状图中最大的矩形 已解答 困难 相关标签 相关企业 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#x…

深度学习中损失函数(loss function)介绍

深度学习中损失函数(loss function)介绍 ​ 在深度学习的宏伟城堡中,损失函数扮演着国王的角色,它决定了模型训练的方向和目标。损失函数,也被称为代价函数,是衡量模型预测与实际结果之间差异的函数。在深度学习的训练过程中&…

【docker】springboot 服务提交至docker

准备docker (不是docker hub或者harbor,就是可以运行docker run的服务),首先确保docker已经安装。 本文以linux下举例说明: systemctl stats docker ● docker.service - Docker Application Container EngineLoaded…

【新版】阿里云ACP云计算题库及答案解析

阿里云ACO云计算考试提醒都是选择题,70道单选题30道单选题,聪明的小伙伴都知道刷题备考加深记忆,给大家分享一波阿里云ACP云计算题库及答案,希望对大家顺利拿到阿里云ACP云计算高级工程师证书有所帮助! 1、设计云上架…

通过ajax的jsonp方式实现跨域访问,并处理响应

一、场景描述 现有一个项目A,需要请求项目B的某个接口,并根据B接口响应结果A处理后续逻辑。 二、具体实现 1、前端 前端项目A发送请求,这里通过jsonp的方式实现跨域访问。 $.ajax({ url:http://10.10.2.256:8280/ssoCheck, //请求的u…

Unity 沿圆周创建Sphere

思路 取圆上任意一点连接圆心即为半径,以此半径为斜边作直角三角形。当已知圆心位置与半径长度时,即可得该点与圆心在直角三角形两直角边方向上的位置偏移,从而得出该点的位置。 实现 核心代码 offsetX radius * Mathf.Cos(angle * Mathf…

【CUDA】CUBLAS

【CUDA】CUBLAS 在深入了解之前,提前运行预热(warmup)和基准测试(benchmark runs) 是获得准确执行时间的关键。如果不进行预热运行,cuBLAS 的首次运行会有较大的开销(大约 45 毫秒)…

9. 高效利用Excel设置归档Tag

高效利用Excel设置归档Tag 1. Excle批量新建/修改归档Tag2. 趋势记录模型批量导入归档Tag(Method1)2. 趋势记录模型批量导入归档Tag(Method2)3. 趋势记录控件1. Excle批量新建/修改归档Tag Fcatory Talk常常需要归档模拟量,对于比较大的项目工程会有成千上万个重要数据需…

网页端web内容批注插件:

感觉平时每天基本上90%左右的时间都在浏览器端度过,按理说很多资料都应该在web端输入并且输出,但是却有很多时间浪费到了各种桌面app中,比如说什么notion、语雀以及各种笔记软件中,以及导入到ipad的gn中,这些其实都是浪…

Jackson @JsonIgnore 注解

1. 概述 Jackson 是一个广泛使用的Java库,它允许轻松地将Java对象序列化为JSON以及从JSON反序列化回Java对象。Jackson库提供的其中一个注解是JsonIgnore。这个注解用于在序列化和反序列化过程中忽略特定的属性。这在转换JSON与Java对象之间时隐藏或省略敏感或不必…

数据结构——栈的模拟实现

大家好,今天我要介绍一下数据结构中的一个经典结构——栈。 一:栈的介绍 与顺序表和单链表不同的是: 顺序表和单链表都可以在头部和尾部插入和删除数据,但是栈的结构就锁死了(栈的底部是堵死的)栈只能从…