由于有缓存图片验证码的需要,所以我找了一些开源的缓存想直接使用,结果要么太老旧,要么太复杂,要么和 `fastAPI` 整合有问题,所以才想到自己写一个简单的,够用就好。
本文讲述了如何实现一个简单的内存缓存,他可以把过期的键值自动清除,在缓存验证码等场合应该很好用。
它的基本实现思路是:在初始化的时候自动启动一个清理线程,轮询删除过期的键值。
在实现的过程中使用了 `lock` ,以保证多线程安全。
主要代码如下:
1 class Cache: 2 def __init__(self, max_size, ttl): 3 """ 4 初始化缓存类 5 :param max_size: 缓存最大容量 6 :param ttl: 每个缓存元素的生存时间(秒) 7 """ 8 self.max_size = max_size 9 self.ttl = ttl 10 self.cache = {} # 存储缓存数据 11 self.lock = Lock() # 保证线程安全 12 self._start_cleanup_thread() # 启动自动清理线程 13 14 def _start_cleanup_thread(self): 15 """启动后台线程定期清理过期缓存""" 16 def cleanup(): 17 while True: 18 time.sleep(1) 19 self._remove_expired_keys() 20 21 thread = Thread(target=cleanup, daemon=True) 22 thread.start() 23 24 def _remove_expired_keys(self): 25 """移除过期的缓存键""" 26 with self.lock: 27 current_time = time.time() 28 expired_keys = [ 29 key for key, (_, expire_at) in self.cache.items() 30 if expire_at <= current_time 31 ] 32 for key in expired_keys: 33 del self.cache[key] 34 print(f"清理过期键:{key}") 35 36 def add(self, key, value): 37 """ 38 添加缓存元素 39 :param key: 缓存键 40 :param value: 缓存值 41 :raises CacheFullError: 当缓存已满时抛出 42 """ 43 with self.lock: 44 if key in self.cache: 45 # 如果键已存在,更新值和过期时间 46 self.cache[key] = (value, time.time() + self.ttl) 47 return 48 if len(self.cache) >= self.max_size: 49 print("缓存已满,无法添加新元素") 50 return Error.FULL 51 self.cache[key] = (value, time.time() + self.ttl) 52 return Error.OK 53 54 def get(self, key): 55 """ 56 获取缓存值 57 :param key: 缓存键 58 :return: 缓存值 59 :raises KeyError: 当键不存在或过期时抛出 60 """ 61 with self.lock: 62 if key in self.cache: 63 value, expire_at = self.cache[key] 64 if time.time() < expire_at: 65 return Error.OK, value 66 else: 67 del self.cache[key] # 自动清除过期键 68 return Error.EXPIRED,None 69 return Error.NOT_FOUND,None
以上是主要的逻辑,下面是全部代码下载地址:
- [gitee]
- [github]
- [gitcode]
它已经实际应用在 langchain+llama3+Chroma RAG demo 中,有兴趣您也体验实际应用,并欢迎指正。
- [gitee]
- [github]
- [gitcode]
🪐祝您好运🪐
浙公网安备 33010602011771号