Flask:使用全局变量将数据文件加载到内存中
Flask: Using a global variable to load data files into memory
我有一个很大的 XML 文件,它被打开,加载到内存中,然后被 Python class 关闭。一个简化的示例如下所示:
class Dictionary():
def __init__(self, filename):
f = open(filename)
self.contents = f.readlines()
f.close()
def getDefinitionForWord(self, word):
# returns a word, using etree parser
在我的 Flask 应用程序中:
from dictionary import Dictionary
dictionary = Dictionary('dictionary.xml')
print 'dictionary object created'
@app.route('/')
def home():
word = dictionary.getDefinitionForWord('help')
我知道在理想情况下,我会使用数据库而不是 XML 并在每次请求时与该数据库建立新连接。
我从文档中了解到 Flask 中的应用程序上下文意味着每个请求都会导致 dictionary = new Dictionary('dictionary.xml')
重新创建,因此打开磁盘上的文件并将整个内容重新读入内存。但是,当我查看调试输出时,我看到 dictionary object created
行只打印了一次,尽管从多个源(不同的会话?)进行了连接。
我的第一个问题是:
因为我的应用程序似乎只加载了一次 XML 文件...那么我可以假设它全局驻留在内存中,并且可以被大量同时安全地读取请求,仅受我服务器上 RAM 的限制——对吧?如果 XML 是 50MB,那么大约需要。 50MB 内存并高速处理同时请求...我猜这并不容易。
我的第二个问题是:
如果不是这种情况,我处理大量流量的能力会受到什么样的限制?如果我有一个 50MB XML 被反复打开、从磁盘读取和关闭,我可以处理多少请求?我一次假设一个。
我意识到这很模糊并且取决于硬件,但我是 Flask、python 和网络编程的新手,只是在寻找指导。
谢谢!
只要不修改全局对象,就可以安全地保留它。这是 Werkzeug 文档中解释的 WSGI 功能1(Flask 构建于其上的库)。
该数据将保存在 WSGI 应用服务器的每个工作进程的内存中。这并不意味着一次,而是进程(worker)的数量很少且恒定(不取决于会话数或流量)。
因此,可能保持这种状态。
就是说,我会在您那里使用合适的数据库。如果您有 16 个 worker,您的数据将占用至少 800 MB 的 RAM(worker 的数量通常是处理器数量的两倍)。如果 XML 增长并且您最终决定使用数据库服务,则需要重写代码。
如果保留内存的原因是 PostgreSQL 和 MySQL 太慢,您可以使用 SQLite 保存在像 RAMFS 这样的内存文件系统中临时文件系统。它为您提供了速度、SQL 界面,并且您可能会节省 RAM 使用量。迁移到 PostgreSQL 或 MySQL 也会容易得多(就代码而言)。
我有一个很大的 XML 文件,它被打开,加载到内存中,然后被 Python class 关闭。一个简化的示例如下所示:
class Dictionary():
def __init__(self, filename):
f = open(filename)
self.contents = f.readlines()
f.close()
def getDefinitionForWord(self, word):
# returns a word, using etree parser
在我的 Flask 应用程序中:
from dictionary import Dictionary
dictionary = Dictionary('dictionary.xml')
print 'dictionary object created'
@app.route('/')
def home():
word = dictionary.getDefinitionForWord('help')
我知道在理想情况下,我会使用数据库而不是 XML 并在每次请求时与该数据库建立新连接。
我从文档中了解到 Flask 中的应用程序上下文意味着每个请求都会导致 dictionary = new Dictionary('dictionary.xml')
重新创建,因此打开磁盘上的文件并将整个内容重新读入内存。但是,当我查看调试输出时,我看到 dictionary object created
行只打印了一次,尽管从多个源(不同的会话?)进行了连接。
我的第一个问题是:
因为我的应用程序似乎只加载了一次 XML 文件...那么我可以假设它全局驻留在内存中,并且可以被大量同时安全地读取请求,仅受我服务器上 RAM 的限制——对吧?如果 XML 是 50MB,那么大约需要。 50MB 内存并高速处理同时请求...我猜这并不容易。
我的第二个问题是:
如果不是这种情况,我处理大量流量的能力会受到什么样的限制?如果我有一个 50MB XML 被反复打开、从磁盘读取和关闭,我可以处理多少请求?我一次假设一个。
我意识到这很模糊并且取决于硬件,但我是 Flask、python 和网络编程的新手,只是在寻找指导。
谢谢!
只要不修改全局对象,就可以安全地保留它。这是 Werkzeug 文档中解释的 WSGI 功能1(Flask 构建于其上的库)。
该数据将保存在 WSGI 应用服务器的每个工作进程的内存中。这并不意味着一次,而是进程(worker)的数量很少且恒定(不取决于会话数或流量)。
因此,可能保持这种状态。
就是说,我会在您那里使用合适的数据库。如果您有 16 个 worker,您的数据将占用至少 800 MB 的 RAM(worker 的数量通常是处理器数量的两倍)。如果 XML 增长并且您最终决定使用数据库服务,则需要重写代码。
如果保留内存的原因是 PostgreSQL 和 MySQL 太慢,您可以使用 SQLite 保存在像 RAMFS 这样的内存文件系统中临时文件系统。它为您提供了速度、SQL 界面,并且您可能会节省 RAM 使用量。迁移到 PostgreSQL 或 MySQL 也会容易得多(就代码而言)。