hyperf/model-cache

使用 findManyFromCache 时报错

Closed this issue · 4 comments

报错信息:
PHP Warning: foreach() argument must be of type array|object, bool given in /data/php-server/vendor/hyperf/model-cache/src/Redis/HashGetMultiple.php on line 32

问题定位点:

// vendor/hyperf/model-cache/src/Redis/HashGetMultiple.php

    public function parseResponse($data)
    {
        $result = [];
        foreach ($data ?? [] as $item) {
            if (! empty($item) && is_array($item)) {
                $temp = [];
                $count = count($item);
                for ($i = 0; $i < $count; ++$i) {
                    $temp[$item[$i]] = $item[++$i];
                }

                $result[] = $temp;
            }
        }

        return $result;
    }

查看源码发现 $data 的值是通过lua脚本获取的,脚本内容:

// vendor/hyperf/model-cache/src/Redis/HashGetMultiple.php

    public function getScript(): string
    {
        return <<<'LUA'
    local values = {}; 
    for i,v in ipairs(KEYS) do 
        if(redis.call('type',v).ok == 'hash') then
            values[#values+1] = redis.call('hgetall',v);
        end
    end
    return values;
LUA;
    }

本地环境测试了一下,在没有任何缓存时、有部分缓存时、全部key均有缓存时都没有复现这个问题。。
目前服务是正常的(程序会当作空数组,即没有获取到缓存处理)

想问一下,什么情况下这个lua脚本会返回false呢??是不是redis配置有什么问题?

本地和线上的model-cache包版本均为 3.0.17
线上使用的docker镜像为 hyperf/hyperf:8.0-alpine-v3.16-swoole-v5.0.1

如果返回了 bool ,可能是 redis 有什么问题

比如禁用了 lua 什么的,建议检查一下 redis 的命令禁用列表

大概了解到原因了,线上为redis集群,由于lua脚本只会在同一个node下执行,当多个传入的key不再同一个node时,会返回ERR 'KEY1' and 'KEY2' not in the same slot

好吧,只能重写改造一下findManyFromCache
建议官方可不可以将lua脚本改成redis pipeline呢?

image

把这个加上