Redis“未知命令”错误

3

我在我的网站(Laravel 4.2)中使用Redis作为会话存储。有时候我会遇到以下错误。我猜测">"字符打破了setex命令。

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in 

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''

这些错误很少出现在生产服务器上,我无法重现它们。你有任何想法为什么会出现这些错误以及如何预防它们吗?

key: laravel:xxxxxxxxxxxxxxx

value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";

exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282

更新

这里有一个我正在使用redis的代码示例。

    public function view($username = null)
    {
        $username = mb_strtolower($username);
        $redis = $this->getRedis();
        try{
            $view = $redis->get(User::getCacheKeyByUsername($username));
        }catch (\Exception $exception){
            $view = null;
        }
        if($view === null || Session::has("admin")){
            $user = User::where('username', '=', $username)->where("status", 1)->first();
            if (empty($user)) {
                return Redirect::to(Session::get("lang") . '/all');
            }
            $view = View::make("view", array("user" => $user));
            if(!Session::has("admin")){
                try{
                    $redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
                }catch (\Exception $exception){
                    Log::error($exception->getMessage());
                }
            }
        }
        return $view;
    }

@Ferid Movsumov,这个问题解决了吗? - Nick
@mnv 很遗憾,问题仍然存在。 - Farid Movsumov
@FeridMovsumov 只是一个猜测,您是否在将视图传递给 Redis 之前尝试过 ->render() 视图呈现?只需将 $view 替换为 $view->render() 尝试一下。 - Giedrius Kiršys
1
@FeridMovsumov 已经明白了。也许解决方法是将特殊字符转换为HTML实体,然后在检索时进行反向处理?我指的是 htmlspecialcharshtmlspecialchars_decode - Giedrius Kiršys
@GiedriusKiršys,您的解决方案解决了我的问题。请将其写为答案,我会接受它。 - Farid Movsumov
显示剩余9条评论
2个回答

1
从您的错误日志中可以得出结论:redis不喜欢特殊字符,如<和>,因此您需要对它们进行编码。
在检索数据时,请使用htmlspecialchars进行编码,使用htmlspecialchars_decode进行解码。

0

你的 Redis 客户端出现了问题。你无法重现它,因为这个错误不是发生在你的代码中,而是在客户端和 Redis 服务器之间的 TCP 通信中。

我建议更新提问并说明你正在使用哪个 Redis 客户端模块。它是 Predis 吗?

如果你在 Unix 上,请尝试编译和安装 phpredis。它是一个 PHP 模块,我从来没有遇到过任何问题。


使用 Telnet 进行复制

执行 telnet 主机 端口号 并按照指示操作:

正常请求 GET a 的格式如下:

*2
$3
get
$1
a
$-1

现在考虑一下 - 请求gem a:

*2
$3
gem
$1
a
-ERR unknown command 'gem'

协议有效,但命令“gem”无效。

现在考虑这个:

*1
$3
ml>
-ERR unknown command 'ml>'

这是您的错误。协议有效,但命令无效。

或者考虑以下方案:

*2
$3
get
$1
<html>
$-1
-ERR unknown command 'ml>'

这是你的错误信息。无效的strlen("<html>");

为什么这是Redis客户端错误而不是用户错误:

许多Redis客户端使用PHP魔术方法

这意味着如果您调用$redis->bla(),它们会提取“bla”部分及其参数并将其转发到redis服务器。

但是,您不能执行$redis->ml>()。这将是语法错误。因此,这是来自Redis客户端的错误,而不是来自您的代码。

它看起来也像是HTML的一部分。看起来您正在Redis中存储HTML数据。我只能猜测客户端没有计算strlen()count()并发送了错误的信息“下行电报线”。


感谢您的反馈。再次出现了Redis库的问题。我将编辑如何使用Telnet重现此错误。 - Nick
谢谢你的回答,@Nick。但是我该如何解决这个问题? - Farid Movsumov
我将在Predis客户端中搜索这个错误。我会让你知道结果。 - Farid Movsumov
安装 phpredis 至少进行检查,链接为 https://github.com/phpredis/phpredis - 这在 Laravel 中是百分之百支持的,因为它是 Redis 连接的事实标准。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接