Подтвердить что ты не робот

Решение NoSQL для постоянных графов в масштабе

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

Я огляделся и ничего не мог найти, но я также не мог найти ничего, связанного с возможностью создания простой базы данных MySQL.

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

Спасибо!

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

4b9b3361

Ответ 1

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

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

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

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

redis отлично работает здесь.

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

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

Вам нужно сначала установить Redis и клиент python. Блог DeGizmo имеет превосходный учебник "вверх и вниз", который включает пошаговое руководство по установке обоих.

После того, как 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)

В нижеприведенном фрагменте я сохранил график с четырьмя node; каждая строка ниже вызывает hmset на клиенте redis и сохраняет один node и ребра, связанные с этим node ( "0" = > без края, "1" = > edge). (На практике, конечно, вы должны абстрагировать эти повторяющиеся вызовы в функции, здесь я показываю каждый вызов, потому что, вероятно, это легче понять.)

>>> 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 DB в виде графика NetworkX.

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

  • извлекать данные из базы данных redis в матрицу смежности, реализован как массив 2D NumPy; затем

  • конвертировать это непосредственно в граф 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)]

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

>>> r1.shutdown()

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

Итак, где же redis DB? Он хранится в папке по умолчанию с именем файла по умолчанию, которое 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 Package Index содержит пакет, специально предназначенный для реализации базы данных графа в redis. Пакет называется redis-graph, и я его не использовал.

Ответ 3

Мне было бы интересно увидеть лучший способ использования жесткого диска. В прошлом я сделал несколько графиков и сохранил их как .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