Давайте попробуем заняться чем-то немного большим. В первой части мы создали небольшой граф для проверки нашего алгоритма графа разрешения разрешений, и он работал как шарм на дюжине наших узлов и ребер. У меня нет быстрых рук, поэтому вместо того, чтобы набирать граф на миллион узлов, мы создадим генератор графиков и используем пакетный импортер для загрузки его в Neo4j. То, что я хочу создать, — это набор файлов для подачи в пакетный импортер.
Файл node.csv (на самом деле разделенный табуляцией, c находится только для того, чтобы убедиться, что вы обратили внимание) выглядит следующим образом:
unique_id type 9a984170-71cc-0130-92a0-20c9d042eca9 user 9a984450-71cc-0130-92a0-20c9d042eca9 user 9a984550-71cc-0130-92a0-20c9d042eca9 user ... a67769a0-71cc-0130-92a0-20c9d042eca9 doc a6776a40-71cc-0130-92a0-20c9d042eca9 doc
Идентификаторы узла не установлены выше, вместо этого номер строки представляет идентификатор узла, который будет создан на нашем графике. Unique_id и тип являются свойствами узлов. Файл rels.csv также необходим, и он выглядит следующим образом:
start end type flags 1 3003 IS_MEMBER_OF 1 3060 IS_MEMBER_OF 2 3032 IS_MEMBER_OF ... 754949 272265 IS_CHILD_OF 825621 283395 IS_CHILD_OF
В этом случае начальный и конечный столбцы — это идентификаторы узлов, которые связывают эти отношения через тип (обязательно) и некоторые свойства (если есть). Для создания этих файлов я создаю быстрый Rakefile, чтобы помочь мне сделать два набора из них. Один график будет иметь миллион узлов, остальные 10 миллионов, и мы увидим, насколько хорошо Neo4j масштабируется в этом отношении. Приведет ли увеличение в 10 раз количества документов на графике к увеличению производительности нашего алгоритма в 1/10 раз?
require 'neography/tasks' require './neo_generate.rb' namespace :neo4j do task :create do %x[rm *.csv] create_graph end task :create_bigger do %x[rm *.csv] create_bigger_graph end task :load do %x[rm -rf neo4j/data/graph.db] load_graph end end
Методы создания и создания больших графов практически идентичны, единственная реальная разница в том, сколько узлов они будут создавать:
def create_graph create_node_properties create_nodes create_nodes_index create_relationship_properties create_relationships end def create_bigger_graph create_node_properties create_more_nodes create_nodes_index create_relationship_properties create_relationships end
Мы собираемся установить первые 3000 узлов для пользователей, следующие 100 для групп, а следующие 1 миллион для документов.
def create_nodes @nodes = { "user" => { "start" => 1, "end" => 3000}, "group" => { "start" => 3001, "end" => 3100}, "doc" => { "start" => 3101, "end" =>1003100} } @nodes.each{ |node| generate_nodes(node[0], node[1])} end
rake neo4j:create
Файлы CSV, созданные для графа узла 1 миллион, не очень велики:
-rw-r--r-- 1 maxdemarzi staff 47M Mar 18 02:37 documents_index.csv -rw-r--r-- 1 maxdemarzi staff 40M Mar 18 02:37 nodes.csv -rw-r--r-- 1 maxdemarzi staff 259M Mar 18 02:46 rels.csv -rw-r--r-- 1 maxdemarzi staff 140K Mar 18 02:37 users_index.csv
Теперь давайте загрузим их в:
rake neo4j:load java -server -Xmx4G -jar ./batch-import-jar-with-dependencies.jar neo4j/data/graph.db nodes.csv rels.csv node_index Users exact users_index.csv node_index Documents exact documents_index.csv
Это запустит следующее:
Using Existing Configuration File .......... Importing 1003100 Nodes took 2 seconds .................................................................................................... 19508 ms for 10000000 ......... Importing 10976303 Relationships took 21 seconds Importing 3000 Done inserting into Users Index took 0 seconds .......... Importing 1000000 Done inserting into Documents Index took 7 seconds Total import time: 34 seconds
Неплохо для 1 миллиона узлов и 10 миллионов отношений:
rake neo4j:start
Как только мы запустим neo4j и посмотрим на веб-администратора, мы увидим наш график:
Для нашего большего графика мы просто добавляем еще один ноль и создаем 10 миллионов документов.
def create_more_nodes @nodes = { "user" => { "start" => 1, "end" => 3000}, "group" => { "start" => 3001, "end" => 3100}, "doc" => { "start" => 3101, "end" =>10003100} } @nodes.each{ |node| generate_nodes(node[0], node[1])} end
Мы запустим другую задачу rake, которая перезапишет меньшие файлы csv.
rake neo4j:create_bigger
CSV-файлы, созданные для графа 10-миллионного узла, чуть больше, чем для графа 1-миллионного узла:
-rw-r--r-- 1 maxdemarzi staff 476M Mar 19 00:33 documents_index.csv -rw-r--r-- 1 maxdemarzi staff 401M Mar 19 00:31 nodes.csv -rw-r--r-- 1 maxdemarzi staff 510M Mar 19 05:16 rels.csv -rw-r--r-- 1 maxdemarzi staff 140K Mar 19 00:33 users_index.csv
Давайте остановим сервер neo4j и вместо этого загрузим большой граф:
rake neo4j:stop rake neo4j:load java -server -Xmx4G -jar ./batch-import-jar-with-dependencies.jar neo4j/data/graph.db nodes.csv rels.csv node_index Users exact users_index.csv node_index Documents exact documents_index.csv
Интересно, сколько времени это займет
Using Existing Configuration File .................................................................................................... 14052 ms for 10000000 Importing 10003100 Nodes took 14 seconds .................................................................................................... 19242 ms for 10000000 .................................................................................................. Importing 19812750 Relationships took 37 seconds Importing 3000 Done inserting into Users Index took 0 seconds .................................................................................................... 64223 ms for 10000000 Importing 10000000 Done inserting into Documents Index took 64 seconds Total import time: 135 seconds
Это тоже неплохо. Чуть более двух минут
rake neo4j:start
Хорошо. Теперь у нас есть два больших графика, с которыми мы можем играть. Следите за следующей частью, где я добавлю два теста производительности Gatling .