Mik*_*maa 6 python memcached mod-wsgi shelve multiprocessing
我只是尝试了一个Python 搁置模块作为从外部服务获取的数据的持久缓存.完整的例子就在这里.
我想知道如果我想让这个多进程安全,最好的方法是什么?我知道redis,memcached和这样的"真正的解决方案",但是我只想使用Python标准库的部分或非常小的依赖性来保持我的代码紧凑,并且在单个进程中运行代码时不会引入不必要的复杂性 - 单线程模型.
很容易想出一个单进程解决方案,但这不适用于当前的Python Web运行时.具体来说,问题在于Apache + mod_wsgi环境
只有一个进程正在更新缓存数据一次(文件锁,不知何故?)
其他进程在更新过程中使用缓存的数据
如果进程无法更新缓存数据,那么在另一个进程可以再次尝试之前会有N分钟的惩罚(以防止雷鸣般的群体等) - 如何在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)
Run Code Online (Sandbox Code Playgroud)
我想说你想要使用一些现有的缓存库,dogpile.cache
它已经有很多功能,并且你可以轻松插入你可能需要的后端。
dogpile.cache
文档讲述了以下内容:
\n\n这个 \xe2\x80\x9cget-or-create\xe2\x80\x9d 模式是 \xe2\x80\x9cDogpile\xe2\x80\x9d\n 系统的整个关键,它协调多个值之间的单个值创建操作针对特定键的并发获取操作,消除了许多工作人员同时重复生成过期值的问题。
\n