#scala #gremlin #janusgraph
#scala #gremlin #janusgraph
Вопрос:
Я пытаюсь добавить ребро между двумя вершинами, используя платформу gremlin scala, подключенную к удаленному серверу JanusGraph. Пока это ребро создается, я все еще получаю «org.apache.tinkerpop.shaded.kryo.Исключение KryoException: java.lang.Исключение ошибки NegativeArraySizeException»
Ребро и вершины создаются, но ошибка все еще выдается, и я не могу ее перехватить. Я использую JanusGraph 0.3.1 и пробовал с разными версиями scala gremlin (3.3, 3.4), все они приводят к одной и той же ошибке.
val serializer = new GryoMessageSerializerV3d0(GryoMapper.build.addRegistry(TinkerIoRegistryV3d0.instance))
val cluster = Cluster.build.addContactPoint("localhost").port(8182).serializer(serializer).create
implicit val graph: ScalaGraph = EmptyGraph.instance.asScala.configure(_.withRemote(DriverRemoteConnection.using(cluster)))
val Founded = Key[String]("founded")
val Distance = Key[Int]("distance")
// create labelled vertex
val paris = graph "Paris"
// create vertex with typed properties
val london = graph ("London", Founded -> "43 AD")
// create labelled edges
paris --- ("OneWayRoad", Distance -> 495) --> london
cluster.close()
Сообщение об ошибке, выданное во время выполнения
15:34:02.704 [gremlin-driver-loop-1] WARN o.a.t.g.driver.MessageSerializer - Response [PooledUnsafeDirectByteBuf(ridx: 92, widx: 92, cap: 92)] could not be deserialized by org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV3d0.
org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
at org.apache.tinkerpop.shaded.kryo.serializers.ObjectField.read(ObjectField.java:144)
at org.apache.tinkerpop.shaded.kryo.serializers.FieldSerializer.read(FieldSerializer.java:557)
...
Caused by: java.lang.NegativeArraySizeException: null
at org.apache.tinkerpop.shaded.kryo.io.Input.readBytes(Input.java:325)
[...]
15:34:02.705 [gremlin-driver-loop-1] ERROR o.a.t.g.d.Handler$GremlinResponseHandler - Could not process the response
io.netty.handler.codec.DecoderException: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)
[...]
Caused by: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
at org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV3d0.deserializeResponse(AbstractGryoMessageSerializerV3d0.java:159)
[...]
Caused by: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
at org.apache.tinkerpop.shaded.kryo.serializers.ObjectField.read(ObjectField.java:144)
[...]
Caused by: java.lang.NegativeArraySizeException: null
at org.apache.tinkerpop.shaded.kryo.io.Input.readBytes(Input.java:325)
[...]
Отладчик показывает мне, что ошибка выдается при создании ребра. Используя
val edge = g.V(paris).as("a").V(london).addE("test").iterate()
приводит к той же ошибке.
Вот мой конфигурационный файл gremlin-server.yaml
host: 0.0.0.0
port: 8182
scriptEvaluationTimeout: 180000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphs: {
graph: conf/gremlin-server/janusgraph-cql-es-server.properties,
ConfigurationManagementGraph: conf/janusgraph-cql-configurationgraph.properties
}
scriptEngines: {
gremlin-groovy: {
plugins: { org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]},
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/empty-sample.groovy]}}}}
serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
# Older serialization versions for backwards compatibility:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
processors:
- { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
- { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
consoleReporter: {enabled: true, interval: 180000},
csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
jmxReporter: {enabled: true},
slf4jReporter: {enabled: true, interval: 180000},
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
graphiteReporter: {enabled: false, interval: 180000}}
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferLowWaterMark: 32768
writeBufferHighWaterMark: 65536
Ошибка не появляется при работе без использования удаленного сервера:
implicit val graph: ScalaGraph = EmptyGraph.instance
работает нормально.
Ответ №1:
Эта проблема обычно указывает на проблему совместимости с Gryo, которая обычно возникает при смешивании версий TinkerPop. По большей части Gryo имеет тенденцию быть обратно совместимым между версиями, таким образом, Gryo 1.0 из 3.3.3 будет работать с 3.3.4, но бывают случаи, когда это не всегда верно (например, обнаружена ошибка в ядре формата, и необходимо кардинальное изменение).)
TinkerPop рекомендует при использовании Gryo согласовать версию TinkerPop на сервере с версией клиента. Итак, JanusGraph 0.3.1 использует TinkerPop 3.3.3, поэтому ваша версия Gremlin Scala должна быть 3.3.3.x (я почти уверен, что Gremlin Scala привязывает свои первые три номера версий к номерам TinkerPop). Кажется, вы уже пробовали это, поэтому давайте рассмотрим вашу конфигурацию.
Я отмечаю, что вы добавили TinkerIoRegistryV3d0
но поскольку вы используете JanusGraph, вам также может потребоваться добавить их пользовательский IoRegistry
:
GryoMessageSerializerV3d0(GryoMapper.build.addRegistry(JanusGraphIoRegistry.getInstance()))
Вы можете добавить TinkerIoRegistryV3d0
, если этого требует ваш вариант использования — обычно это полезно только для возврата подграфов. Если ничто из этого не устраняет проблему, то моим единственным предложением было бы значительно упростить: удалите все конфигурации сериализатора из конфигурации сервера Gremlin, кроме той, которую вы используете, убедитесь, что вы можете подключиться к ней с помощью нескольких простых сценариев, настраивающих ваш драйвер, используя только консоль Gremlin, и обратите внимание на то, что это за конфигурация, чтобы заставить соединение работать, чтобы вы могли перенести конфигурацию в Gremlin Scala.
Я вижу, что в настоящее время вы изолировали проблему от:
val edge = g.V(paris).as("a").V(london).addE("test").iterate()
Обратите внимание, что этот код не делает именно то, что, я думаю, вы хотите по нескольким причинам:
- Если вы хотите вернуть ребро, вам нужно
next()
а неiterate()
- Это не добавляет ребро между «парижем» и «Лондоном» — это добавляет самоссылающееся ребро к «лондону». Вам нужно указать
from()
илиto()
послеaddE()
.
Я надеюсь, что что-то там поможет.