KryoException: буфер слишком мал

Я использую Gremlin 3.0.2 вместе с Titan 1.0.0.

Запрос, который я отправляю на сервер Gremlin, возвращает список узлов и их свойств. По сути, это список элементов, подобных следующему:

[coverurl:[https://lh3.googleusercontent.com/RYb-duneinq8ClWVLVKknkIx1jOKm64LjreziFApEnkKME8j9tHNDRi9NMA6PK4PTXO7], appname:[Slack], pkgid:[com.Slack]]

В одном случае запрос вернет 38 элементов, подобных приведенному выше, и все в порядке. В другом случае список будет содержать 56 таких элементов, и я получаю следующее исключение:

WARN  org.apache.tinkerpop.gremlin.driver.MessageSerializer  - Response [PooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 0)] could not be deserialized by org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0.
ERROR org.apache.tinkerpop.gremlin.driver.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: Buffer too small: capacity: 0, required: 1
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)

Эта проблема обсуждалась здесь в прошлом году. Однако для разных версий Титана и для записи данных в Титан вместо чтения, как здесь.

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

В любом случае - объем данных, которые я получаю, довольно мал (вероятно, чуть более 8500 байт). Я удивлен, что это исключение вообще выбрасывается?


person Christoph Möbius    schedule 25.05.2016    source источник


Ответы (1)


Titan 1.0 основан на TinkerPop 3.0.1.. Вы строите Титан самостоятельно?

TINKERPOP-817 содержит исправление, позволяющее настраивать параметр bufferSize. Как упомянул Стивен в комментариях:

размер крио-буфера по умолчанию был равен 4096, и они выдавали исключение «Буфер слишком мал»

Исправление вошло в TinkerPop 3.0.2 и задокументировано здесь.

Чтобы использовать это, вам необходимо обновить свой сервер Titan для работы с TinkerPop 3.0.2, и было бы лучше перекомпилировать из исходного кода после изменения tinkerpop.version в файле pom.xml Титана. Инструкции по сборке Titan можно найти здесь. В качестве альтернативы вы можете рассмотреть возможность создания ветки titan11 для последних доступных исправлений и TinkerPop 3.1.1. (Поддержка Hadoop 2!).

Далее вам нужно будет настроить bufferSize на соответствующем сериализаторе в файле gremlin-server.yaml. Я не думаю, что вы можете решить эту проблему только с конфигурацией клиента.

serializers:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { bufferSize: 8192, useMapperFromGraph: graph }}       # application/vnd.gremlin-v1.0+gryo

Поскольку у вас есть Java-клиент и вы собираетесь работать напрямую с объектами Vertex, возможно, вы могли бы рассмотреть возможность прямого подключения к Titan и полностью избежать этой сериализации.

person Jason Plurad    schedule 25.05.2016
comment
Итак, для полноты, как правильно это настроить? В моем коде Kotlin (который легко переводится на Java) у меня есть val kryo = GryoMapper.build().addRegistry(TitanIoRegistry.INSTANCE).create(); val ser = GryoMessageSerializerV1d0(kryo); val conf = HashMap<String, Any>(); conf.put(TOKEN_BUFFER_SIZE, serializerBufferSize); ser.configure(conf,null), где var TOKEN_BUFFER_SIZE = "bufferSize" и var serializerBufferSize = 8192. Судя по всему, это не влияет. - person Christoph Möbius; 27.05.2016