Python 使用大型networkx图形和Flask Web服务器

Python 使用大型networkx图形和Flask Web服务器,python,flask,networkx,graph-theory,Python,Flask,Networkx,Graph Theory,我正在尝试创建一个Flask web应用程序,它可以查询NetworkX图,以返回最短路径(使用Dijkstra算法,加上Yen的k-最短路径算法) 下面是我的示例代码(去掉了错误处理等c,只显示了Dijkstra实现),如果您向localhost:3000/d?source=a&target=b提交GET请求,它将返回路径: import csv import json import networkx as nx from flask import Flask, request app =

我正在尝试创建一个Flask web应用程序,它可以查询NetworkX图,以返回最短路径(使用Dijkstra算法,加上Yen的k-最短路径算法)

下面是我的示例代码(去掉了错误处理等c,只显示了Dijkstra实现),如果您向
localhost:3000/d?source=a&target=b提交GET请求,它将返回路径:

import csv
import json
import networkx as nx
from flask import Flask, request

app = Flask(__name__)
G = nx.Graph()

@app.route('/d')
def dijkstra():

  global G

  source = request.args['source'].lower().strip()
  target = request.args['target'].lower().strip()

  path = nx.dijkstra_path(G, source, target, weight='weight')

  return json.dumps(path)


if __name__ == '__main__':

  global G

  with open('nodes.csv', 'rb') as f:
    reader = csv.reader(f)
    node_list = list(reader)

  for i in nodes:
    G.add_node(i[0])

  with open('edges.csv', 'rb') as f:
    reader = csv.reader(f)
    edge_list = list(reader)

  for i in edges:
    G.add_edge(i[0], i[1], weight=i[2])

  app.run(host='0.0.0.0', port=3000, use_reloader=False)
这个图非常大(一百万个节点,两千万条边),所以我现在在应用程序加载时从CSVs填充它,而不是为每个请求构建它。在我的MacBookPro(3GHz,16GB RAM)上本地运行时,这大约需要五分钟。查找需要不同的时间,但通常在15秒左右,使用一定量后性能通常会下降,这意味着我必须重新启动应用程序

问题一:由于这是一个缓慢且占用大量内存的过程,是否有一种方法可以存储此图,这样我就不必每次都生成它,然后将其保存在内存中

问题二:我使用
G
作为全局变量来处理它是否正确


我以前从未使用过这么大的图,所以我知道我的实现可能远不是理想的,如果您能想到如何使它更好/更可靠地运行,我将不胜感激

您是否尝试使用市场上提供的缓存

  • 此库利用redis缓存
  • 或者你甚至可以使用
创建一个后台脚本来更新这些缓存或pickle,您的请求只加载并发送其中的数据

编辑 As OP还发现了NetworkX上的内置Pickles方法

比较酸洗和直接处理CSV的速度

编辑2 当您pickle整个数据结构时,您受到系统RAM的限制。然而,你可以分块做

可以是一种酸洗大于板上内存的对象的解决方案。因为问题是在取消勾选时发生的,但是您也可以使用这种方法来克服它

或者使用Redis方法,如果您希望在请求完成后保存数据,您可以查找


这是一个大问题:D取决于您实际需要什么。

谢谢您的快速回复!看起来NetworkX有一个读/写pickle()的函数。这就是你的意思吗?当必须加载整个图形时,这不会产生相同的内存问题吗?Wunderbar,如果它内置了picke write:D。您可以在这里比较响应时间Pickles和HDF5比CSV快得多。现在尝试一下会让您知道。再次感谢!:)运气不好:(尝试创建pickle花了大约20分钟,然后我收到了一条
Killed:9
消息。还有其他想法吗?StackOverflow还是OutOfm?它显示了什么错误?PS这里是记录每个阶段的脚本版本的计时示例,因此您可以看到所花费的时间:从开始到加载1014896个节点的3.6秒;99)。从开始算起0秒(∴ 95.4秒)加载20025902个边缘;从开始算起101.3秒(∴ 5.9秒)将节点添加到图表中;从开始算起330.9秒(∴ 229.6秒)将边添加到图形中。