使用大型 networkx 图形和 Flask 网络服务器

Working with large networkx graph and Flask webserver

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

这是我的示例代码(去掉了错误处理 ,只显示了 Dijkstra 实现),如果您提交一个 return 路径GET 请求 localhost:3000/d?source=a&target=b:

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)

图表非常大(一百万个节点,两千万条边),所以我目前在应用程序加载时从 CSV 填充它,而不是为每个请求构建它。在我的 MacBook Pro(3GHz,16GB 内存)本地 运行 上,这大约需要五分钟。查找需要不同的时间,但通常在 15 秒左右,并且性能通常会在使用一定量后下降,这意味着我必须重新启动应用程序。

问题一:因为这很慢而且占用大量内存,有没有办法存储这个图,这样我就不必每次都生成它,然后等一下它在内存中?

问题二:我使用 G 作为全局变量的方法是否正确?

我以前没有用过这么大的图表,所以我知道我的实现可能远非理想,如果有任何关于如何使它可靠地执行 better/more 的想法,我将不胜感激!

您是否尝试过使用市场中可用的缓存?

创建一个更新这些缓存或 pickle 的后台脚本,您的请求仅加载并发送其中的数据。

编辑 由于 OP 还在 NetworkX 上找到了 Builtin Pickles Method enter link description here

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

编辑 2 当您 pickle 整个数据结构时,您会受到系统 RAM 的限制。但是,您可以分块进行。

streaming-pickle 可以作为酸洗大于板上内存的对象的解决方案。因为 unpickling 时会出现问题,但您也可以使用这种方法来克服它。

或者使用 Redis 方法,如果你想在请求完成后保留数据,你可以寻找 Redis Cluster

这是一个非常棘手的问题 :D 取决于您实际需要什么。