我已经使用IdentifiedDataSerializable
为我的POJO实现了一个自定义序列化程序,这样我就可以在类的发展过程中保持细粒度的控制,并且需要添加/删除新的字段。对于某些集合,我还需要持久性并使用嵌入式键值存储实现MapStore
。我的问题是我希望在IdentifiedDataSerializable
实现中重用MapStore
序列化,以利用代码重用以及确保将来的类演变。
我试图获取对内部Hazelcast SerializationService
的引用,但它不是通过HazelcastInstance
中的“公共”API提供的。事实上,我无法找到任何合适的方式来掌握它。
我实际上喜欢的是MapStore
接口的一个版本,它在字节数组级别上工作,Hazelcast在调用之前处理序列化/反序列化。新功能请求我猜...
欢迎任何想法如何解决这个问题。
答案 0 :(得分:3)
将您的问题分成两部分:
如何避免必须维护不同的序列化行为 对于Hazelcast和持久的商店。
如何避免额外序列化反序列化的开销 在Hazelcast机器和持久性之间走一步 机械。
我使用Jackson对Hazelcast序列化和实现MapStore
所需的持久性进行了很好的结果。这允许我一致地使用相同的序列化逻辑,而不必担心不同设置的不同语义。
Fuad Malikov's blog entry比较各种Hazelcast序列化有一个如何使用Jackson二进制序列化的例子。您可以在MapStore
实施中使用相同的逻辑。更好的是,你可以使用不同的ObjectMapper
来编写JSON而不是二进制Smile格式 - 序列化语义在其他方面是相同的,但二进制格式更紧凑,读写速度更快,这是你想要什么Hazelcast。我发现能够在持久性存储中保存人类可读数据非常有用,为此我不太关心空间和时间效率,而更关心可维护性。 (我实际上能够通过编辑原始JSON来“修补”生产中的数据,而不是我想用二进制格式做的事情!)
杰克逊在添加和删除字段时非常灵活,这要归功于@JsonAnyGetter
和@JsonAnySetter
注释,它们可以优雅地处理无法识别的字段。
还可以将序列化行为“注入”到您无法控制的类中。
正如您所注意到的,Hazelcast不支持仅以序列化形式工作的MapStore
变体,因此每次加载都涉及反序列化,然后序列化为Hazelcast结构。根据我的经验和阅读,像Jackson和Kryo这样高度优化的序列化库是如此之快,以至于额外的工作完全由从持久性商店中读取的成本所支配。
如果重要的是要避免这一额外的步骤,你可以
在IMap<String, byte[]>
上使用MapInterceptors在interceptGet
中执行反序列化,在interceptPut
中执行序列化。不过,我不推荐它,因为你不得不重新创建Hazelcast开箱即用的功能。