phpredis在阿里云集群版Redis使用scan命令遇到的坑

发布时间:April 24, 2018 // 分类:杂记 // 暂无评论

在利用phpredis扩展使用阿里云集群版Redis时,scan命令出现了奇怪的问题。集群节点0的CPU占用率飙到100%,数据却出不来。

跟踪scan的代码后发现,scan的游标卡在了72057594037927936上(2的56次方)。因为用的是phpredis官方文档提供的do{}while()方式循环扫描,游标卡在72057594037927936上就导致了死循环。这也解释了为什么CPU会飙到100%。

而使用Redis Desktop Manager管理Redis内容,使用scan方法管理列出key时,并未出错,但游标可以达到500000000000000000以上。

由此可以判断,phpredis在读取scan返回游标时可能发生了溢出。

在几乎不可能改动phpredis扩展的代码的情况下,好在phpredis支持直接执行命令,配合阿里redis集群版的自研命令iscan进行查询还是可以满足需求。(详见https://help.aliyun.com/knowledge_detail/51306.html)

以下是phpredis直接执行redis命令的方法(官方文档:https://github.com/phpredis/phpredis#rawcommand ):

/**
 * Send arbitrary things to the redis server.
 * @param   string      $command    Required command to send to the server.
 * @param   mixed       ...$arguments  Optional variable amount of arguments to send to the server.
 * @return  mixed
 * @example
 * <pre>
 * $redis->rawCommand('SET', 'key', 'value'); // bool(true)
 * $redis->rawCommand('GET", 'key'); // string(5) "value"
 * </pre>
 */
public function rawCommand( $command, $arguments ) {}

使用类似下面的方法即可实现scan:

$it=0; // 初始化游标
$idx=0;  // Redis节点ID

$scan_res = $redis->rawCommand('ISCAN', $idx, $it, 'MATCH', 'abc:*', 'COUNT', 10000);
$it=$scan_res[0];
$arr_keys = $scan_res[1];

需要注意的是:

  • 游标从0开始,phpredis原本的scan是从null开始的。
  • rawCommand传入游标进行scan后并不会自动修改传入变量,需要在返回结果时额外赋值。

本文固定链接
https://www.ywlib.com/archives/141.html

标签
redis, phpredis, 阿里云

添加新评论 »

分类
随机文章
最新文章
最近回复
  • typecho模板: 只调用随机文章的内容怎么操作啊?类似多思多金博主的你好污啊那种样子的
  • box: 好棒b( ̄▽ ̄)d
  • mi: /data/opkg update
  • alen chen: 我的是小米路由器mini ROM:開發版2.19.40
  • alen chen: 你好,看到你的文章如獲至寶,一舉解決了我多年想在小米路由器mini裡面安裝dlna的心願。一路...
  • hiicy: windows上最有效 最简单明了的方法!打电话!!
  • 梁兴健: 楼上好像都搞定了,只有我一个人报错吗,我是放在post.php文章下面,想显示随机文章的,Fa...
  • Jordan: Thanks!!!
  • Kent: 这一块我也只是玩一玩。。高深的都不懂其实哈哈哈
  • 紫色: 博主,有没有联系方式?邮箱QQ什么的,我最近在做人脸识别的课题,想请教一些问题。