当多个线程访问同一密钥时,点燃操作会创建锁

时间:2019-07-19 07:35:06

标签: ignite

我有一个点火服务器节点和一个客户端。存储在某些键中的数据量很大(大约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

1 个答案:

答案 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. 
    }
}