扫描的 Redis 密钥限制

  • 本文关键字:密钥 Redis 扫描 redis
  • 更新时间 :
  • 英文 :


我有一些代码,可以在 redis 中存储用户是否处于活动状态的标志,在每个用户的唯一键下。

class RedisProfileActiveRepo implements ProfileActiveRepo
{
/** @var Redis  */
private $redis;
public function __construct(Redis $redis)
{
$this->redis = $redis;
}
public function markProfileIsActive(int $profile_id)
{
$keyname = ProfileIsActiveKey::getAbsoluteKeyName($profile_id);
// Set the user specific key for 10 minutes
$result = $this->redis->setex($keyname, 10 * 60, 'foobar');
}
public function getNumberOfActiveProfiles()
{
$count = 0;
$pattern = ProfileIsActiveKey::getWildcardKeyName();
$iterator = null;
while (($keys = $this->redis->scan($iterator, $pattern)) !== false) {
$count += count($keys);
}
return $count;
}
}

当我从以下代码生成密钥时:

namespace ProjectName;
class ProfileIsActive
{
public static function getAbsoluteKeyName(int $profile_id) : string
{
return __CLASS__ . '_' . $profile_id;
}
public static function getWildcardKeyName() : string
{
return __CLASS__ . '_*';
}
}

这会导致密钥看起来像ProjectNameProfileIsActive_1234Redis 中的 scan 命令无法匹配任何密钥。

当我用下划线替换斜杠时:

class ProfileIsActive
{
public static function getAbsoluteKeyName(int $profile_id) : string
{
return str_replace('\', '', __CLASS__) . '_' . $profile_id;
}
public static function getWildcardKeyName() : string
{
return str_replace('\', '', __CLASS__) . '_*';
}
}

代码按预期工作。

我的问题是 - 为什么在键名中使用斜杠进行扫描无法按预期运行,以及键名中是否应避免使用任何其他字符以避免类似问题?

理论上最新的 Redis 会在您将键设置为redis-cli时自动转义反斜杠:

127.0.0.1:6379> set thistest 1
OK
127.0.0.1:6379> keys this*
1) "this\test"

在运行 php 客户端代码之前,在redis-cli中发出MONITOR命令,并注意SCAN命令。如果您的集合足够大,并且您的count参数不存在或足够低,则可能无法获得记录:

127.0.0.1:6379> scan 0 match this*
1) "73728"
2) (empty list or set)
127.0.0.1:6379> scan 0 match this* count 10000
1) "87704"
2) 1) "this\test"

最新更新