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 也会容易得多(就代码而言)。