Flask:使用全局变量将数据文件加载到内存中

10

我有一个很大的XML文件,由Python类打开、加载到内存中,然后关闭。一个简单的示例如下:

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和网络编程的新手,只是寻求指导。
谢谢!

1
嗨,Sam,你最终使用了这个解决方案吗?它有效吗?你能处理多少个请求? - Private
1个回答

11
只要全局对象未被修改,这种方式是安全的。这是 WSGI 功能,如 Werkzeug 文档1 所解释的那样(Flask 依赖于其构建)。
该数据将保留在每个 WSGI 应用程序服务器的工作进程的内存中。这并不意味着只有一次,而是进程(工作者)数量较少且恒定(不取决于会话或流量数量)。
因此,可能可以保持这种方式。
即便如此,我会使用适当的数据库。如果您有16个工作进程,则数据将占用至少800 MB的RAM(工作者的数量通常是处理器数量的两倍)。如果 XML 文件增长,最终决定使用数据库服务,您将需要重写代码。
如果保留数据在内存中的原因是 PostgreSQL 和 MySQL 太慢,可以使用保存在 RAMFS 或 TMPFS 等内存文件系统中的 SQLite。它提供了速度、SQL 接口,您可能还可以节省 RAM 的使用。迁移到 PostgreSQL 或 MySQL 也会更容易(从代码方面来看)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接