0

I am using jedis and jedis connection pooling in my app. I am using redis sorted set collection to store the data. In my app using LUA script i am poping data (Remove). The LUA script contains 5 to 6 commands. My app is in multithreaded one so I am used akka actor and attached a jedis pool to it. So each thread will have its own jedis instance. At some point the jedis returns the same data for more than one akka thread.

Here is my code,

public class XoRedisSortedSetCache<T> extends XoRedisCollectionCache<T> {

private static final String ZPOP = "local function zPop(tempkey) local val = redis.pcall('ZREVRANGEBYSCORE', tempkey, 1, 0, 'WITHSCORES' , 'LIMIT' , '0' , '1' ) if val then redis.call('zrem', tempkey, val[1]) end return val end return zPop(KEYS[1])";
private static final byte[] ZPOP_BYTES = ZPOP.getBytes();
private static final String ZRANDOM_WEIGHTED_POP = "local function zRandomWeightedPop(tempkey) local totalSize = redis.pcall('zcard', tempkey) if totalSize > 0 then local maxscore = redis.pcall('ZREVRANGE', tempkey, 0, 0, 'WITHSCORES') local minscore = redis.pcall('ZRANGE', tempkey, 0, 0, 'WITHSCORES') local c = math.randomseed(redis.pcall('time')[1]) local randomIndex = math.random(0, totalSize) local val = redis.pcall('ZRANGEBYSCORE', tempkey, minscore[2], maxscore[2], 'WITHSCORES' , 'LIMIT' , randomIndex , 1) if val then redis.pcall('zrem', tempkey, val[1]) end return val end end return zRandomWeightedPop(KEYS[1])";
private static final byte[] ZRANDOM_WEIGHTED_POP_BYTES = ZRANDOM_WEIGHTED_POP.getBytes();

final byte[] bInclusiveB = { 0x5B, 0x0B };
final byte[] bExclusiveC = { 0x28, 0x0C };
final byte[] bLexMinusInf = { 0x2D };
final byte[] bLexPlusInf = { 0x2B };

private static final JedisPool JEDIS_POOL = ((RedisPlugin)XoUtil.getPluginByClass(RedisPlugin.class)).jedisPool();
private final Serializer<T> SERIALIZER;
private byte[] collectionName;
private String namespace;

private final Random randomGenerator;
private int maxThreshold;

public XoRedisSortedSetCache(String namespace, String collectionName, Class<T> persistentClass, int maxThreshold) {
    super(namespace, collectionName, persistentClass);
    randomGenerator = new Random();
    this.maxThreshold = maxThreshold;
}

public final T pop() {
    Jedis jedis = null;
    T value = null;
    try{

        int randScore = randomGenerator.nextInt(100);
        Collection<byte[]> valueBytes = null;
        byte[] valuebyte = null;

        jedis = JEDIS_POOL.getResource();
        if(randScore <= this.maxThreshold) {
            valueBytes = (Collection<byte[]>) jedis.eval(ZPOP_BYTES, 1, this.collectionName);
        } else {
            valueBytes = (Collection<byte[]>) jedis.eval(ZRANDOM_WEIGHTED_POP_BYTES, 1, this.collectionName);
        }
        if(valueBytes != null && valueBytes.size() > 0) {
            valuebyte = valueBytes.iterator().next();
        }
        if(valuebyte != null) {
            value = (T) this.deSerialize(valuebyte);
        }
    } catch(Exception e) {
        Logger.error("Error while popping the value from set.", e);
    } finally{
        if(jedis != null) {
            jedis.close();
        }
    }
    Logger.info("Poped Value : " + value);
    return value;
}

}

Is it because of lua script contains more commands? Please give a suggestion to fix this.

Here is the logs,

2015-07-23 18:39:04,159 - [INFO] - from application in play-akka.actor.default-dispatcher-14 

Poped Value : 1315406::2349091862155::N/A

2015-07-23 18:39:04,333 - [INFO] - from application in play-akka.actor.default-dispatcher-12 Poped Value : 1315406::2349091862155::N/A

2015-07-23 18:39:04,560 - [INFO] - from application in play-akka.actor.default-dispatcher-11 Poped Value : 1315406::2349091862155::N/A

2015-07-23 18:39:04,560 - [INFO] - from application in play-akka.actor.default-dispatcher-16 Poped Value : 1315406::2349091862155::N/A

2015-07-23 18:39:04,888 - [INFO] - from application in play-akka.actor.default-dispatcher-12 Poped Value : 1315406::2349091862155::N/A

2015-07-23 18:39:04,891 - [INFO] - from application in play-akka.actor.default-dispatcher-11 Poped Value : 1315406::2349091862155::N/A

Also please mention the mistake i have done it here.

Hakuna Matata
  • 755
  • 3
  • 13
  • idk if relevant to your problem, but be sure to call `returnResource` to the pool once you're done with the connection – Itamar Haber Jul 23 '15 at 15:38
  • returnResource is depricated from jedis 2.6 onwards and also jedis is a "Closable" so we can use either "try-resource" type or just call the close() method of jedis is fine. – Hakuna Matata Jul 24 '15 at 05:22

0 Answers0