Java Hazelcast和MapDB—实现一个简单的分布式数据库
我已经实现了一个hazelcast服务,它通过MapStoreFactory和newMapLoader将数据存储到本地mapdb实例中。这样,如果需要重新启动群集,可以加载密钥:Java Hazelcast和MapDB—实现一个简单的分布式数据库,java,hazelcast,mapdb,nosql,Java,Hazelcast,Mapdb,Nosql,我已经实现了一个hazelcast服务,它通过MapStoreFactory和newMapLoader将数据存储到本地mapdb实例中。这样,如果需要重新启动群集,可以加载密钥: public class HCMapStore<V> implements MapStore<String, V> { Map<String, V> map; /** specify the mapdb e.g. via * DBMaker.newFileDB(new Fi
public class HCMapStore<V> implements MapStore<String, V> {
Map<String, V> map;
/** specify the mapdb e.g. via
* DBMaker.newFileDB(new File("mapdb")).closeOnJvmShutdown().make()
*/
public HCMapStore(DB db) {
this.db = db;
this.map = db.createHashMap("someMapName").<String, Object>makeOrGet();
}
// some other store methods are omitted
@Override
public void delete(String k) {
logger.info("delete, " + k);
map.remove(k);
db.commit();
}
// MapLoader methods
@Override
public V load(String key) {
logger.info("load, " + key);
return map.get(key);
}
@Override
public Set<String> loadAllKeys() {
logger.info("loadAllKeys");
return map.keySet();
}
@Override
public Map<String, V> loadAll(Collection<String> keys) {
logger.info("loadAll, " + keys);
Map<String, V> partialMap = new HashMap<>();
for (String k : keys) {
partialMap.put(k, map.get(k));
}
return partialMap;
}}
公共类HCMapStore实现MapStore{
地图;
/**指定mapdb,例如通过
*DBMaker.newFileDB(新文件(“mapdb”)).closeOnJvmShutdown().make()
*/
公共HCMapStore(数据库){
这个.db=db;
this.map=db.createHashMap(“someMapName”).makerGet();
}
//省略了其他一些存储方法
@凌驾
公共无效删除(字符串k){
logger.info(“删除,”+k);
地图。删除(k);
db.commit();
}
//地图加载器方法
@凌驾
公共V加载(字符串键){
logger.info(“加载,”+键);
返回map.get(key);
}
@凌驾
公共集合loadAllKeys(){
logger.info(“loadAllKeys”);
返回map.keySet();
}
@凌驾
公共地图加载全部(集合键){
logger.info(“loadAll,”+键);
Map partialMap=newhashmap();
用于(字符串k:键){
partialMap.put(k,map.get(k));
}
返回partialMap;
}}
我现在面临的问题是来自hazelcast的MapLoader接口的loadAllKeys方法需要返回整个集群的所有键,但每个节点只存储它拥有的对象
示例:我有两个节点,存储了8个对象,例如,5个对象存储在node1的mapdb中,3个存储在node2的mapdb中。我认为哪个节点拥有哪个对象是由hazelcast决定的。现在重新启动时,node1将为loadAllKeys返回5个键,node2将返回3个键。Hazelcast决定忽略这3项,数据“丢失”
有什么好的解决方案吗?
赏金更新:我在hc邮件列表中询问了这个问题,提到了2个选项(我将再添加1个),我想知道类似的内容是否已经在hazelcast 3.2或3.3中实现:
3) 强制Hazelcast在每个节点上存储所有数据。根据Hazelcast 3.3文档,将分区号设置为1或其他值 MapLoader初始化流程如下所示: 当第一次从任何节点调用getMap()时,初始化将开始 取决于InitialLoadMode的值。如果设置为渴望, 初始化开始。如果设置为LAZY,初始化实际上 不会启动,但每次加载分区时都会加载数据 完成
我希望这会有所帮助。可以加载存储在所有节点上的数据,但目前必须手动加载 在每个节点上:
HCMapStore store = createMapDbStore();
HazelcastInstance hz = createHz( store ); // use store in MapStoreConfig as implementation
IMap imap = hz.getMap("map");
Map diskMap = store.loadAll( store.loadAllKeys() ); // load all entries on disk
imap.putAll( diskMap ); // put into distributed map
但是,正如邮件列表
MapStore
中提到的那样,并不是真正打算这样使用的。还要注意,备份不会以这种方式持久化到磁盘。因此,如果重新启动群集,一个节点上的磁盘死亡,这些条目将丢失。谢谢-选项是好主意,但我想知道我将如何做这样的事情,以及这是否可能。谢谢!这意味着有一个“嘘”