生产环境为了提升库存操作的速度,使用lua脚本扣减库存,在本地单机环境没有问题,阿里云集群环境的时候,遇到错误

``command keys must in same slot``

lua 脚本

``$scriptSha = self::$redis->get(self::STOCK_SCRIPT_SHA);
    if (!$scriptSha) {
        $script = <<<luascript
        if tonumber(ARGV[1]) >= 0 then
            return redis.call('HINCRBY', KEYS[1], KEYS[2], ARGV[1])
        else
            local store = tonumber(redis.call("HGET", KEYS[1], KEYS[2]))
            if store == nil or store < math.abs(tonumber(ARGV[1])) then
                return -1
            else
                return redis.call('HINCRBY', KEYS[1], KEYS[2], ARGV[1])
            end
        end
luascript;
        $scriptSha = self::$redis->script('load', $script);
        self::$redis->set(self::STOCK_SCRIPT_SHA, $scriptSha);
    }
    $stockKey = ($isPre ? self::STOCK_PRESALE : self::STOCK_SALE) . $productId;
    $result = self::$redis->evalSha($scriptSha, [$stockKey, self::STOCK_SALE.$supplyId, $quantity], 2); //-1表示库存不足``

这个是使用php redis扩展执行命令 evalsha和eval函数的第二个参数是数组,把keysargv都放同一个数组,后面的数字2表示key的个数。lua数组索引是从1开始的,所以这边2表示前两个数keys的变量,后面的是argv的变量

推荐的解决方法是在key的共性上加{}

比如productStock:10000,是商品10000的库存hash,调整调整key的设置,{productStock}:10000,另外就是hash 的field也按这个格式,

比如单机情况下设置库存hset productStock:10000 stock 100

需要调整key和field的结构 hset {productStock}:10000 {productStock}:stock 100 这样在分配到solt的时候,就会根据productStock进行hash处理,从而分配到同一个solt。solt。个solt。