RedisのクラスタLUAは達成します

別に直接証券取引所に何か、ハのロットから..明るいすばらしい神に感謝する

フォーカスは、次の一節です。

Object object = redisTemplate.execute(redisUpdateOrderScript,
//这里有key 要像官网说的那样加个"{}",不然就报错了,这里3个key都要前缀一致
Arrays.asList(hkey, amountKey, key),
//值无要求
amount.longValueExact(),price.doubleValue(),price.doubleValue());

私自身の理解では、実装と執行hgetスクリプトは同じですが、Redisのことで実行されるコンテンツのluaスクリプトが、コマンドが同じで送るように頼んだ。したがって、上記のキーを3プラスは、同じ接頭辞を持っていたということです。


ビジネスロジックはこのようなものです:
置かRedisのベットギア20
1.順序集合(ソートセット)が自動的に価格を発注します

ZADD key 0.0354 "0.0354"

そして、価格に基づいてハッシュ値に行く2、ヴァルはシングルこの価格で取られます

HGET key 0.0354

Javaコード

プラスハンディキャップ

 public void addOrderForLua(BeforeMatchDTO model) {

        //缓存失效
        redisService.remove(RedisService.getPositionKey(model.getContract()));

        BigDecimal price = model.getPrice();
        BigDecimal amount = model.getAmount().multiply(PRECISION_DOUBLE);
        String key = RedisKeyGen.getContractPositionZsetKey(model.getContract(), model.getDirection());
        log.info("getContractPositionZsetKey:{}",key);
        String hkey = RedisKeyGen.getContractPositionHashKey(model.getContract(), model.getDirection());
        log.info("getContractPositionHashKey:{}",hkey);
        String amountKey = RedisKeyGen.getContractPositionAmountKey(model.getContract(),price.stripTrailingZeros().toPlainString());
        log.info("getContractPositionAmountKey:{}",amountKey);
        log.info("addOrderForLua contract:{}, value:{}", model.getContract(), amount.longValueExact());
        Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amount.longValueExact(),price.doubleValue(),price.doubleValue());
        log.info("addOrderForLua" + object);

    }

少ないハンディキャップ

public void subOrderForLua(String contract,BigDecimal price,BigDecimal amount,int direction) {

        //缓存失效
        redisService.remove(RedisService.getPositionKey(contract));

        String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
        log.info("getContractPositionZsetKey:{}",key);
        String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
        log.info("getContractPositionHashKey:{}",hkey);
        String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
        log.info("getContractPositionAmountKey:{}",amountKey);
        log.info("subOrderForLua contract:{}, value:{}", contract, amount.doubleValue());
        BigDecimal amountTag = amount.multiply(PRECISION_DOUBLE).negate();  //转成负数

        Object nowAmount = redisService.hmGet(hkey, price.toPlainString());
        log.info("subOrderForLua nowAmount:{},direction:{}", nowAmount, direction);

        Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amountTag.longValueExact(),price.doubleValue(),price.doubleValue());

        log.info("subOrderForLua" + object);

    }

クエリ(無視してください変換の値を参照するにはローカルキー)

public List<QuotationOrderRsgResp> query(String contract,int direction) {

        List<QuotationOrderRsgResp> result = new ArrayList<>();
        String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
        log.info("getContractPositionZsetKey:{}",key);
        String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
        log.info("getContractPositionHashKey:{}",hkey);
        Set<Object> objectSet = null;

        //卖从低到高
        if(QuotationConstants.DIRECTION_SELL == direction) {
            objectSet = redisService.rangeByIndex(key, 0, 19);
        } else {
            //买从高到低
            objectSet = redisService.reverseRangeByIndex(key, 0, 19);
        }

        if (objectSet != null && objectSet.size() > 0) {

            Integer [] digits = convertService.getContractDigitsForInt(contract);

            for (Object obj : objectSet) {

                log.info("query class:{},val:{}",obj.getClass(),JSON.toJSONString(obj));
                BigDecimal price = new BigDecimal(obj.toString());
                String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
                Object object = redisService.hmGet(hkey, amountKey);
                log.info("getContractPositionAmountKey hmGet key:{},val:{}",amountKey,object);
                BigDecimal valTemp = getBigDecimal(object);
                if(valTemp.compareTo(BigDecimal.ZERO) == 0) continue;
                BigDecimal val = valTemp.divide(PRECISION_DOUBLE);
                QuotationOrderRsgResp resp = new QuotationOrderRsgResp();
                resp.setContract(contract);
                resp.setDirection(direction);
                resp.setPrice(convertService.setScale(price, digits[0]));
                resp.setVolume(convertService.setScale(val,digits[1]));
                resp.setTotal(convertService.setScale(price.multiply(val),add(digits[0] ,digits[1])));
                result.add(resp);
            }
        } else {
            log.info("query redis is null! contract:{},direction:{}", contract, direction);
        }

        return result;
    }

鍵の生成

 public static final String getContractPositionZsetKey(String contract,int direction){
        return "{POSITION:"+contract+"}.POSITION-ORDER-" + contract + "-" + direction;
    }

    public static final String getContractPositionHashKey(String contract,int direction){
        return "{POSITION:"+contract+"}.POSITION-ORDER-VAL-" + contract + "-" + direction;
    }

    public static final String getContractPositionAmountKey(String contract,String amount){
        return "{POSITION:"+contract+"}." + amount;
    }

LUAスクリプト

local val1 = '"'
local valAmount = redis.call('hget',KEYS[1],KEYS[2])
if not valAmount then
    redis.pcall('hset',KEYS[1],KEYS[2],ARGV[1])
    if tonumber(ARGV[1]) > 0 then
        local val2 = val1 .. ARGV[3] .. val1
        return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
    else
        return 1
    end
else
    local tagAmount = tonumber(valAmount) + ARGV[1]

    redis.pcall('hset',KEYS[1],KEYS[2],tagAmount)

    local val2 = val1 .. ARGV[3] .. val1
    local zset = redis.pcall('ZRANK', KEYS[3], val2)

    if tagAmount <= 0 then
        if not zset then
            return 1
        else
            return redis.pcall('ZREMRANGEBYSCORE', KEYS[3], tonumber(ARGV[2]), tonumber(ARGV[2]))
        end
    else
        if not zset then
            local val2 = val1 .. ARGV[3] .. val1
            return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
        else
            return 1
        end
    end
end

おすすめ

転載: blog.51cto.com/5634409/2402874