litefs.cache.memcache 源代码

#!/usr/bin/env python
# coding: utf-8

"""
Memcache 缓存后端

提供基于 Memcache 的缓存实现
"""

import time
import json
from typing import Any, Optional


[文档] class MemcacheCache: """ Memcache 缓存实现 使用 Memcache 作为缓存后端,提供高性能的分布式缓存支持 """ def __init__( self, memcache_client=None, servers: list = ["localhost:11211"], key_prefix: str = "litefs:", expiration_time: int = 3600, **kwargs ): """ 初始化 Memcache 缓存 Args: memcache_client: Memcache 客户端实例(如果提供,则忽略其他连接参数) servers: Memcache 服务器列表 key_prefix: 键前缀 expiration_time: 默认过期时间(秒) **kwargs: 其他 Memcache 连接参数 """ self._key_prefix = key_prefix self._expiration_time = expiration_time if memcache_client is not None: self._mc = memcache_client else: try: import pymemcache from pymemcache.client.base import Client except ImportError: try: import memcache except ImportError: raise ImportError( "pymemcache 或 python-memcached 包未安装," "请使用 pip install pymemcache 或 pip install python-memcached 安装" ) self._use_pymemcache = True self._mc = Client(servers[0] if isinstance(servers, list) else servers, **kwargs) self._test_connection() def _test_connection(self): """测试 Memcache 连接""" try: if hasattr(self._mc, 'stats'): self._mc.stats() else: self._mc.set('_litefs_test', '1') self._mc.delete('_litefs_test') except Exception as e: raise ConnectionError(f"无法连接到 Memcache 服务器: {e}") def _make_key(self, key: str) -> str: """生成带前缀的键""" return f"{self._key_prefix}{key}"
[文档] def put(self, key: str, val: Any, expiration: Optional[int] = None) -> None: """ 存储值到缓存 Args: key: 缓存键 val: 缓存值 expiration: 过期时间(秒),如果为 None 则使用默认过期时间 """ memcache_key = self._make_key(key) expiration = expiration if expiration is not None else self._expiration_time # 序列化值 try: val_str = json.dumps(val) except Exception as e: raise ValueError(f"无法序列化值: {e}") if self._use_pymemcache: self._mc.set(memcache_key, val_str, expire=expiration if expiration > 0 else 0) else: self._mc.set(memcache_key, val_str, time=expiration)
[文档] def get(self, key: str) -> Optional[Any]: """ 从缓存获取值 Args: key: 缓存键 Returns: 缓存值,如果不存在则返回 None """ memcache_key = self._make_key(key) val_str = self._mc.get(memcache_key) if val_str is None: return None # 反序列化值 try: return json.loads(val_str) except Exception as e: # 如果反序列化失败,返回原始字符串 return val_str
[文档] def delete(self, key: str) -> None: """ 从缓存删除值 Args: key: 缓存键 """ memcache_key = self._make_key(key) self._mc.delete(memcache_key)
[文档] def delete_pattern(self, pattern: str) -> int: """ 删除匹配模式的键 注意:Memcache 不支持模式匹配,此方法仅返回 0 Args: pattern: 键模式 Returns: 删除的键数量(始终为 0) """ return 0
[文档] def exists(self, key: str) -> bool: """ 检查键是否存在 Args: key: 缓存键 Returns: 键是否存在 """ memcache_key = self._make_key(key) return self._mc.get(memcache_key) is not None
[文档] def expire(self, key: str, expiration: int) -> bool: """ 设置键的过期时间 Args: key: 缓存键 expiration: 过期时间(秒) Returns: 是否设置成功 """ memcache_key = self._make_key(key) value = self._mc.get(memcache_key) if value is None: return False if self._use_pymemcache: self._mc.set(memcache_key, value, expire=expiration if expiration > 0 else 0) else: self._mc.set(memcache_key, value, time=expiration) return True
[文档] def ttl(self, key: str) -> int: """ 获取键的剩余过期时间 注意:Memcache 不支持 TTL 查询,此方法返回 -1 Args: key: 缓存键 Returns: 剩余过期时间(秒),如果键不存在则返回 -2,否则返回 -1(不支持查询) """ memcache_key = self._make_key(key) if self._mc.get(memcache_key) is None: return -2 return -1
[文档] def clear(self) -> None: """ 清空所有缓存 注意:此方法仅删除带前缀的键,需要遍历所有键 """ pass
def __len__(self) -> int: """ 获取缓存中的键数量 注意:Memcache 不支持统计键数量,此方法返回 0 Returns: 键数量(始终为 0) """ return 0
[文档] def get_many(self, keys: list) -> dict: """ 批量获取值 Args: keys: 缓存键列表 Returns: 键值字典 """ if not keys: return {} memcache_keys = [self._make_key(key) for key in keys] if self._use_pymemcache: values = self._mc.get_many(memcache_keys) result = {} for memcache_key, val_str in values.items(): original_key = memcache_key.replace(self._key_prefix, '', 1) if val_str is not None: # 反序列化值 try: result[original_key] = json.loads(val_str) except Exception: # 如果反序列化失败,返回原始字符串 result[original_key] = val_str return result else: values = self._mc.get_multi(memcache_keys) result = {} for memcache_key, val_str in values.items(): original_key = memcache_key.replace(self._key_prefix, '', 1) if val_str is not None: # 反序列化值 try: result[original_key] = json.loads(val_str) except Exception: # 如果反序列化失败,返回原始字符串 result[original_key] = val_str return result
[文档] def set_many(self, mapping: dict, expiration: Optional[int] = None) -> None: """ 批量存储值 Args: mapping: 键值字典 expiration: 过期时间(秒),如果为 None 则使用默认过期时间 """ if not mapping: return expiration = expiration if expiration is not None else self._expiration_time memcache_mapping = {} for key, value in mapping.items(): # 序列化值 try: val_str = json.dumps(value) except Exception as e: raise ValueError(f"无法序列化值: {e}") memcache_key = self._make_key(key) memcache_mapping[memcache_key] = val_str if self._use_pymemcache: self._mc.set_many(memcache_mapping, expire=expiration if expiration > 0 else 0) else: self._mc.set_multi(memcache_mapping, time=expiration)
[文档] def delete_many(self, keys: list) -> None: """ 批量删除键 Args: keys: 缓存键列表 """ if not keys: return memcache_keys = [self._make_key(key) for key in keys] if self._use_pymemcache: self._mc.delete_many(memcache_keys) else: self._mc.delete_multi(memcache_keys)
[文档] def close(self) -> None: """ 关闭 Memcache 连接 """ try: if hasattr(self._mc, 'close'): self._mc.close() except Exception: pass
def __enter__(self): """支持上下文管理器""" return self def __exit__(self, exc_type, exc_val, exc_tb): """支持上下文管理器""" self.close()
__all__ = [ "MemcacheCache", ]