用于大规模保持图的NoSQL解决方案

Los*_*oul 28 python graph-theory nosql networkx

我迷上了使用Python和NetworkX来分析图形,因为我学到更多,我想使用越来越多的数据(猜测我正在变成一个数据迷:-).最终我认为我的NetworkX图形(存储为dict的dict)将超出我系统的内存.我知道我可能只是添加更多内存,但我想知道是否有办法将NetworkX与Hbase或类似解决方案集成?

我环顾四周,找不到任何东西,但我也找不到与允许简单的MySQL后端相关的任何东西.

这可能吗?是否存在允许连接到某种持久存储的任何东西?

谢谢!

更新:我记得在"社交网络分析初创公司"中看过这个主题,作者谈到了其他存储方法(包括hbase,s3等),但没有说明如何做到这一点或是否可行.

dou*_*oug 44

存储图表有两种常规类型的容器:

  1. 真实的图形数据库:例如,Neo4J,agamemnon,GraphDBAllegroGraph ; 这些不仅存储图形,而且它们也理解图形,例如,您可以查询这些数据库,例如,从节点X到节点Y的最短路径之间有多少个节点

  2. 静态图形容器:Twitter的MySQL改编的FlockDB是这里最着名的示例.这些DB可以很好地存储和检索图形; 但要查询图形本身,您必须首先从数据库中检索图形,然后使用库(例如,Python的优秀Networkx)来查询图形本身.

我在下面讨论的基于redis的图形容器属于第二类,但显然redis也非常适合第一类容器,如redis-graph所证明,redis-graph是一个非常小的python包,用于在redis中实现图形数据库.

redis将在这里工作得很漂亮.

Redis是一个适合生产使用的重型耐用数据存储,但它也足够简单,可用于命令行分析.

Redis与其他数据库的不同之处在于它具有多种数据结构类型; 我在这里推荐的是哈希数据类型.使用此redis数据结构,您可以非常接近地模仿"字典列表",这是一种用于存储图形的传统模式,其中列表中的每个项目都是键入这些边缘所源自的节点的边缘字典.

您需要先安装redis和python客户端.该DeGizmo博客具有优异的"向上和运行"教程,其包括一步一步的GUID上安装两者.

一旦安装了redis及其python客户端,启动一个redis服务器,你喜欢这样:

  • cd到安装redis的目录(如果通过make install安装,则在'nix上为/ usr/local/bin); 下一个

  • 在shell提示符下键入redis-server然后输入

您现在应该在shell窗口中看到服务器日志文件

>>> import numpy as NP
>>> import networkx as NX

>>> # start a redis client & connect to the server:
>>> from redis import StrictRedis as redis
>>> r1 = redis(db=1, host="localhost", port=6379)
Run Code Online (Sandbox Code Playgroud)

在下面的代码片段中,我存储了一个四节点图; 下面的每一行在redis客户端上调用hmset并存储一个节点和连接到该节点的边("0"=> 无边,"1"=>边缘).(实际上,当然,你会在函数中抽象出这些重复的调用;这里我展示了每个调用,因为它可能更容易理解.)

>>> r1.hmset("n1", {"n1": 0, "n2": 1, "n3": 1, "n4": 1})
      True

>>> r1.hmset("n2", {"n1": 1, "n2": 0, "n3": 0, "n4": 1})
      True

>>> r1.hmset("n3", {"n1": 1, "n2": 0, "n3": 0, "n4": 1})
      True

>>> r1.hmset("n4", {"n1": 0, "n2": 1, "n3": 1, "n4": 1})
      True

>>> # retrieve the edges for a given node:
>>> r1.hgetall("n2")
      {'n1': '1', 'n2': '0', 'n3': '0', 'n4': '1'}
Run Code Online (Sandbox Code Playgroud)

现在图表已保留,请将其作为NetworkX图形从redis DB中检索.

有很多方法可以做到这一点,下面是两个*步骤*:

  1. 将数据从redis数据库中提取到邻接矩阵中,实现为2D NumPy数组; 然后

  2. 使用NetworkX 内置函数将其直接转换为NetworkX图形 :

缩减为代码,这两个步骤是:

>>> AM = NP.array([map(int, r1.hgetall(node).values()) for node in r1.keys("*")])
>>> # now convert this adjacency matrix back to a networkx graph:
>>> G = NX.from_numpy_matrix(am)

>>> # verify that G in fact holds the original graph:
>>> type(G)
      <class 'networkx.classes.graph.Graph'>
>>> G.nodes()
      [0, 1, 2, 3]
>>> G.edges()
      [(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (3, 3)]
Run Code Online (Sandbox Code Playgroud)

当您结束redis会话时,您可以从客户端关闭服务器,如下所示:

>>> r1.shutdown()
Run Code Online (Sandbox Code Playgroud)

redis在关闭之前保存到磁盘,因此这是确保所有写入都保持不变的好方法.

那么redis DB在哪里?它使用默认文件名存储在默认位置,该文​​件名是主目录中的dump.rdb.

要更改此设置,请编辑redis.conf文件(包含在redis源代码分发中); 从以下开始:

# The filename where to dump the DB
dbfilename dump.rdb
Run Code Online (Sandbox Code Playgroud)

将dump.rdb更改为您希望的任何内容,但保留.rdb扩展名.

接下来,要更改文件路径,请在redis.conf中找到以下行:

# Note that you must specify a directory here, not a file name
Run Code Online (Sandbox Code Playgroud)

下面的行是redis数据库的目录位置.编辑它以便它背诵您想要的位置.保存您的修订并重命名此文件,但保留.conf扩展名.您可以将此配置文件存储在任何位置,只需在启动redis服务器时在同一行上提供此自定义配置文件的完整路径和名称:

所以下次启动redis服务器时,必须这样做(从shell提示符开始:

$> cd /usr/local/bin    # or the directory in which you installed redis 

$> redis-server /path/to/redis.conf
Run Code Online (Sandbox Code Playgroud)

最后,Python Package Index列出了一个专门用于在redis中实现图形数据库的包.该包称为redis-graph,我没有使用它.

  • neo4j是一个真正的图形数据库; 我在答案中实现的是一个"持久图".两者都可以存储图形; 图表db"理解"图形是什么,因此可以查询"节点X和节点Y之间有多少节点?要在上面的redis实现中执行此操作,您需要首先将图形从redis提取到例如, networkx.换句话说,neo4j(这是我所知道的唯一开源图形数据库)就像我的redis实现+智能图形应用程序层(networkx).如果你更喜欢使用Networkx,那么这个附加功能可能就是在路上. (5认同)

Jon*_*ler 5

有一个名为 Cloudlight 的 SQLlite3 支持的 NetworkX 实现。 https://www.assembla.com/spaces/cloudlight/wiki/Tutorial