【问题标题】:Hazelcast 3.6.1 "There is no suitable de-serializer for type" exceptionHazelcast 3.6.1“没有适合类型的反序列化程序”异常
【发布时间】:2016-04-01 20:35:57
【问题描述】:

我正在使用 Hazelcast 3.6.1 读取地图。存储在地图中的对象类称为Schedule

我已经像这样在客户端配置了一个自定义序列化程序。

ClientConfig config = new ClientConfig();
SerializationConfig sc = config.getSerializationConfig();
sc.addSerializerConfig(add(new ScheduleSerializer(), Schedule.class));
...
private SerializerConfig add(Serializer serializer, Class<? extends Serializable> clazz) {
    SerializerConfig sc = new SerializerConfig();
    sc.setImplementation(serializer).setTypeClass(clazz);
    return sc;
}

地图是这样创建的

private final IMap<String, Schedule> map = client.getMap("schedule");

如果我使用计划 ID 作为键从地图获取,则地图返回 正确 值,例如

return map.get("zx81");

如果我尝试使用 SQL 谓词,例如

return new ArrayList<>(map.values(new SqlPredicate("statusActive")));

然后我得到以下错误

Exception in thread "main" com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 2. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members.

自定义序列化器正在使用Kryo进行序列化(基于此博客http://blog.hazelcast.com/comparing-serialization-methods/

public class ScheduleSerializer extends CommonSerializer<Schedule> {

    @Override
    public int getTypeId() {
        return 2;
    }

    @Override
    protected Class<Schedule> getClassToSerialize() {
        return Schedule.class;
    }

}

CommonSerializer 定义为

public abstract class CommonSerializer<T> implements StreamSerializer<T> {

    protected abstract Class<T> getClassToSerialize();

    @Override
    public void write(ObjectDataOutput objectDataOutput, T object) {
        Output output = new Output((OutputStream) objectDataOutput);
        Kryo kryo = KryoInstances.get();
        kryo.writeObject(output, object);
        output.flush(); // do not close!
        KryoInstances.release(kryo);
    }

    @Override
    public T read(ObjectDataInput objectDataInput) {
        Input input = new Input((InputStream) objectDataInput);
        Kryo kryo = KryoInstances.get();
        T result = kryo.readObject(input, getClassToSerialize());
        input.close();
        KryoInstances.release(kryo);
        return result;
    }

    @Override
    public void destroy() {
        // empty
    }
}

我需要在服务器端做任何配置吗?我认为客户端配置就足够了。

我正在使用 Hazelcast 客户端 3.6.1,并且有一个节点/成员正在运行。

【问题讨论】:

    标签: serialization client hazelcast kryo


    【解决方案1】:

    查询要求节点知道类,因为必须反序列化字节流才能访问属性并查询它们。这意味着当您要查询对象时,您还必须在服务器端部署模型类(和序列化程序)。

    而当您使用基于键的访问时,我们不需要查看值(在我们比较键的字节数组时也不需要查看键)并只发送结果。这样一来,模型类和序列化程序都不必在 Hazelcast 节点上可用。

    我希望这是有道理的。

    【讨论】:

    • 那么有没有办法以编程方式在服务器/实例上设置配置?
    • 配置配置 = new XmlConfigBuilder().build(); SerializationConfig 序列化配置 = config.getSerializationConfig();序列化配置.add...();类似的东西?
    • 我在使用 hazelcastInstance.getReplicatedMap("fooo") 时收到此错误。 ,当我使用 hazelcastInstance.getMap("fooo") 时它消失了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多