Хранение промежуточных значений в графе - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь усвоить лучшие практики представления линии данных в виде графа (в частности, DAG) и сохранения значений в нечто вроде neo4j.

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

База данных графа не будет отвечать за сами вычисления, а только за представление входных данных длякаждая чистая функция представлена ​​узлом.Давайте предположим, что некоторые узлы являются вычислительно дорогими для вычисления, поэтому сохранение промежуточных значений имеет смысл.При изменении любого значения в графике дочерние узлы могут быть помечены как устаревшие для некоторого процесса, чтобы пересчитать их асинхронно.

Для тех, кто видел эту архитектуру, каковы некоторые передовые практики, связанные с этим подходом, и представляет собой графбаза данных правильное место для хранения этих данных зависимостей?

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Да, графическая база данных структурно отражает DAG и является идеальным местом для хранения, как вы описали.Что касается лучших практик, это зависит от того, какая база данных.Neo4j является направленным графом свойств, и вы можете назначать свойства и значения узлам и отношениям («вершины» и «ребра» в графе-говорящем).

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

Каждое отношениепредставляет сообщение от одной функции к другой.У вас есть выбор, и какой путь вы выберете, зависит от запросов.Основываясь на вашем описании, я мог бы сохранить значения входных и выходных параметров в функции.Но вы также можете описать их как полезную нагрузку отношений.Последнее является более точным представлением конвейера, но потребует некоторой несогласованности, если вам потребуется сохранить ваш конечный результат.

0 голосов
/ 20 мая 2018

Когда мне приходилось наматывать что-то подобное, я добавлял столбец dateUpdated в свою базу данных, чтобы сделать это очевидным при обновлении.Затем вы можете просмотреть список дочерних узлов, чтобы убедиться, что дочерний элемент всегда обновлялся после его родительского элемента.Я предполагаю:

  • У вас всегда есть DAG
  • Топология не меняется

тогда вы можете один раз разбить графикв непересекающиеся сегменты (один раз), внутри каждого сегмента - соберите все корни в кучу и обработайте каждый корень и его дочерние элементы, обновив столбец dataUpdated по мере необходимости обновления узла.

Если вы хотитесохраняйте полную историю, делайте INSERT, когда вы «обновляете» dateUpdated (скопируйте все, что не изменилось, установите dateUpdated = NOW.) Если вы хотите представлять только текущее обработанное состояние, выполните UPDATE.

Одна из проблем, связанных с выполнением UPDATE, заключается в том, что если у вас есть другие процессы, читающие эти данные, у вас может быть состояние гонки, при котором вы обновляете родителя, читаете неотобновленный потомок и получаете устаревшее значение.Другой подход заключается в том, что вы фактически не возвращаете значение до тех пор, пока все дочерние элементы не обновят времена, превышающие их родительские значения (или какие-либо входные данные в вашей функции.) Если вы выполняете INSERT, то дочерние узлы не будут существовать, пока ониобрабатываются, но вам придется обрабатывать случай, когда вы запрашиваете узел, который не существует из-за перестроения, в отличие от случая, когда вы запрашиваете узел, который просто не существует.

Еслиизменения топологии, тогда вам, вероятно, потребуется применить ограничение DAG, а затем выполнять разбиение каждый раз.

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

Ядовольно хорошо в трех из четырех добавленных тэгов, но я ничего не знаю о neo4j, так что извините, если там уже есть структура данных для этого.Также всегда кажется, что должна быть какая-то система баз данных, которая может хранить данные по мере их изменения при разных ревизиях, но я всегда использую dateUpdated с MySQL ...

...