在Hazelcast中存储地图地图的有效方法?

时间:2015-07-06 08:35:12

标签: java hazelcast

我目前正在使用Hazelcast在网络上分发我的数据。该实现使用我想要存储的IMap对象。但是,这些对象中的每一个基本上只是一个HashMap,所以我一直想知道是否有更有效的方法来分发地图的地图"使用Hazelcast。

我已在他们的错误跟踪器上阅读了this long-forgotten issue,但在实现该功能方面没有取得任何进展。

如果没有这个作为核心Hazelcast功能,除了我当前的&#34; IMap<String, HashMap<String, String>>&#34;之外,还有更有效的方法来管理这种数据结构吗?接近?

4 个答案:

答案 0 :(得分:2)

  

该实现使用我想要存储的IMap对象。但是,这些对象中的每一个基本上只是一个HashMap

除了使用IMap存储HashMap之外,您可能只需将主要IMap存储在与某个键对应的HashMap的标识符中,并将所有子映射存储在Hazelcast中。

而不是IMap<String, HashMap> 使用IMap<String, SomeStringId>并使用HashMap获取相应的HazlecastInstance.getMap(SomeStringId) - 这样您仍然需要在变异后将值重新放回Hazelcast中,但是您只需输入一个值 - 而不是整个地图

IMap main = hazelcastInstance.getMap("Main"); 
String childMapName = main.get(key);
IMap childMap = hazelcastInstance.getMap(childMapName); 
Object value = childMap.get(childKey);
value.changeSmth();
childMap.put(chlidKey,value);

答案 1 :(得分:2)

Hazelcast不支持键值映射图。但一种可能的解决方案是使用复合密钥:

String employeeId = "1234"
String attribute = "name"
map.put(employeeId+"#"+attribute, "peter")

然而,请注意。如果您需要访问许多值,因为每次访问都需要往返。另一个缺点是很难获得key1的所有key2 /值(例如,查找employee 1234的所有属性)。

另一种阻止进行不需要的序列化/反序列化的方法是将map作为值与通过EntryProcessor的所有访问相结合。通过这种方式,您可以非常精确地控制正在发送/返回的数据+使用EntryProcessor,您无需担心数据争用,因为这是由EntryProcessor开箱即用的。 API可能不那么漂亮,但它可能会以非常有效的方式完成。在这种情况下,我建议在内存格式中使用OBJECT。这种方法的另一个优点是很容易获得所有值,因为它们被分组在hashmap-value中。但是,如果您有一个“无限”列数,这可能会导致问题,因为散列图值未分发。这不是复合键方法的问题。

所以这取决于你的用例你想要什么。

答案 2 :(得分:2)

我知道这可能为时已晚,无法回答您的问题,但当我尝试为聊天服务创建自己的分布式用户会话实现时,我遇到了同样的问题。

所以我所做的是将地图序列化为 byte [] ,然后将其持久化为hazelcast的 IMap 。  检查以下代码:

IMap<String, byte[]> distributedMap = hazelcast.getMap(MAP_NAME);

Map<String, Serializable> myMap = new HashMap<String, Serializable>();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(myMap);

distributedMap.put(sessionId, baos.toByteArray());

当我尝试检索持久用户会话时,我所做的就像下面的代码。

IMap<String, byte[]> distributedMap = hazelcast.getMap(MAP_NAME);

byte[] raw = distributedMap.get(sessionId);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Map<String, Serializable> myMap = (Map<String, Serializable>) ois.readObject();

然后我回到地图之后,我可以做任何事情。我希望这能帮助任何需要和我一样做的人。

答案 3 :(得分:0)

由于Hazelcast Map不会将对象的状态视为给定值,因此如果添加或删除内部HashMap中的值,则使用带有Hashmap对象(值)的IMAP将无意义,这些更改将不会在群集中共享。

Hazelcast仅分享其容器中的参考更改。所以你应该有一个带有单个连接键的IMap key1 +&#34; WhatEverString&#34; + key2

如果每次更改内部HashMap的状态时都要将内部HashMap引用到IMap,Hazelcast将重新整理内部地图,并且性能会降低。