我有一个2节点设置的分布式缓存设置,需要对两个成员进行持久化设置。
我已经实现了MapSore和Maploader,并且在两个节点上部署了相同的代码。
MapStore和MapLoader在单个成员的设置中工作绝对正常,但是当另一个成员加入后,MapStore和Maploader继续在第一个成员上工作,第二个成员的所有插入或更新都会通过第一个成员持久化到磁盘上。
我的要求是,每个成员都应该能够独立地持久化到磁盘上,这样分布式缓存就会在所有成员上备份,而不仅仅是第一个成员。
我是否可以通过改变设置来实现这个要求。
这是我的Hazlecast Spring配置。
@Bean
public HazelcastInstance hazelcastInstance(H2MapStorage h2mapStore) throws IOException{
MapStoreConfig mapStoreConfig = new MapStoreConfig();
mapStoreConfig.setImplementation(h2mapStore);
mapStoreConfig.setWriteDelaySeconds(0);
YamlConfigBuilder configBuilder=null;
if(new File(hazelcastConfiglocation).exists()) {
configBuilder = new YamlConfigBuilder(hazelcastConfiglocation);
}else {
configBuilder = new YamlConfigBuilder();
}
Config config = configBuilder.build();
config.setProperty("hazelcast.jmx", "true");
MapConfig mapConfig = config.getMapConfig("requests");
mapConfig.setMapStoreConfig(mapStoreConfig);
return Hazelcast.newHazelcastInstance(config);
}
这是我的Hazlecast yml配置--它被放在了 /opt/hazlecast.yml
被我上面的spring配置所接收。
hazelcast:
group:
name: tsystems
management-center:
enabled: false
url: http://localhost:8080/hazelcast-mancenter
network:
port:
auto-increment: true
port-count: 100
port: 5701
outbound-ports:
- 0
join:
multicast:
enabled: false
multicast-group: 224.2.2.3
multicast-port: 54327
tcp-ip:
enabled: true
member-list:
- 192.168.1.13
完整的代码可以在这里找到:[]。https:/bitbucket.orgsamrat_royhazelcasttestsrcmaster][1] 。
这可能只是运气不好,数据量低,而不是真正的错误。
在每个节点上,尝试运行 LocalKeySet() 方法并打印结果。
这将告诉你哪些键在集群中的哪个节点上。拥有键"X"将调用该键的地图存储,即使更新是由其他节点发起的。
如果你的数据量很低,可能不是5050的数据分割。在一个极端的情况下,2个节点集群中的2条数据记录可能都在同一个节点上。如果你有1000条数据记录,那就不太可能都在同一个节点上。
所以另一个可以尝试的就是增加更多的数据,更新所有的数据,看看是否两个节点都参与。
好吧,经过一番挣扎,我注意到了一个十几岁的小买关键细节。
Datastore需要是一个集中的系统,所有Hazelcast成员都可以访问。不支持持久化到本地文件系统。
这与我所观察到的完全一致[。https:/docs.hazelcast.orgdocslatestmanualhtml-single#loading-and-storing-persistent-data] 。
然而不要气馁,我发现我可以使用事件监听器来做我需要做的事情。
@Component
public class HazelCastEntryListner
implements EntryAddedListener<String,Object>, EntryUpdatedListener<String,Object>, EntryRemovedListener<String,Object>,
EntryEvictedListener<String,Object>, EntryLoadedListener<String,Object>, MapEvictedListener, MapClearedListener {
@Autowired
@Lazy
private RequestDao requestDao;
我创建了这个类,并把它挂到配置中,就像这样
MapConfig mapConfig = config.getMapConfig("requests");
mapConfig.addEntryListenerConfig(new EntryListenerConfig(entryListner, false, true));
return Hazelcast.newHazelcastInstance(config);
这工作完美无瑕,我能够将数据复制到每个节点上的嵌入式数据库。
我的用例是覆盖HA故障转移的边缘情况。在HA故障切换期间,从属节点需要知道活动节点的工作内存。
我并没有使用hazelcast作为缓存,而是作为一种数据同步机制。