【发布时间】:2013-12-06 09:18:25
【问题描述】:
我刚刚尝试使用 Python shelve 模块作为从外部服务获取的数据的持久缓存。 The complete example is here.
我想知道如果我想让这个多进程安全,最好的方法是什么?我知道 redis、memcached 和这样的“真正的解决方案”,但我只想使用 Python 标准库的一部分或非常少的依赖项来保持我的代码紧凑,并且在单个进程中运行代码时不会引入不必要的复杂性 -单线程模型。
想出一个单进程解决方案很容易,但这在当前的 Python Web 运行时效果不佳。具体来说,问题出在 Apache + mod_wsgi 环境中
只有一个进程会更新一次缓存数据(文件锁定,不知何故?)
其他进程在更新过程中使用缓存数据
-
如果进程未能更新缓存数据,则在另一个进程重试之前会受到 N 分钟的惩罚(以防止 thundering herd 等) - 如何在 mod_wsgi 进程之间发出信号
李> 您没有为此使用任何“重型工具”,仅使用 Python 标准库和 UNIX
另外,如果某些 PyPi 包在没有外部依赖的情况下执行此操作,请告诉我。欢迎使用其他方法和建议,例如“只使用 sqlite”。
例子:
import datetime
import os
import shelve
import logging
logger = logging.getLogger(__name__)
class Converter:
def __init__(self, fpath):
self.last_updated = None
self.data = None
self.data = shelve.open(fpath)
if os.path.exists(fpath):
self.last_updated = datetime.datetime.fromtimestamp(os.path.getmtime(fpath))
def convert(self, source, target, amount, update=True, determiner="24h_avg"):
# Do something with cached data
pass
def is_up_to_date(self):
if not self.last_updated:
return False
return datetime.datetime.now() < self.last_updated + self.refresh_delay
def update(self):
try:
# Update data from the external server
self.last_updated = datetime.datetime.now()
self.data.sync()
except Exception as e:
logger.error("Could not refresh market data: %s %s", self.api_url, e)
logger.exception(e)
【问题讨论】:
-
您的缓存数据是否需要能够交换和/或持久保存到磁盘,或者假设您的缓存将适合可用内存?
-
只是少量数据;但需要在服务器冷启动后在,以避免启动时没有可用数据的问题
标签: python memcached multiprocessing mod-wsgi shelve