88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
"""Redis 缓存层,替代内存缓存,支持持久化和跨进程共享。"""
|
||
import json
|
||
import redis
|
||
from typing import Any, Optional
|
||
from config import REDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD
|
||
|
||
class RedisCache:
|
||
def __init__(self):
|
||
self.client: Optional[redis.Redis] = None
|
||
self.enabled = False
|
||
self._connect()
|
||
|
||
def _connect(self):
|
||
"""连接 Redis,失败时降级为禁用状态"""
|
||
try:
|
||
self.client = redis.Redis(
|
||
host=REDIS_HOST,
|
||
port=REDIS_PORT,
|
||
db=REDIS_DB,
|
||
password=REDIS_PASSWORD if REDIS_PASSWORD else None,
|
||
decode_responses=True,
|
||
socket_connect_timeout=2,
|
||
socket_timeout=2
|
||
)
|
||
self.client.ping()
|
||
self.enabled = True
|
||
print(f"✓ Redis 已连接: {REDIS_HOST}:{REDIS_PORT}")
|
||
except Exception as e:
|
||
self.enabled = False
|
||
print(f"✗ Redis 连接失败,缓存已禁用: {e}")
|
||
|
||
def get(self, key: str) -> Optional[Any]:
|
||
"""获取缓存,自动反序列化 JSON"""
|
||
if not self.enabled:
|
||
return None
|
||
try:
|
||
value = self.client.get(key)
|
||
if value:
|
||
return json.loads(value)
|
||
return None
|
||
except Exception as e:
|
||
print(f"Redis get error: {e}")
|
||
return None
|
||
|
||
def set(self, key: str, value: Any, expire: int = 3600):
|
||
"""设置缓存,自动序列化为 JSON
|
||
|
||
Args:
|
||
key: 缓存键
|
||
value: 缓存值(可序列化为JSON的对象)
|
||
expire: 过期时间(秒),默认1小时
|
||
"""
|
||
if not self.enabled:
|
||
return False
|
||
try:
|
||
serialized = json.dumps(value, ensure_ascii=False, default=str)
|
||
self.client.setex(key, expire, serialized)
|
||
return True
|
||
except Exception as e:
|
||
print(f"Redis set error: {e}")
|
||
return False
|
||
|
||
def delete(self, key: str):
|
||
"""删除缓存"""
|
||
if not self.enabled:
|
||
return False
|
||
try:
|
||
self.client.delete(key)
|
||
return True
|
||
except Exception as e:
|
||
print(f"Redis delete error: {e}")
|
||
return False
|
||
|
||
def clear_pattern(self, pattern: str):
|
||
"""批量删除匹配模式的键"""
|
||
if not self.enabled:
|
||
return 0
|
||
try:
|
||
keys = self.client.keys(pattern)
|
||
if keys:
|
||
return self.client.delete(*keys)
|
||
return 0
|
||
except Exception as e:
|
||
print(f"Redis clear_pattern error: {e}")
|
||
return 0
|
||
|
||
# 全局单例
|
||
cache = RedisCache() |