【问题标题】:What is the best way to serialize class hierarchies in Hazelcast?在 Hazelcast 中序列化类层次结构的最佳方法是什么?
【发布时间】:2020-04-07 19:42:24
【问题描述】:

我想在 Hazelcast 中序列化和缓存与另一个 @Entity 具有双向关系的 @Entity。

我正在寻找在这种情况下被认为是官方最佳实践的解决方案,该解决方案将:

  1. 正确序列化可能包含 null 的类层次结构 引用以及对集合和列表的引用
  2. 处理图表中的引用循环

到目前为止,我通过在图表中的每个 @Entity 中实现 DataSerializable 成功实现了前者。我通过以下方式处理空值和集合:

@Override
public void writeData(ObjectDataOutput out) throws IOException {
    out.writeBoolean(certificationNumber != null);
    if (certificationNumber != null)
        out.writeUTF(certificationNumber);
    out.writeShort(getSkills().size());
    for (SkillEntity s: getSkills())
        s.writeData(out);
}


@Override
public void readData(ObjectDataInput in) throws IOException {
    if (in.readBoolean()) {
        certification = new CertificationEntity();
        certification.readData(in);
    }
    short size = in.readShort();
    skills = new HashSet<>();
    for(int i=0; i<size; i++)
        skills.add(in.readObject());
}

但是,打破参考周期更具挑战性。 This 线程建议:

我认为这将基于维护线程本地映射。

在序列化时,您需要查找要序列化的对象 已经在那张地图中了..如果是这样..您需要序列化某种 占位符(例如 uuid)

如果不在该地图中,则生成一个占位符并将其放入该地图中 并写出实际的对象,你可能想写 占位符,以便您可以在反序列化时使用此信息。

我认为这应该让你朝着正确的方向前进,但是因为我有 在我不知道是否有任何陷阱之前没有实现这一点 在这里。

虽然上面的建议非常有意义,但我不太确定如何去做,即应用什么软件工程模式以及如何将我的实体与序列化逻辑清晰地分开。

任何指针?

【问题讨论】:

    标签: hibernate spring-boot jpa spring-data-jpa hazelcast


    【解决方案1】:

    我认为我的问题的答案在“Mastering Hazelcast 3.9”手册的第 201 页,可以从 Hazelcast 网站下载。

    页面内容:

    public class PersonKryoSerializer implements StreamSerializer<Person> {
        private static final ThreadLocal<Kryo> kryoThreadLocal
                = new ThreadLocal<Kryo>() {
            @Override
            protected Kryo initialValue() {
                Kryo kryo = new Kryo();
                kryo.register(Person.class);
                return kryo;
            }
        };
        @Override
        public int getTypeId() {
            return 2;
        }
        @Override
        public void write(ObjectDataOutput objectDataOutput, Person product)
                throws IOException {
            Kryo kryo = kryoThreadLocal.get();
            Output output = new Output((OutputStream) objectDataOutput);
            kryo.writeObject(output, product);
            output.flush();
        }
        @Override
        public Person read(ObjectDataInput objectDataInput)
                throws IOException {
            InputStream in = (InputStream) objectDataInput;
            Input input = new Input(in);
            Kryo kryo = kryoThreadLocal.get();
            return kryo.readObject(input, Person.class);
        }
        @Override
        public void destroy() {
        }
    }
    

    PersonKryoSerializer 实现起来相对简单。不错的 事情是 Kryo 负责循环检测并产生很多 比 Java 序列化更小的序列化数据。对于我们的一个 我们设法将地图条目的大小从 15 个 使用 Java 序列化的千字节平均值,小于 6 千字节 平均的。当我们启用 Kryo 压缩时,我们设法在下面得到它 三千字节。

    【讨论】:

      猜你喜欢
      • 2019-06-01
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多