Проблема с суперузлом Neo4j - разветвление
Я новичок в сцене базы данных графиков, изучая Neo4j и изучая Cypher, мы пытаемся смоделировать базу данных графиков, она довольно простая, у нас есть пользователи, и у нас есть фильмы, пользователи могут просматривать фильмы, оценивать фильмы, создавать плейлисты и плейлисты могут иметь фильмы.
Вопрос касается проблемы производительности Super Node. И я приведу кое-что из очень хорошей книги, которую я сейчас читаю - Learning Neo4j Рика Ван Бруггена, так что вот она:
Тогда очень интересная проблема возникает в наборах данных, где некоторые части графа связаны с одним и тем же узлом. Этот узел, также называемый плотным узлом или суперузлом, становится реальной проблемой для обходов графа, поскольку системе управления базой данных графа придется оценивать все связанные отношения с этим узлом, чтобы определить, каким будет следующий шаг. Обход графа.
Решение этой проблемы, предложенное в книге, состоит в том, чтобы иметь мета-узел со 100 подключениями к нему, а 101-е соединение должно быть связано с новым мета-узлом, который связан с предыдущим мета-узлом.
Я видел пост в официальном блоге Neo4j, в котором говорится, что они исправят эту проблему в ближайшем будущем (пост в блоге с января 2013 года) - http://neo4j.com/blog/2013-whats-coming-next-in-neo4j/
Точнее они говорят:
Другой проект, который мы запланировали вокруг "больших данных", - это добавление некоторых конкретных оптимизаций для обработки обходов через узлы с высокой плотностью соединений, имеющих очень большое количество (миллионы) отношений. (Эта проблема иногда упоминается как проблема "суперузлов".)
Каково ваше мнение по этому вопросу? Должны ли мы следовать шаблону разветвления мета-узла или использовать базовые отношения, которые, кажется, используются в каждом учебном пособии? Любые другие предложения?
3 ответа
Это хороший вопрос. Это не совсем ответ, но почему мы не можем обсуждать это здесь? Технически, я думаю, я должен пометить ваш вопрос как "в первую очередь основанный на мнении", так как вы явно запрашиваете мнения, но я думаю, что это стоит обсудить.
Скучный, но честный ответ: всегда зависит от ваших шаблонов запросов. Не зная, какие типы запросов вы собираетесь выполнить для этой структуры данных, на самом деле нет способа узнать "лучший" подход.
Супер-узлы - это проблемы и в других областях. Графические базы данных иногда очень трудно масштабировать, так как данные в них трудно разделить. Если бы это была реляционная база данных, мы могли бы разделиться вертикально или горизонтально. В графической БД, когда у вас есть супер-узлы, все "близко" ко всему остальному. (Аляскинскому фермеру нравится Леди Гага, равно как и нью-йоркскому банкиру). Больше чем просто скорость обхода графа, суперузлы являются большой проблемой для всех видов масштабируемости.
Предложение Рика сводится к тому, чтобы побудить вас создать "подкластеры" или "разделы" суперузла. Для определенных шаблонов запросов это может быть хорошей идеей, и я не сбиваю с толку эту идею, но думаю, что здесь скрыто понятие стратегии кластеризации. Сколько мета-узлов вы назначаете? Сколько максимальных ссылок на мета-узел? Как вы решили назначить этого пользователя этому метаузлу (а не другому)? В зависимости от ваших запросов, на эти вопросы будет очень сложно ответить, трудно реализовать правильно, или и то, и другое.
Другой (но концептуально очень похожий) подход состоит в том, чтобы клонировать Lady Gaga около тысячи раз, дублировать ее данные и поддерживать их синхронизацию между узлами, а затем утверждать связку "такие же как" между клонами. Это ничем не отличается от "мета" подхода, но имеет то преимущество, что копирует данные Lady Gaga в клон, а узел "Meta" не просто тупой заполнитель для навигации. Большинство из тех же проблем применимы, хотя.
Вот и другое предложение: у вас здесь есть масштабная проблема отображения многих ко многим. Вполне возможно, что если это действительно огромная проблема для вас, вам лучше разбить ее на одну реляционную таблицу с двумя столбцами. (from_id, to_id)
каждый из которых ссылается на идентификатор узла neo4j. Тогда у вас может быть гибридная система, которая в основном графическая (но с некоторыми исключениями). Здесь много компромиссов; Конечно, вы не могли бы пройти через этот rel в cypher, но он гораздо лучше масштабировался и делился, и запросы на конкретный rel, вероятно, были бы намного быстрее.
Одно общее замечание здесь: говорим ли мы о реляционных, графических, документах, K/V-базах данных или о чем-то еще - когда базы данных становятся действительно большими и требования к производительности становятся действительно интенсивными, почти неизбежно, что люди в конечном итоге получают какие-то своего рода гибридное решение с более чем одним видом СУБД. Это из-за неизбежной реальности, что все базы данных хороши в одних вещах, а не хороши в других. Так что если вам нужна система, которая хороша почти для всего, вам придется использовать более одного вида базы данных.:)
Вероятно, neo4j может многое сделать для оптимизации в этих случаях, но мне кажется, что системе потребуются некоторые подсказки по шаблонам доступа, чтобы сделать действительно хорошую работу в этом. Из 2 000 000 существующих отношений, как к конечным точкам лучший кластер? Являются ли более старые отношения важнее новых или наоборот?
Число рейнольдса блог Neo4j, поддержка плотных узлов должна быть улучшена в Neo4j 2.1 (и выше), см. также http://neo4j.com/blog/neo4j-2-1-graph-etl/
(отказ от ответственности: не ответ, но некоторое обсуждение)
В блоге neo4j 2013 года вы упомянули ссылки на этот коммит github, где обсуждается предполагаемая область действия проблемы и ее решение. Подводя итог, это не касается общего supernode
вопрос. Вместо этого он облегчает проблему, когда среди множества типов отношений (и направлений) supernode
имеет, некоторые из типов (направлений) имеют непропорционально меньше краев, чем другие. Двигатель способен фильтровать по типам и направлениям.
Более общим решением является vertex centric
подход от Titan ( /questions/22830580/indeksyi-orientirovannyie-na-vershinyi-titan-i-metki-neo4j/22830608#22830608), который сортирует ребра по одному или по совокупности свойств, приводит к эффективности поиска O(log(E)), где E - количество ребер в / из supernode
,
Neo4j имеет понятие индекса по отношениям. В отличие от vertex centric
Подход Титана, индекс является глобальным. Тем не менее, индекс отношений является устаревшим в Neo4j. Это обсуждается в другом потоке stackru.
Еще одна проблема с Supernode
проблема хранения, которая приводит к проблеме хранения и стоимости ввода-вывода.