Hazelcast VersionedPortalble的使用

Hazelcast VersionedPortalble的使用,hazelcast,Hazelcast,我正在寻找Hazelcast中的可移植序列化。我特别感兴趣的是VersionedPortable-接口。我创建了一个场景,其中两个客户端具有相同类的不同版本: //VERSION 1 public class Vehicle implements VersionedPortable { private final String type; public Vehicle() { this.type = ""; } public Vehicle(final String t

我正在寻找Hazelcast中的可移植序列化。我特别感兴趣的是
VersionedPortable
-接口。我创建了一个场景,其中两个客户端具有相同类的不同版本:

//VERSION 1
public class Vehicle implements VersionedPortable {
    private final String type;

    public Vehicle() { this.type = ""; }
    public Vehicle(final String type) { this.type = type; }

    public void setType(final String type) { this.type = type; }
    public String getType () { return this.type; }

    public void writePortable(PortableWriter writer) throws IOException {
         writer.writeUTF("type", type);
    }

    public void readPortable(PortableReader reader) throws IOException {
         type = reader.readUTF("type");
    }

    public int getFactoryId() { return 1; }
    public int getClassId() { return 1; }
    public int getClassVersion () { return 1;}
}

//VERSION 2
public class Vehicle implements VersionedPortable {
    private final String type;
    private final int tyres;

    public Vehicle() { this.type = ""; this tyres = 0;}
    public Vehicle(final String type, final int tyres) { this.type = type; this.tyres = tyres; }

    public void setType(final String type) { this.type = type; }
    public String getType () { return this.type; }

    public void writePortable(PortableWriter writer) throws IOException {
         writer.writeUTF("type", type);
         writer.writeInt("tyres", tyres);
    }

    public void readPortable(PortableReader reader) throws IOException {
         type = reader.readUTF("type");
         tyres = reader.readInt("tyres");
    }

    public int getFactoryId() { return 1; }
    public int getClassId() { return 1; }
    public int getClassVersion () { return 2;}
}
我在以下场景中使用了这两个类:

  • 带有V1的Hazelcast客户端创建车辆并将其存储在IMap中:type=Porsche
  • 带有V2的Hazelcast客户端更新车辆并将其存储在IMap中:轮胎=4
  • 带有V1的Hazelcast客户端更新车辆并将其存储在IMap:type=Audi中
  • 具有V2的Hazelcast客户端读取车辆并将其打印到控制台:预期:奥迪,4;得到:奥迪,0
我的期望错了吗?我开始怀疑VersionedPortable并不是我所期望的(支持在单个IMap中读取和写入同一对象的不同版本)


(第95行)和另一行(见第三个项目符号)上的一些代码似乎指向这个方向。

您提到的另一篇文章是正确的——您的V1代码只知道类型字段,因此V1执行的任何写入操作都只会写入类型字段,而不会写入轮胎字段。由于您的V1对象不知道有关轮胎的信息,因此它不会保留上次更新期间V2代码写入的值

好消息是,V1代码可以读取V2代码编写的对象,而无需任何修改。(注意:经过编辑以更正语句,V1可以读取V2编写的对象,我输入错误并说是在原件中写入的)

V2代码需要知道,只要V1客户端仍然是系统的一部分,它就必须准备好查看那些没有价值的条目。当找不到值时,设置要使用的默认值可能会很有用


在某些情况下,您可能希望强制执行一个限制,即读卡器检查正在读取的对象的版本,如果它来自代码的更高版本,则禁止更新该对象。通过这种方式,您可以确保不会丢失来自较新代码的更新,可能会引发一个异常,该异常将导致用户看到一个警告或错误,即他们没有运行最新的客户机代码,应该进行更新,以便对请求的对象具有写访问权限

是否可以测试对象是否由具有较旧版本的客户端创建?在这种情况下,具有较新版本的客户端可以替换较旧版本,从那时起,即使V1客户端再次更新V2版本,V2版本也将保持不变,不是吗?我立即尝试了您所说的:创建V2对象,在V1客户端中读取和更新,在V2客户端中读取。结果是一样的。V1客户端中未知的字段已重置为默认值。V1代码只能写入V1对象。。。因此,每当V1更新对象时,只有V2知道的所有字段都将丢失。感谢您的澄清。如果Hazelcast的文档能够清楚地说明Portable只向后兼容读取,而不兼容写入,那就太好了。其他解决方案(如链接文章中的protobuf)排除了EntryProcessor的使用,这是一个遗憾,但显然我们也要为写操作的向后兼容付出代价。