我有一个大的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和网络编程的新手,只是寻求指导。
谢谢!
答案 0 :(得分:8)
只要不修改全局对象,就可以保持这种方式。这是一个WSGI功能,如Werkzeug docs 1(Flask建立在其上的库)中所述。
该数据将保存在WSGI应用服务器的每个工作进程的内存中。这并不意味着一次,但流程(工人)的数量很小而且不变(不依赖于会话或流量)。
所以,可能保持这种方式。
那就是说,我会在你的地方使用一个合适的数据库。如果您有16名工作人员,则您的数据至少需要800 MB RAM(工作人员数量通常是处理器数量的两倍)。如果XML增长并且您最终决定使用数据库服务,则需要重写代码。
如果保留内存的原因是PostgreSQL和MySQL太慢,你可以使用保存在内存文件系统中的SQLite,如TMPFS的RAMFS。它为您提供了速度,SQL界面,您可能会节省RAM使用率。迁移到PostgreSQL或MySQL也会更容易(就代码而言)。