Решение NoSQL для сохранения графиков в масштабе - PullRequest
28 голосов
/ 16 февраля 2012

Я подсел на использование Python и NetworkX для анализа графиков, и по мере того, как я узнаю больше, я хочу использовать все больше и больше данных (думаю, я становлюсь наркоманом данных :-). В конце концов я думаю, что мой график NetworkX (который хранится как dict of dict) превысит объем памяти в моей системе. Я знаю, что могу, вероятно, просто добавить больше памяти, но мне было интересно, есть ли способ вместо этого интегрировать NetworkX с Hbase или подобное решение?

Я оглянулся и ничего не смог найти, но я также не смог найти ничего, связанного с разрешением простого бэкэнда MySQL.

Возможно ли это? Существует ли что-то, что позволяет подключаться к какому-либо постоянному хранилищу?

Спасибо!

Обновление: я помню, как видел эту тему в «Анализе социальных сетей для стартапов», автор рассказывает о других методах хранения (включая hbase, s3 и т. Д.), Но не показывает, как это сделать или, если это возможно.

Ответы [ 3 ]

44 голосов
/ 10 марта 2012

Существует два основных типа контейнеров для хранения графиков:

  1. базы данных истинных графов: например, Neo4J , agamemnon, GraphDB и AllegroGraph ;они не только хранят граф, но и понимают, что граф - это, например, вы можете запросить эти базы данных, например, сколько узлов находится между кратчайшим путем от узла X к узлу Y ?

  2. контейнеры статических графов : FlockDB, адаптированный для MySQL, является самым известным примером в Twitter.Эти БД могут хранить и извлекать графики просто отлично;но чтобы запросить сам график, вы должны сначала извлечь график из БД, а затем использовать библиотеку (например, превосходный Networkx Python) для запроса самого графика.

на основе RedisГрафовый контейнер, который я обсуждаю ниже, относится ко второй категории, хотя очевидно, что redis также хорошо подходит для контейнеров в первой категории, о чем свидетельствует redis-graph , удивительно небольшой пакет python для реализации базы данных графов в redis..

redis будет прекрасно работать здесь.

Redis - это надежное и долговечное хранилище данных, пригодное для производственного использования, но также достаточно простое для анализа из командной строки.

Redis отличается отдругие базы данных, в которых есть несколько типов структур данных;я бы порекомендовал тип данных hash .Использование этой структуры данных redis позволяет очень близко имитировать «список словарей», традиционную схему хранения графиков, в которой каждый элемент в списке представляет собой словарь ребер, привязанных к узлу, из которого происходят эти ребра.

Сначала необходимо установить redis и клиент Python.В блоге DeGizmo есть отличное учебное пособие, включающее пошаговую инструкцию 1050 * по установке обоих.

Как только redis и его pythonклиент установлен, запустить сервер Redis , который вы делаете так:

  • CD в каталог, в котором вы установили Redis ( / usr / local / bin on 'nix, если вы установили через make install );далее

  • введите redis-server в командной строке, затем введите

, теперь вы должны увидеть файл журнала серверав окне вашей оболочки

>>> 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)

В приведенном ниже фрагменте я сохранил график из четырех узлов;каждая строка ниже вызывает hmset на клиенте redis и сохраняет один узел и ребра, подключенные к этому узлу («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'}

Теперь, когда график сохраняется,получить его из базы данных Redis в виде графа NetworkX.

Есть много способов сделать это, ниже сделал это в двух * шагах *:

  1. извлечь данные из базы данных redis в матрица смежности , реализованная в виде двумерного массива NumPy;затем

  2. преобразуйте это непосредственно в граф NetworkX, используя встроенную функцию * Network Network :

, уменьшенную до кода,эти два шага:

>>> 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)]

Когда вы завершаете сеанс redis, вы можете выключить сервер с клиента следующим образом:

>>> r1.shutdown()

redis сохраняет на диск непосредственно перед тем, как он завершает работу.вниз, так что это хороший способ убедиться, что все записи были сохранены.

Так где же база данных redis?Он сохраняется в расположении по умолчанию с именем файла по умолчанию, которое * dump.rdb в вашем домашнем каталоге.

Чтобы изменить это, отредактируйте Файл redis.conf (входит в состав исходного кода redis);перейдите к строке, начинающейся с:

# The filename where to dump the DB
dbfilename dump.rdb

измените dump.rdb на все, что вы пожелаете, но оставьте расширение .rdb на месте.

Далее, чтобы изменить путь к файлу, найдите эту строку в redis.conf:

# Note that you must specify a directory here, not a file name

Строка ниже, которая является каталогом для базы данных redis.Отредактируйте его так, чтобы оно указывало местоположение, которое вы хотите.Сохраните ваши ревизии и переименуйте этот файл, но сохраните расширение .conf.Вы можете сохранить этот файл конфигурации в любом месте, просто укажите полный путь и имя этого пользовательского файла конфигурации в той же строке при запуске сервера Redis:

Так что при следующем запуске сервера Redis выдолжен сделать это так (из приглашения оболочки:

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

$> redis-server /path/to/redis.conf

Наконец, Индекс пакета Python перечисляет пакет специально для реализации базы данных графа в redis. Пакет называется redis-graph и я им не пользовался.

3 голосов
/ 21 марта 2013

Существует реализация NetworkX с поддержкой SQLlite3, называемая Cloudlight.https://www.assembla.com/spaces/cloudlight/wiki/Tutorial

1 голос
/ 16 февраля 2012

Мне было бы интересно увидеть лучший способ использования жесткого диска. В прошлом я делал несколько графиков и сохранял их как файлы .dot. Потом как-то смешались некоторые из них в памяти. Не лучшее решение, хотя.

from random import random
import networkx as nx

def make_graph():
    G=nx.DiGraph()
    N=10
    #make a random graph
    for i in range(N):
        for j in range(i):
            if 4*random()<1:
                G.add_edge(i,j)

    nx.write_dot(G,"savedgraph.dot")
    return G

try:
    G=nx.read_dot("savedgraph.dot")
except:
    G=make_graph() #This will fail if you don't use the same seed but have created the graph in the past. You could use the Singleton design pattern here.
print G.adj
...