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).
Глобальные мутации графа

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. Таким образом, вычисления существуют вдоль данных в кластере.
