Jedis返回相同的值,即使lua脚本删除它

时间:2015-07-23 13:40:42

标签: java redis playframework-2.3 jedis

我在我的应用中使用jedis和jedis连接池。 我使用redis排序集合来存储数据。 在我使用LUA脚本的应用程序中,我正在弹出数据(删除)。 LUA脚本包含5到6个命令。 我的应用程序是多线程的,所以我使用了akka actor并附加了一个jedis池。所以每个线程都有自己的jedis实例。 在某些时候,jedis为多个akka线程返回相同的数据。

这是我的代码,

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;
}

}

是否因为lua脚本包含更多命令? 请提出解决此问题的建议。

这是日志,

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] - 来自play-akka.actor.default-dispatcher-12中的应用程序 Poped Value:1315406 :: 2349091862155 :: N / A

2015-07-23 18:39:04,560 - [INFO] - 来自play-akka.actor.default-dispatcher-11中的应用程序 Poped Value:1315406 :: 2349091862155 :: N / A

2015-07-23 18:39:04,560 - [INFO] - 来自play-akka.actor.default-dispatcher-16中的应用程序 Poped Value:1315406 :: 2349091862155 :: N / A

2015-07-23 18:39:04,888 - [INFO] - 来自play-akka.actor.default-dispatcher-12中的应用程序 Poped Value:1315406 :: 2349091862155 :: N / A

2015-07-23 18:39:04,891 - [INFO] - 来自play-akka.actor.default-dispatcher-11中的应用程序 Poped Value:1315406 :: 2349091862155 :: N / A

另请注意我在这里做错了。

0 个答案:

没有答案