Redis-py连接池重连耗时处理

本文探讨了在tornado+mongodb+redis环境下,redis-py连接池中连接失效导致重连耗时过长的问题。通过调整连接超时时间和启用socket心跳维护连接状态,提供了两种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis-py连接池重连耗时处理

问题来源

最近项目中用到tornado + mongodb + redis,之前写爬虫的时候用到过redis-py感觉简单容易上手,结合tornado使用就出现了连接池中连接失效重连耗时太久的问题。

代码例子如下:

import time
import redis

redis_setting = dict(
    host='127.0.0.1',
)
db = redis.Redis(connection_pool=redis.ConnectionPool(**redis_setting))

def do_with_redis():
    now = time.time()
    db.get('a')
    print(time.time() - now)

def do_something():
    do_with_redis()  # 第一次查询
    time.sleep(301)  # do something other,一些业务逻辑
    do_with_redis()  # 第二次查询

do_something()
得到的结果是:
第一次查询耗时0.018s左右
第二次查询耗时20.018s左右

查看了官方文档说redis连接默认20s超时,关键代码是client.py中669行。
当连接池中的socket已经失效,等待20s s.recv()没有响应,就会抛出异常走到671行,重连继续运行。

client.py

解决方案1(不完全)

把连接超时时间缩短,然后超时后断开重连

redis_setting = dict(
    host='127.0.0.1',
    socket_timeout=1,
    socket_connect_timeout=1,
    retry_on_timeout=True
)

但是这样还是需要忍受1s的时间

解决方案2(推荐)

让socket连接保持心跳,维持连接状态。找了一堆的socket资料,再读一遍源代码,终于发现还能这样用。

redis_setting = dict(
    host='127.0.0.1',
    socket_keepalive=True,
    socket_keepalive_options={socket.TCP_KEEPIDLE: 60, socket.TCP_KEEPINTVL: 30, socket.TCP_KEEPCNT: 3}
)
<think>好的,我现在需要帮助用户了解Flask与Redis集成的扩展。用户之前问过Flask-PyMongo,现在转向Redis,可能是在项目中需要缓存或者消息队列功能。首先,我需要确定用户的需求,可能是为了提高应用性能,或者处理实时数据。 首先,我应该介绍Flask-Redis或Flask-Redis扩展的基本信息,但要注意,实际上Flask官方并没有一个叫做Flask-Redis的官方扩展。常用的可能是redis-py库直接集成,或者第三方扩展如Flask-Redis。需要确认正确的库名称,避免混淆。比如,可能有多个类似的库,比如flask-redis、Flask-RedisExt等,但用户可能指的是使用redis-py在Flask中的集成方式。 接下来,需要涵盖安装步骤、基本配置、核心功能,比如缓存、会话存储、任务队列等。用户可能关心如何配置Redis连接,如何在视图函数中使用,以及常见用例,比如缓存视图结果、存储会话数据,或者作为Celery的后端。 还需要注意错误处理和性能优化,比如连接池配置、超时设置,以及如何避免常见错误。用户可能希望了解如何确保连接的高效和稳定性,特别是在高并发场景下。 另外,用户之前的问题中,助手给出了Flask-PyMongo的详细分步说明,所以用户可能期待类似的结构,比如核心功能、安装部署、使用场景、性能优化、错误处理和替代方案对比。需要保持结构一致,方便用户对比学习。 可能还需要比较不同的Redis集成方式,比如直接使用redis-py还是通过Flask扩展,指出各自的优缺点。例如,Flask扩展可能简化配置,而直接使用redis-py更灵活。 最后,确保回答使用正确的中文术语,代码示例符合规范,如使用$...$格式的行内代码和$$...$$的独立公式(如果有的话)。例如,在讲解性能优化时,可能提到连接池的大小公式,或者缓存命中率的计算,但需要合理使用数学表达式。 需要验证所有代码示例的正确性,比如配置Redis URI,初始化扩展,以及使用set和get方法。同时,注意提醒用户关于安全配置,比如密码和SSL的设置,特别是在生产环境中。 总结步骤:介绍扩展,安装配置,核心功能,使用场景,性能优化,错误处理,替代方案。保持与之前回答类似的结构,确保用户容易理解。</think>--- ### Flask 与 Redis 的集成指南 Redis 是一款高性能的键值存储数据库,常用于缓存、会话管理和实时数据处理。在 Flask 中集成 Redis 通常通过 `redis-py` 库实现,也可使用第三方扩展如 `Flask-Redis` 或 `Flask-Caching`。以下是详细解析: --- #### 一、核心组件选择 1. **直接使用 `redis-py`** - 官方原生驱动,灵活性高 - 需手动管理连接和配置 $$ \text{响应时间} \propto \frac{1}{\text{连接池复用率}} $$ 2. **`Flask-Redis` 扩展** - 简化配置和连接管理 - 集成 Flask 应用上下文 3. **`Flask-Caching`** - 专门用于缓存场景 - 支持 Redis、Memcached 等后端 --- #### 二、安装与配置 1. **安装基础库** ```bash pip install redis # 原生驱动 pip install Flask-Redis # 扩展(非官方) ``` 2. **基础配置示例** ```python from flask import Flask from flask_redis import FlaskRedis app = Flask(__name__) app.config["REDIS_URL"] = "redis://:password@localhost:6379/0" redis_client = FlaskRedis(app) ``` --- #### 三、核心功能实现 1. **数据缓存** ```python @app.route("/get_data") def get_data(): cached_data = redis_client.get("cached_result") if not cached_data: data = calculate_expensive_data() # 耗时操作 redis_client.setex("cached_result", 3600, data) # 缓存1小时 return data return cached_data ``` 2. **会话管理** ```python from flask import session app.config["SESSION_TYPE"] = "redis" # 使用 Redis 存储会话 ``` 3. **任务队列(结合 Celery)** ```python from celery import Celery celery = Celery(app.name, broker=app.config["REDIS_URL"]) ``` --- #### 四、性能优化 1. **连接池配置** ```python app.config["REDIS_MAX_CONNECTIONS"] = 50 # 最大连接数 ``` 2. **管道操作(Pipeline)** ```python with redis_client.pipeline() as pipe: pipe.set("key1", "value1").set("key2", "value2").execute() ``` 3. **Lua 脚本优化** ```python script = """ local count = redis.call('GET', KEYS[1]) return tonumber(count) + 1 """ redis_client.eval(script, 1, "counter") # 原子递增 ``` --- #### 五、错误处理 1. **连接试机制** ```python from redis import Redis, ConnectionError try: redis_client.ping() # 测试连接 except ConnectionError: retry_connection() ``` 2. **哨兵模式配置** ```python app.config["REDIS_URL"] = "redis+sentinel://:password@sentinel-host:26379/mymaster/0" ``` --- #### 六、安全实践 1. **SSL 加密连接** ```python app.config["REDIS_URL"] = "rediss://:password@host:6379/0" # rediss协议 ``` 2. **访问控制** ```python # 在 Redis 服务端配置 requirepass redis-cli CONFIG SET requirepass "yourpassword" ``` --- #### 七、替代方案对比 | 方案 | 适用场景 | 性能对比 | |------|----------|----------| | `redis-py` | 需要精细控制连接和操作 | 原生最佳性能 | | `Flask-Redis` | 快速集成 Flask 应用 | 性能接近原生 | | `Flask-Caching` | 专注缓存场景 | 额外封装开销约 5-10% | --- 通过合理选择工具和优化策略,可以在 Flask 中高效利用 Redis 实现缓存加速、会话共享和分布式任务处理。建议根据具体需求选择集成方式:直接操作 `redis-py` 适合深度优化,而扩展库适合快速开发。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值