You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python asyncio脚本从Redis取非空数据返回None的原因与排查

问题分析与解决

可能的原因

1. Redis连接/数据库实例不一致

保存数据使用的是redis_pool,而获取数据时新建了Redis(host=redis_host)实例,两者可能存在连接参数差异:

  • 比如redis_pool配置了非默认的数据库(如db=1),但获取时用默认db=0
  • 或者redis_pool包含密码、端口等参数,新建实例未传入,导致连接到不同的Redis实例

2. 键名存在细微差异

日志打印的键名看起来一致,但实际生成的键可能存在大小写、空格、拼写错误等差异:

  • 保存时用的是exchange.__class__.__name__(类名,如BinanceClient),但获取时传入的exchange_name是小写(如binanceclient)或缩写
  • 方法名或符号名存在大小写、下划线差异(如get_ticker vs GetTicker)

3. 异步时序问题

获取数据的操作可能在保存数据的set操作完成前执行,尽管日志显示保存成功,但异步IO的特性可能导致Redis还未完成写入。

调试方法

  1. 直接检查Redis实例
    使用redis-cli执行命令,确认键是否存在:

    # 查看所有键
    KEYS "*"
    # 查看目标键的值
    GET "你的键名"
    

    如果Redis中不存在该键,说明保存逻辑有问题;如果存在,说明获取逻辑的键名或连接参数错误。

  2. 打印键的原始值
    在保存和获取函数中添加键的精确打印(用repr()避免隐藏字符):
    保存时:

    logging.info(f"Saved key: {repr(key)}")
    

    获取时:

    logging.info(f"Fetching key: {repr(key)}")
    

    对比两者输出,排查键名的细微差异。

  3. 校验Redis连接参数
    打印redis_pool和获取时Redis实例的连接配置,确认参数一致:

    # 保存时打印pool配置
    logging.info(f"Redis pool config: {redis_pool.connection_kwargs}")
    # 获取时打印实例配置
    redis = Redis(host=redis_host)
    logging.info(f"Fetch client config: {redis.connection_kwargs}")
    
  4. 验证异步执行顺序
    在获取数据前,确保保存任务已至少执行一次。可以临时添加延迟,或用事件通知机制确保写入完成。

解决方法

1. 统一Redis客户端

避免在获取函数中新建Redis实例,复用保存时的redis_pool,确保连接参数完全一致:

async def fetch_data_from_redis(redis_pool, exchange_name, method, symbol=None):
    key = f"{exchange_name}:{method}"
    if symbol:
        key = f"{key}:{symbol}"
    data = await redis_pool.get(key)
    return json.loads(data) if data else None

2. 标准化键名格式

统一键名的大小写或格式,避免类名/传入名称的差异:
保存时:

key = f"{exchange.__class__.__name__.lower()}:{method.lower()}"
if symbol:
    key = f"{key}:{symbol.lower()}"

获取时:

key = f"{exchange_name.lower()}:{method.lower()}"
if symbol:
    key = f"{key}:{symbol.lower()}"

3. 添加缺失键的调试日志

在获取函数中,当键不存在时打印Redis中的所有键,快速定位问题:

async def fetch_data_from_redis(redis_pool, exchange_name, method, symbol=None):
    key = f"{exchange_name}:{method}"
    if symbol:
        key = f"{key}:{symbol}"
    data = await redis_pool.get(key)
    if not data:
        all_keys = await redis_pool.keys("*")
        logging.warning(f"Key {repr(key)} not found. Existing keys: {all_keys}")
    return json.loads(data) if data else None

内容的提问来源于stack exchange,提问作者bigidulka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:11:07