我一直在尝试实现一个分布式系统,该系统将数据存储在执行get命令的节点中。我的想法是使用KeyAffinityService来查找与本地节点关联的密钥,并且每次在put命令完成之前,存储将引用同一本地节点的密钥并使用将使用此密钥的分组API将值存储在本地节点中。 我的代码如下:
SimpleCache.java:
import java.util.*;
import java.util.concurrent.*;
import org.infinispan.Cache;
import org.infinispan.affinity.*;
import org.infinispan.manager.*;
//Used to store the key for the local node
class locaddr{ static String nut; static String sim;}
public class SimpleCache {
public void start() throws Exception {
EmbeddedCacheManager manager = new DefaultCacheManager("democluster.xml");
Cache<String, String> cache = manager.getCache();
String command = "";
int ticketid = 1;
Scanner scan = new Scanner(System.in);
cache.start();
manager.start();
// Create the affinity service to find the Key for the manager
KeyAffinityService keyAffinityService = KeyAffinityServiceFactory.newLocalKeyAffinityService(
cache,
(KeyGenerator)new RndKeyGenerator(),
Executors.newSingleThreadExecutor(),
100);
//Find key associated with local node
locaddr.nut = Objects.toString(keyAffinityService.getKeyForAddress(manager.getAddress()));
log("Start of program.....");
log("Input one of following commands:");
log("book");
log("pay");
log("list");
log("locaddr");
log("quit");
while (true){
command = scan.nextLine();
if (command.equals("book")) {
log("Enter name ");
String name = scan.nextLine();
locaddr.sim = Objects.toString(keyAffinityService.getCollocatedKey(locaddr.nut));
cache.put(Integer.toString(ticketid)+manager.getAddress().toString(),name);
log("Booked ticket " + name);
ticketid++;
}
else if (command.equals("pay")) {
log("Enter ticket number ");
String id = scan.nextLine();
log("Display ticket:"+cache.get(id));
String ticket = cache.remove(id);
log("Checked out ticket " + ticket);
}
else if (command.equals("list")) {
Set <String> set = cache.keySet();
for (String ticket: set) {
log(ticket + " " + cache.get(ticket));
}
}
else if (command.equals("quit")) {
cache.clear();
cache.stop();
manager.stop();
keyAffinityService.stop();
log("Bye");
break;
}
else if (command.equals("locaddr")) {
log("local key for manager is: "+locaddr.nut);
log("manager address is: " + manager.getAddress());
}
else {
log("Unknown command " + command);
}
}
}
public static void main(String[] args) throws Exception{
new SimpleCache().start();
}
public static void log(String s){
System.out.println(s);
}
}
democluster.xml:
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:6.0
http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
xmlns="urn:infinispan:config:6.0">
<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups-tcp.xml" />
</properties>
</transport>
</global>
<default>
<clustering mode="distributed" >
<sync/>
<hash numOwners="1" numSegments="100" capacityFactor="1">
<groups enabled="true">
<grouper class="KXGrouper"/>
</groups>
</hash>
</clustering>
</default>
</infinispan>
KXGrouper.java:
import org.infinispan.distribution.group.Grouper;
public class KXGrouper implements Grouper<String> {
public String computeGroup(String key, String group) {
String g = locaddr.sim;
return g;
}
public Class<String> getKeyType() {
return String.class;
}
}
我的实现基于infinispan的简单缓存实现示例。但是我有两个主要问题:
1 当我在单独的JVM中运行此代码时,有时它会起作用,但有时当我执行一个&#34; book&#34; command(调用collocated key命令和cache put命令),我得到一个错误,它说另一个节点不再是集群的一部分。错误如下所示:
Exception in thread "main" java.lang.IllegalStateException: Address SRI-PC-4630 is no longer in the cluster
at org.infinispan.affinity.KeyAffinityServiceImpl.getKeyForAddress(KeyAffinityServiceImpl.java:107)
at org.infinispan.affinity.KeyAffinityServiceImpl.getCollocatedKey(KeyAffinityServiceImpl.java:91)
at SimpleCache.start(SimpleCache.java:77)
at SimpleCache.main(SimpleCache.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
地址&#34;地址SRI-PC-4630&#34;将是另一个正在运行的JVM中的管理器的地址。我一直在网上寻找这个问题的解决方案,但似乎没有人遇到类似的问题。
2 如果我确实让它运行并做了一本书#34;并且键/值存储在本地节点中,我无法从任何其他节点访问它。
我一直试图解决这个问题,但无济于事,我们将非常感谢任何建议或建议。