Apache TinkerPop

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 15:48, 22 февраля 2019.
Apache TinkerPop
Tinkerpop-logo.png
Разработчики: Apache Software Foundation
Постоянный выпуск: 3.4.0[Источник 1] / 2 January 2019 года; 2 years ago (2019-01-02)
Операционная система: Unix-системы
Тип ПО: Graph computing
Лицензия: Apache License 2.0[Источник 2]
Веб-сайт tinkerpop.apache.org

Apache TinkerPop ™ - это открытая среда графовых вычислений с открытым исходным кодом, распространяемая по коммерческой лицензии Apache2.

Особенности

Когда система данных поддерживает TinkerPop, ее пользователи могут моделировать свой домен в виде графа и анализировать этот граф с помощью языка обхода графа Gremlin. Кроме того, все системы с поддержкой TinkerPop интегрируются друг с другом, что позволяет им легко расширять свои возможности, а также позволяет пользователям выбирать подходящую технологию графов для своего приложения. Иногда приложение лучше обслуживать базой данных транзакционного графа. Иногда с этим справится база данных распределенных графов с несколькими машинами. Или, возможно, приложению требуется база данных распределенных графов для запросов в реальном времени и параллельно процессор больших (графовых) данных для пакетной аналитики. Какими бы ни были требования приложения, существует графовая система с поддержкой TinkerPop для удовлетворения его потребностей. Gremlin помогает ориентироваться в вершинах и ребрах графа. По сути, он является языком запросов для построения графовых баз данных, как SQL является языком запросов к реляционным базам данных. Чтобы сообщить Gremlin, как он должен «пройти» по графику (то есть, что пользователь хочет, чтобы запрос делал), нужен способ предоставить ему команды на понятном ему языке - и, конечно, этот язык называется «Gremlin». Для этой задачи понадобится один из самых важных инструментов TinkerPop: Консоль Gremlin.

Gremlin

Gremlin[Источник 3] - это язык обхода графов Apache TinkerPop. Gremlin - это функциональный язык потоков данных, который позволяет пользователям кратко выражать сложные обходы (или запросы) графа свойств своего приложения. Каждый обход состоит из последовательности (потенциально вложенных) шагов. Шаг выполняет элементарную операцию над потоком данных. Каждый шаг - это либо шаг карты (преобразование объектов в потоке), либо шаг фильтра (удаление объектов из потока), либо шаг побочного эффекта (вычисление статистики о потоке). Библиотека шагов Gremlin расширяет эти 3 фундаментальных операции, чтобы предоставить пользователям обширную коллекцию шагов, которые они могут составить, чтобы задать любой возможный вопрос о своих данных для Gremlin.

Язык был разработан в соответствии с философией "пиши один раз, используй где угодно". Это означает, что не только все графовые системы с поддержкой TinkerPop могут выполнять обходы Gremlin, но и каждый обход Gremlin может оцениваться как запрос к базе данных в реальном времени или как пакетный аналитический запрос. Первый известен как онлайновый транзакционный процесс (OLTP), а второй - как онлайн-аналитический процесс (OLAP). Эта универсальность стала возможной благодаря машине обхода Гремлин. Эта распределенная виртуальная машина на основе графов понимает, как координировать выполнение обхода графов с несколькими машинами. Кроме того, выполнение может быть не только OLTP или OLAP, но также возможно, что некоторые подмножества обхода выполняют OLTP, а другие - через OLAP. Преимущество заключается в том, что пользователю не нужно изучать как язык запросов к базе данных, так и язык аналитики BigData для конкретного домена (например, Spark DSL, MapReduce и т. д.). Gremlin - это все, что требуется для построения графового приложения, потому что машина обхода Gremlin будет обрабатывать все остальное.

Анатомия Gremlin

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

Составные части обхода Gremlin могут быть идентифицированы из следующего кода:

gremlin> g.V().
           has('person', 'name', within('marko', 'josh')).
           outE().
           groupCount().
             by(label()).next()
==>created=3
==>knows=2
gremlin> g.V()
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]

g.V () - Это практически каждый обход, который встречается в документации, сообщениях в блогах или примерах.

Хотя хорошо известно, что g.V () возвращает список всех вершин в графе, технические основы этого вездесущего утверждения могут быть менее надежными. Прежде всего, g является переменной. Это мог быть x, y или что-то еще, но по соглашению обычно используют g. Этот g является GraphTraversalSource и порождает экземпляры GraphTraversal с начальными шагами. V () является одним из таких начальных шагов, но есть и другие, такие как E, для получения всех ребер графа. Важной частью является то, что эти начальные шаги начинают обход.

В дополнение к доступным доступным начальным шагам, GraphTraversalSource также содержит параметры конфигурации (возможно, представить их как предварительные инструкции для Gremlin), которые будут использоваться для выполнения обхода. Методы, которые позволяют устанавливать эти конфигурации, начинаются со слова «с». Вот несколько примеров для рассмотрения:

g.withStrategies(SubgraphStrategy.build().vertices(hasLabel('person')).create()).  //1
  V().has('name','marko').out().values('name')
g.withSack(1.0f).V().sack()                                                        //2
g.withComputer().V().pageRank()                                                    //3
  1. Определить стратегию обхода
  2. Определить начальное значение sack
  3. Определить GraphComputer для использования совместно с VertexProgram для обходов на основе OLAP - например, см. Spark

GraphTraversal

GraphTraversal создается из начальных шагов GraphTraversalSource. GraphTraversal содержит шаги, которые составляют язык Gremlin. Каждый шаг возвращает GraphTraversal, так что эти шаги можно легко объединить в цепочку. Возвращаясь к примеру сверху:

gremlin> g.V().
           has('person', 'name', within('marko', 'josh')).
           outE().
           groupCount().
             by(label()).next()
==>created=3
==>knows=2

Компоненты GraphTraversal представлены шагами has (), outE () и groupCount (). Ключом к чтению этого Gremlin является понимание того, что выход одного шага становится входом для следующего. Поэтому, если рассмотреть начальный шаг V (), он возвращает вершины в графе, входные данные для has () будут вершинами. Шаг has () - это шаг фильтрации, который будет принимать переданные в него вершины и блокировать все вершины, которые не соответствуют указанным критериям. В этом случае это означает, что выходные данные шага has () - это вершины, имеющие метку «person» и значение свойства «name» для «josh» или «marko».

Учитывая, что известен результат has (), также известны входные данные для outE (). outE () является навигационным шагом, поскольку он позволяет перемещаться по графику. В этом случае outE () говорит Gremlin принять входящие вершины "marko" и "josh" и пересечь их исходящие ребра в качестве выходных данных.

Теперь, когда ясно, что выход outE () является ребром, известно о входных данных для groupCount () - ребер. На этом этапе просто стоит отметить, что выходные данные groupCount () являются картами, и если за ним следует шаг Gremlin, то входными данными этого шага будет карта.

Терминальный шаг

Терминальные шаги отличаются от шагов GraphTraversal тем, что такие шаги не возвращают экземпляр GraphTraversal, а вместо этого возвращают результат GraphTraversal. В случае примера next () является конечным шагом и возвращает карту, созданную в groupCount () - шаге. Другие примеры конечных шагов включают в себя: hasNext (), toList () и iterate (). Без терминальных шагов не будет результата. Есть только GraphTraversal.

Императивные и декларативные обходы

Обход может быть написан либо императивным (процедурным), декларативным (описательным) способом, либо гибридным способом, содержащим как императивные, так и декларативные аспекты. Обязательный обход сообщает путникам, как действовать на каждом этапе обхода. Например, императивный обход справа сначала помещает путника в вершину. Затем этот путник разделяется на кусочки-путники, которые не являются самим Gremlin. Затем, путники идут к менеджерам этих кусочков, чтобы в конечном итоге быть сгруппированы в распределение имен менеджера. Этот обход является императивным в том смысле, что он говорит путникам «иди сюда, а потом иди туда» явным, процедурным образом.

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

Пользователь может написать свои обходы любым способом по своему выбору. Однако, в конечном счете, когда их обход компилируется, и в зависимости от базового механизма выполнения (то есть базы данных графиков OLTP или процессора графиков OLAP), обход пользователя переписывается набором стратегий обхода, которые делают все возможное, чтобы определить наиболее оптимальное выполнение. Происходит планирование на основе понимания затрат на доступ к данным графа, а также уникальных возможностей базовых систем данных (например, извлекать вершину Gremlin из индекса "name" базы данных графа). Gremlin был разработан, чтобы предоставить пользователям гибкость в том, как они выражают свои запросы, и гибкость поставщиков графовой системы в том, как эффективно оценивать обходы в их системе данных с поддержкой TinkerPop.

Вложение языка-хоста

Классические языки запросов к базам данных, такие как SQL, задумывались как принципиально отличающиеся от языков программирования, которые в конечном итоге использовали бы их в производственных условиях. По этой причине классические базы данных требуют, чтобы разработчик кодировал как на своем родном языке программирования, так и на соответствующем языке запросов базы данных. Можно привести аргумент, что разница между «языками запросов» и «языками программирования» не так велика, как нас учат верить. Gremlin объединяет это разделение, потому что обходы могут быть написаны на любом языке программирования, который поддерживает составление функций и вложение (которое поддерживает каждый основной язык программирования). Таким образом, обходы пользователя Gremlin записываются вместе с кодом его приложения и получают преимущества от возможностей, предоставляемых основным языком и его инструментами (например, проверка типа, подсветка синтаксиса, завершение точек и т. Д.). Существуют различные варианты языка Gremlin, в том числе: Gremlin-Java, Gremlin-Groovy, Gremlin-Python, Gremlin-Scala и т. д.

Первый пример ниже показывает простой класс Java. Обход Gremlin выражен в Gremlin-Java и, следовательно, является частью кода приложения пользователя. Разработчику не нужно создавать представление String своего запроса на (еще одном) другом языке, чтобы в конечном итоге передать эту String в графовую вычислительную систему и вернуть набор результатов. Вместо этого обходы встроены в основной язык программирования пользователя и находятся наравне со всем другим кодом приложения. С Gremlin пользователям не приходится иметь дело с неловкостью, показанной во втором примере ниже, который является распространенным анти-паттерном, встречающимся во всей отрасли.

//Пример 1
public class GremlinTinkerPopExample {
  public void run(String name, String property) {

    Graph graph = GraphFactory.open(...);
    GraphTraversalSource g = graph.traversal();

    double avg = g.V().has("name",name).
                   out("knows").out("created").
                   values(property).mean().next();

    System.out.println("Average rating: " + avg);
  }
}
//Пример 2
public class SqlJdbcExample {
  public void run(String name, String property) {

    Connection connection = DriverManager.getConnection(...)
    Statement statement = connection.createStatement();
    ResultSet result = statement.executeQuery(
      "SELECT AVG(pr." + property + ") as AVERAGE FROM PERSONS p1" +
        "INNER JOIN KNOWS k ON k.person1 = p1.id " +
        "INNER JOIN PERSONS p2 ON p2.id = k.person2 " +
        "INNER JOIN CREATED c ON c.person = p2.id " +
        "INNER JOIN PROJECTS pr ON pr.id = c.project " +
          "WHERE p.name = '" + name + "');

    System.out.println("Average rating: " + result.next().getDouble("AVERAGE")
  }
}

Установка

Скачать[Источник 4] консоль, распаковать ее и запустить:

$ unzip apache-tinkerpop-gremlin-console-3.4.0-bin.zip
$ cd apache-tinkerpop-gremlin-console-3.4.0
$ bin/gremlin.sh

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin>

Для первого графа лучше использовать граф «Modern», который можно увидеть на рисунке 1:

Рисунок 1 - Граф «Modern»

Его можно создать в консоли следующим образом:

gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]

Первая команда создает экземпляр графа с именем graph, который, таким образом, предоставляет ссылку на данные, которые нужно пройти через Gremlin. К сожалению, просто наличие графа не обеспечивает достаточно контекста, чтобы выполнить работу. Также нужно что-то, называемое TraversalSource, которое генерируется второй командой. TraversalSource предоставляет Gremlin дополнительную информацию (такую как применяемые стратегии обхода и используемый механизм обхода), которая дает ему руководство о том, как выполнить свое путешествие по графу.

Есть несколько способов создать TraversalSource. В приведенном выше примере используется встроенный стиль, и этот подход ограничен языками, использующими виртуальную машину Java. С доступным ресурсом TraversalSource теперь можно попросить Gremlin пройти по графу:

gremlin> g.V() //1\
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
gremlin> g.V(1) //2\
==>v[1]
gremlin> g.V(1).values('name') //3\
==>marko
gremlin> g.V(1).outE('knows') //4\
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.V(1).outE('knows').inV().values('name') //5\
==>vadas
==>josh
gremlin> g.V(1).out('knows').values('name') //6\
==>vadas
==>josh
gremlin> g.V(1).out('knows').has('age', gt(30)).values('name') //7\
==>josh
  1. Получить все вершины в графе..
  2. Получить вершину с уникальным идентификатором «1».
  3. Получить значение свойства name в вершине с уникальным идентификатором «1».
  4. Получить ребра с меткой «knows» для вершины с уникальным идентификатором «1».
  5. Получить имена людей, у которых вершина с уникальным идентификатором «1» «knows».
  6. Обратить внимание, что когда кто-то использует outE (). InV (), как показано в предыдущей команде, его можно сократить до just out () (аналогично inE (). InV () и in для входящих ребер).
  7. Получить имена людей, у которых вершина "1" имеет "knows" и кто старше 30 лет.

Это лишь малая часть того, что можно узнать о TinkerPop, но она призвана помочь в понимании работы этого фреймворка.

Источники

  1. Download Apache TinkerPop™// tinkerpop.apache.org [2018-2018]. Дата обновления: 05.08.2018. URL: http://tinkerpop.apache.org/downloads.html (дата обращения: 02.02.2019).
  2. Framework distributed under the commercial friendly Apache2 license// tinkerpop.apache.org/ [2018-2018]. Дата обновления: 05.08.2018. URL: http://tinkerpop.apache.org/ (дата обращения: 02.02.2019).
  3. The Gremlin Graph Traversal Machine and Language// tinkerpop.apache.org/ [2018-2018]. Дата обновления: 27.12.2018. URL: http://tinkerpop.apache.org/gremlin.html (дата обращения: 02.02.2019).
  4. Getting Started// tinkerpop.apache.org [2018-2018]. Дата обновления: 05.08.2018. URL: http://tinkerpop.apache.org/docs/current/tutorials/getting-started/ (дата обращения: 02.02.2019).