我有一个点火服务器节点和一个客户端。存储在某些键中的数据量很大(大约100MB)。为这些键操作一个键大约需要200毫秒。我的客户端是多线程的(10个线程),它们都试图访问相同的密钥,它们为每个get操作获取时间已累积。我想摆脱这个锁
我尝试使用正常的get操作,在事务中进行get操作。
//Multi thread does the following
long startTime = System.currentTimeMillis();
Object result =ignite.getOrCreateCache("TestCache").get(key);
long endTimeAfterGet = System.currentTimeMillis();
if (null != result) {
System.out.println("Result Found");
}
System.out.println("Get time = " + (endTimeAfterGet - startTime) );
//output
Result Found
Get time = 170 ms. Time for type cast = 0
Result Found
Get time = 178 ms. Time for type cast = 0
Result Found
Get time = 257 ms. Time for type cast = 0
Result Found
Get time = 288 ms. Time for type cast = 0
Result Found
Get time = 371 ms. Time for type cast = 0
Result Found
Get time = 420 ms. Time for type cast = 0
Result Found
Get time = 476 ms. Time for type cast = 0
Result Found
Get time = 537 ms. Time for type cast = 0
Result Found
Get time = 590 ms. Time for type cast = 0
Result Found
Get time = 655 ms. Time for type cast = 0
答案 0 :(得分:0)
很可能,您在服务器节点上的striped thread pool上引起了争用。该线程池负责缓存操作处理,并根据分区ID从中选择线程。因此,所有操作将被发送到服务器上的同一线程以执行。它将操作累积在队列中。
可以使用IgniteCompute#affinityCall(...)解决此争用,这会将作业发送到服务器节点并在public pool中执行。诀窍是,本地缓存操作不会发送到执行以执行到条带化池,而是使用调用线程。因此,将独立于分区ID选择服务器端的线程。
此外,您可以将处理逻辑放入呼叫中。它将消除通过网络发送如此巨大的价值的需求。该代码将被发送到数据,而不是相反。
相似性调用的代码如下:
public class CacheGetJob implements IgniteCallable<Object> {
@IgniteInstanceResource
private Ignite ignite;
@Override public Object call() {
IgniteCache<Object, Object> cache = ignite.cache(CACHE_NAME);
if (cache == null)
return null;
else {
long startTime = System.currentTimeMillis();
Object value = cache.get(KEY);
System.out.println("Get time = " + (System.currentTimeMillis() - startTime));
return process(value);
}
}
Object process(Object value) {
// Value processing.
}
}