Search code examples
jacksonhazelcastkryohazelcast-imap

Hazelcast, Kryo, JsonNode Serializer


I am implementing a Hazelcast application using distributed MAP with as the entry. My JsonNodeSerializer looks like as shown below

private final ObjectReader jsonNodeReader;
private final ObjectWriter jsonNodeWriter;

@Override
public void write(ObjectDataOutput out, JsonNode jsonNode)
        throws IOException {
    out.write(jsonNodeWriter.writeValueAsBytes(jsonNode));
}

@Override
public JsonNode read(ObjectDataInput in)
        throws IOException {
    return jsonNodeReader.readTree(in);
}

However, I wanted to use Kryo to avoid using JsonNodeReader/Writer to save some space and improve performance.

I tried using Kryo and I am not able to read JsonNode/ObjectNode as we do not have no-args constructor.

@Override
public void write(ObjectDataOutput out, JsonNode jsonNode)
        throws IOException {
    Kryo kryo = KRYO_THREAD_LOCAL.get();
    Output output = new Output((OutputStream) out);
    kryo.writeObject(output, jsonNode);
    output.flush();

    //out.write(jsonNodeWriter.writeValueAsBytes(jsonNode));
}

@Trace(dispatcher = true)
@Override
public JsonNode read(ObjectDataInput in)
        throws IOException {
    InputStream inputStream = (InputStream) in;
    Input input = new Input(inputStream);
    Kryo kryo = KRYO_THREAD_LOCAL.get();
    return kryo.readObject(input, ObjectNode.class);
   // return jsonNodeReader.readTree(in);
} 

Not sure if my approach to use JsonNodeReader/Writer is optimal or Using Kryo will make my solution better.

My goal is the save space and improve performance. Any suggestions are welcome to put me in right direction. Thanks


Solution

  • Not sure if kryo is actually able to write those JSON nodes. I think there are multiple possible options:

    • You stay with kryo, but that means you should read and write the objects as separate values, than you can recreate the JsonNode instances with constructor parameters

    • If you anyways gonna write independent values, you might want to write the values directly into ObjectDataOutput and read it using ObjectDataInput

    • From my pov the best way though is to use Jackson - you might want to have a look into the CBOR dataformat which is binary, very concise and directly available for Jackson - in addition you won't loose the schemaless, dynamic nature of JSON (https://github.com/FasterXML/jackson-dataformats-binary/tree/master/cbor)