Files
aiData/Util/RedisKit.py

150 lines
4.6 KiB
Python
Raw Normal View History

2026-01-12 07:49:18 +08:00
import asyncio
import logging
2026-01-20 08:09:13 +08:00
import os
2026-01-12 07:49:18 +08:00
import uuid
import json
import redis
2026-01-20 08:09:13 +08:00
from Config.Config import REDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD, REDIS_DECODE_RESPONSES
2026-01-12 07:49:18 +08:00
# 创建logger实例
logger = logging.getLogger(__name__)
class RedisKit:
"""
异步Redis工具类提供所有Redis操作的异步实现
单例模式确保全局只有一个Redis连接池
"""
_instance = None
_lock = asyncio.Lock()
_redis_pool = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
2026-01-20 08:09:13 +08:00
async def _ensure_pool(self):
2026-01-12 07:49:18 +08:00
"""
确保Redis连接池已创建
"""
2026-01-20 08:09:13 +08:00
if RedisKit._redis_pool is None:
async with RedisKit._lock:
if RedisKit._redis_pool is None:
2026-01-12 07:49:18 +08:00
try:
# 创建同步Redis连接池
sync_pool = redis.ConnectionPool(
host=REDIS_HOST,
port=REDIS_PORT,
db=REDIS_DB,
password=REDIS_PASSWORD,
2026-01-20 08:09:13 +08:00
decode_responses=REDIS_DECODE_RESPONSES
2026-01-12 07:49:18 +08:00
)
# 创建Redis连接实例
2026-01-20 08:09:13 +08:00
RedisKit._redis_pool = redis.Redis(
2026-01-12 07:49:18 +08:00
connection_pool=sync_pool,
encoding='utf-8',
decode_responses=REDIS_DECODE_RESPONSES
)
# 测试连接
2026-01-20 08:09:13 +08:00
await asyncio.to_thread(RedisKit._redis_pool.ping)
2026-01-12 07:49:18 +08:00
logger.info("Redis连接池创建成功")
except Exception as e:
logger.error(f"Redis连接池创建失败: {e}")
raise
2026-01-20 08:09:13 +08:00
async def get_connection(self):
2026-01-12 07:49:18 +08:00
"""
获取Redis连接实例
Returns:
redis.Redis: Redis连接实例
"""
2026-01-20 08:09:13 +08:00
await self._ensure_pool()
return RedisKit._redis_pool
2026-01-12 07:49:18 +08:00
async def get_data(self, key):
"""
异步从Redis中获取数据
Args:
key (str): Redis键名
Returns:
any: Redis中存储的值如果键不存在则返回None
"""
try:
await self._ensure_pool()
return await asyncio.to_thread(RedisKit._redis_pool.get, key)
except Exception as e:
logger.error(f"从Redis获取数据失败(key={key}): {e}")
return None
async def exists(self, key):
"""
异步检查Redis键是否存在
Args:
key (str): Redis键名
Returns:
bool: 键存在返回True不存在或失败返回False
"""
try:
await self._ensure_pool()
result = await asyncio.to_thread(RedisKit._redis_pool.exists, key)
return bool(result)
except Exception as e:
logger.error(f"检查Redis键是否存在失败(key={key}): {e}")
return False
async def set_data(self, key, value, expire=None):
2026-01-21 08:41:47 +08:00
"""
异步保存数据到Redis
Args:
key (str): Redis键名
value (any): 要保存的值
expire (int, optional): 过期时间
"""
2026-01-12 07:49:18 +08:00
try:
await self._ensure_pool()
if expire:
2026-01-20 08:09:13 +08:00
await asyncio.to_thread(RedisKit._redis_pool.set, key, value, ex=expire)
2026-01-12 07:49:18 +08:00
else:
2026-01-20 08:09:13 +08:00
await asyncio.to_thread(RedisKit._redis_pool.set, key, value)
2026-01-12 07:49:18 +08:00
return True
except Exception as e:
2026-01-20 08:09:13 +08:00
logger.error(f"保存数据到Redis失败(key={key}): {e}")
2026-01-12 07:49:18 +08:00
return False
2026-01-21 08:41:47 +08:00
async def close(self):
"""
关闭Redis连接池
"""
if RedisKit._redis_pool is not None:
try:
# redis-py 4.x+ supports close()
await asyncio.to_thread(RedisKit._redis_pool.close)
RedisKit._redis_pool = None
logger.info("Redis连接池已关闭")
except Exception as e:
logger.error(f"关闭Redis连接池失败: {e}")
async def delete_data(self, key):
"""
异步删除Redis中的数据
Args:
key (str): Redis键名
"""
try:
await self._ensure_pool()
await asyncio.to_thread(RedisKit._redis_pool.delete, key)
return True
except Exception as e:
logger.error(f"从Redis删除数据失败(key={key}): {e}")
return False
2026-01-20 08:09:13 +08:00
2026-01-21 08:41:47 +08:00
# ȫ<><C8AB>ʵ<EFBFBD><CAB5>
2026-01-20 08:09:13 +08:00
redisKit = RedisKit()