java - Hazelcast 复制地图:内存格式和序列化
问题描述
我正在尝试根据配置检查对象的序列化/反序列Replicated Map
化In-Memory-Format
。
基于Hazelcast文档:In-Memory-Format
OBJECT(默认):数据以反序列化的形式存储。此配置是默认选择,因为数据复制主要用于高速访问。请注意,在没有 Map.put() 的情况下更改值不会反映在其他成员上,但在更改的成员上可见,以便以后访问值。
BINARY:数据以序列化的二进制格式存储,每次请求都必须反序列化。这个选项提供了更高的封装性,因为只要新更改的对象没有明确地将 Map.put() 再次放入映射中,对值的更改总是被丢弃。
示例不可变类及其自定义序列化器:
@Value
@NoArgsConstructor
@AllArgsConstructor
class MyObject {
String str;
}
@Slf4j
class MyObjectSerializer implements ByteArraySerializer<MyObject> {
private final ObjectMapper jsonMapper = new ObjectMapper();
@Override
public byte[] write(MyObject object) throws IOException {
log.info("Serialize: {}", object);
return jsonMapper.writeValueAsBytes(object);
}
@Override
public MyObject read(byte[] buffer) throws IOException {
MyObject obj = jsonMapper.readValue(buffer, MyObject.class);
log.info("Deserialize {}", obj);
return obj;
}
@Override
public int getTypeId() { return 1; }
@Override
public void destroy() { }
}
HazelcastInstance
配置和创建(使用自定义序列化程序):
private static final HazelcastInstance instance = Hazelcast.newHazelcastInstance(config());
private static Config config() {
Config config = new Config();
config.getSerializationConfig().addSerializerConfig(new SerializerConfig()
.setTypeClass(MyObject.class)
.setImplementation(new MyObjectSerializer());
return config;
}
第一个测试(in-memory-format
是object
):
@Test
public void test_put_inMemoryFormatIsObject() {
ReplicatedMapConfig config = instance.getConfig().getReplicatedMapConfig("map1");
config.setInMemoryFormat(InMemoryFormat.OBJECT);
ReplicatedMap<Integer, MyObject> map = instance.getReplicatedMap("map1");
map.put(1, new MyObject("Hi1"));
}
输出日志:
INFO HazelcastTest$MyObjectSerializer -| Serialize: HazelcastTest.MyObject(str=Hi1)
INFO HazelcastTest$MyObjectSerializer -| Deserialize HazelcastTest.MyObject(str=Hi1)
第二个测试(in-memory-format
是binary
):
@Test
public void test_put_inMemoryFormatIsBinary() {
ReplicatedMapConfig config = instance.getConfig().getReplicatedMapConfig("map2");
config.setInMemoryFormat(InMemoryFormat.BINARY);
ReplicatedMap<Integer, MyObject> map = instance.getReplicatedMap("map2");
map.put(2, new MyObject("Hi2"));
}
输出日志:
INFO HazelcastTest$MyObjectSerializer -| Serialize: HazelcastTest.MyObject(str=Hi2)
所以我的问题是为什么在in-memory-format = object
, for eachmap.put
中,对象被序列化和反序列化一次,而根本没有必要?即对象可以放入地图中,无需任何序列化和反序列化。
是否有可能改变这种行为?
注意:示例类是不可变的,我不担心修改。
解决方案
Hazelcast 是一个分布式数据网格,因此假设数据将分布在多个节点上。使用 IMap,对数据进行分区,以便每个节点保存一部分数据;使用 Replicated Map,每个节点都会有一个完整的副本。
即使可以将对象放入本地地图而无需序列化,也必须对数据进行序列化才能通过网络发送到其他节点。
您是只运行一个节点还是多节点集群?在序列化数据之前,我没有检查源代码以查看我们是否对单节点案例进行了任何测试。
推荐阅读
- flutter - setState 重置 Datepicker 并且不更改文本
- mongodb - 有什么方法可以获取特定 MongoDB 查询访问的记录数?
- php - PHP类的动态变量中的未定义属性
- excel - 从表单列表框中选择一个值并显示关联的值
- powershell - PowerShell 配置文件的正确(首选)编码是什么?
- ajax - 将文件上传到 Google 表格
- python-3.x - 自定义梯度的自定义训练损失
- java - 更改 netbeans 8.2 JDK MacOS High Sierra
- java - 我的 Mac 上安装了多少个 java 版本?
- swift - 如何测试流程/执行顺序?