script
-Ступенно в Фавна Gremlin позволяет выполнение произвольного сценария Gremlin против всех вершин в графе Faunus. Эта простая идея имеет интересные последствия для распределенных графовых вычислений на основе Gremlin. Например, можно оценить скрипт Gremlin на каждой вершине в исходном графе (например, Titan) параллельно, сохраняя локальность данных / процессов. В этом разделе будут обсуждаться следующие два варианта использования.
- Глобальные мутации графа : параллельное обновление вершин / ребер в кластере Титана при произвольном вычислении.
- Алгоритмы глобального графа : распространять информацию на произвольные глубины в кластере Титан, чтобы вычислить некоторый алгоритм в параллельной манере.
script
-Ступенно требует , чтобы скрипт EXIST Gremlin в HDFS и имеет следующие определения методов:
-
setup(String... args)
: вызывается один раз за маппер во времяMap.setup()
-
map(FaunusVertex v, String... args)
: вызывается для каждого ключа / значенияMap.map()
с тем,v
чтобы бытьFaunusVertex
-
cleanup(String... args)
: вызывается один раз за маппер во времяMap.cleanup()
Наконец, script
-ступенно имеет метод подписи: FaunusPipeline.script(String scriptUri, String... args)
.
Глобальные мутации графа
Один из способов сделать глобальные мутации графа с Faunus — это использовать средство, InputFormat
которое считывает граф из базы данных графа (например, Titan и / или Rexster ), а затем мутировать представление Faunus этого графа в HDFS на различных этапах Gremlin / Faunus. Наконец, удалите исходный граф в базе данных и загрузите новый мутированный граф Фаунуса, используя соответствующий OutputFormat
. Проблема этого метода заключается в том, что он требует очистки и повторной загрузки базы данных графов, что для производственных систем 24 × 7 не является разумным требованием.
Другим способом параллельного обновления графа является использование script
-step для обеспечения в реальном времени распределенных массовых обновлений исходного графа в самой базе данных графа. Простой пример объясняет идею. Предположим, что набор данных Graph of the Gods (см. Визуализацию ) в Titan / Cassandra (или Titan / HBase) совмещен с узлами данных Hadoop и трекерами задач. Далее предположим, что вызывается следующий скрипт Gremlin / Groovy FathersNames.groovy
(распространяется с Faunus at data/FathersNames.groovy
). Этот скрипт добавит новое свойство к каждой вызванной вершине fathersName
. Значением этого свойства является имя отца вершины (если у вершины есть father
). В качестве побочного эффекта от Faunus String
указывается имя добавленного отца.
// FathersName.groovy def g // create a Titan database connection that exists for the life of the mapper def setup(args) { conf = new org.apache.commons.configuration.BaseConfiguration() conf.setProperty('storage.backend', args[0]) conf.setProperty('storage.hostname', 'localhost') // co-located Hadoop ensures local Titan machine has vertex g = com.thinkaurelius.titan.core.TitanFactory.open(conf) } // process each Faunus vertex // - find the corresponding Titan vertex as it shares the same id with the Faunus vertex // - update the Titan vertex given some Gremlin traversal over Titan def map(v, args) { u = g.v(v.id) // the Faunus vertex id is the same as the original Titan vertex id pipe = u.out('father').name if (pipe.hasNext()) u.fathersName = pipe.next(); u.name + "'s father's name is " + u.fathersName } // close the Titan database connection def cleanup(args) { g.shutdown() }
Поместите этот FathersName.groovy
файл в HDFS, используя Gremlin.
gremlin> hdfs.copyFromLocal('data/FathersNames.groovy', 'FathersNames.groovy') ==>null
С этим файлом в HDFS можно выполнить следующий обход Gremlin / Faunus. Для всех вершин полубога и бога в графе, добавьте имя отца вершины, если оно существует.
g.V.has('type','demigod','god').script('FathersName.groovy','cassandrathrift')
Graph богов в Titan служит вкладом в работу Faunus. NoOpOutputFormat
используется, поскольку нет необходимости писать график, поскольку оригинальное представление графа Titan изменяется.
gremlin> g = FaunusFactory.open('bin/titan-cassandra-input.properties') ==>faunusgraph[titancassandrainputformat->graphsonoutputformat] gremlin> g.setGraphOutputFormat(NoOpOutputFormat.class) ==>null gremlin> g.V.has('type','demigod','god').script('FathersName.groovy','cassandrathrift') 13/03/06 18:21:43 INFO mapreduce.FaunusCompiler: Compiled to 1 MapReduce job(s) 13/03/06 18:21:43 INFO mapreduce.FaunusCompiler: Executing job 1 out of 1: MapSequence[com.thinkaurelius.faunus.mapreduce.transform.VerticesMap.Map, com.thinkaurelius.faunus.mapreduce.filter.PropertyFilterMap.Map, com.thinkaurelius.faunus.mapreduce.util.ScriptMap.Map] 13/03/06 18:21:43 INFO mapreduce.FaunusCompiler: Job data location: output/job-0 13/03/06 18:21:43 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same. 13/03/06 18:21:44 INFO mapred.JobClient: Running job: job_201303061253_0077 13/03/06 18:21:45 INFO mapred.JobClient: map 0% reduce 0% 13/03/06 18:21:53 INFO mapred.JobClient: map 50% reduce 0% ... ==>hercules's father's name is jupiter ==>pluto's father's name is null ==>jupiter's father's name is saturn ==>neptune's father's name is null
Глядя на исходный граф в Титане, у тех вершин, которые имеют отцов, появилось новое fathersName
свойство.
gremlin> g.V.transform("{it.name + ' ' + it.fathersName}") ... 13/03/06 18:25:40 INFO mapred.JobClient: Running job: job_201303061253_0078 13/03/06 18:25:41 INFO mapred.JobClient: map 0% reduce 0% ... ==>tartarus null ==>alcmene null ==>sea null ==>hydra null ==>hercules jupiter ==>cerberus null ==>pluto null ==>saturn null ==>sky null ==>jupiter saturn ==>neptune null ==>nemean null
В приведенном выше примере Фаунус выполняет функцию фильтрации вершин, подлежащих обработке, до полубогов и богов, а затем предоставляет сценарию идентификатор вершины Титана, который в конечном итоге будет вычислен. Одна из важных идей, которую следует извлечь из этого примера, заключается в том, что, хотя Фаунус связан с вершиной (шаг может действовать только на вершине и ее падающих ребрах), при script
наличии соединения с Титаном можно совершать произвольные прогулки произвольной глубины на один шаг и, таким образом, позволяет более выразительные объемные / глобальные вычисления на Титане.
Типичные случаи использования массовых мутаций описаны ниже:
- «Нам нужно преобразовать все
String
даты вLong
даты». - «Для всех вершин людей давайте добавим новое ребро с именем
grandfather
, которое вычисляется поfather
*father
ребрам». - «Нам нужно удалить всех пользователей и все их соответствующие данные (закачки, папки, данные о дружбе и т. Д.), Которые не вошли в систему за последние 2 года».
Наконец, обратите внимание, что localhost
используется в качестве storage.hostname
титана. Если кластер Hadoop находится в одном месте с кластером Cassandra (или HBase), то localhost
это местоположение FaunusVertex
и TitanVertex
. Таким образом, вычисления существуют вдоль данных в кластере.