我使用Cassandra作为持久存储以及Hazelcast 3.6。用于休息API(POST)。 Mapstore实现如下所示。
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.querybuilder.Insert;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.hazelcast.core.MapStore;
public class InventoryMapStoreImpl implements MapStore<String, Map<String, Integer>> {
public static Cluster cluster;
public static Session session;
public InventoryMapStoreImpl() {
cluster = Cluster.builder().addContactPoint("127.0.0.1").build();
session = cluster.connect("company");
}
@Override
public synchronized Map<String, Integer> load(String key) {
Map<String, Integer> qty = new HashMap<String, Integer>();
ResultSetFuture futureList = session
.executeAsync("Select * from company.onhandinventoryavailability WHERE key='" + key + "';");
try {
if (futureList.get() != null) {
ResultSet rsFuture = futureList.get();
Row resultOne = rsFuture.one();
if (resultOne != null) {
qty = resultOne.getMap(1, String.class, Integer.class);
}
}
session.close();
cluster.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return qty;
}
@Override
public Map<String, Map<String, Integer>> loadAll(Collection<String> keys) {
return null;
}
@Override
public Iterable<String> loadAllKeys() {
return null;
}
@Override
public synchronized void store(String key, Map<String, Integer> value) {
try {
Insert insert = QueryBuilder.insertInto("onhandinventoryavailability")
.value("key", key);
insert.value("value", value);
session.execute(insert);
System.out.println("INSERTED:"+key+" INTO CASSANDRA...");
} catch (Exception e) {
System.out.println("ERORRRR");
e.printStackTrace();
}
session.close();
cluster.close();
}
@Override
public void storeAll(Map<String, Map<String, Integer>> map) {
}
@Override
public void delete(String key) {
}
@Override
public void deleteAll(Collection<String> keys) {
}
}
地图的hazelcast xml条目是。
map name="onHandInventoryAvailability">
<map-store enabled="true">
<class-name>com.company.common.hazelcast.mapstore.InventoryMapStoreImpl</class-name>
<write-delay-seconds>5</write-delay-seconds>
<write-batch-size>1000</write-batch-size>
<write-coalescing>true</write-coalescing>
</map-store>
<in-memory-format>BINARY</in-memory-format>
<backup-count>1</backup-count>
<async-backup-count>0</async-backup-count>
<time-to-live-seconds>0</time-to-live-seconds>
<max-idle-seconds>0</max-idle-seconds>
<eviction-policy>NONE</eviction-policy>
<max-size policy="PER_NODE">0</max-size>
<eviction-percentage>25</eviction-percentage>
<min-eviction-check-millis>100</min-eviction-check-millis>
<merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
<cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
</map>
问题在于,当我在延迟或一次一个地点击POST api后,数据同时出现在hazelcast和cassandra中,但是当我做更多的POST表示10,100等时,与cassandra的连接被hazelcast和写入丢失了后面没有正常工作。只有10,100等中的一两个记录去cassandra(不是全部)。我的mapstore实现有什么问题吗?
答案 0 :(得分:0)
Hazelcast只会实例化您的MapStore
实施,并在此实例上调用load
,store
等方法。这意味着您只需连接一个Cassandra群集并打开一个会话(在MapStore
的构造函数中),并且只调用一次load
或store
方法时,断开与Cassandra集群的连接。这解释了代码的当前行为。
Cassandra司机的Cluster
&amp; Session
个对象应该跨越应用程序的整个生命周期[1]。正如评论中已经建议的那样,在应用程序关闭之前,不应该关闭它们。
[1] http://docs.datastax.com/en/developer/java-driver/2.0/java-driver/fourSimpleRules.html