关于phpredis拓展hScan的一点小坑

先交代一下踩坑的背景主要是用到了redis的哈希结构来存储目标用户。

这一次的目标库用户数去到了50W,redis提供的获取hash数据主要是用到了hget,hgetall,以及hscan。

业务需求导致需要获取全量的目标库数据,由于数据量比较大,之前使用的hgetall会导致进程卡死,决定优化进程,改用hscan方法。

然而关于hscan除去官方的文档,网上的资料并不多,所以摸索几个小时后还是一头雾水,为啥phpredis中的hscan返回的值不太正常?

以此为背景有了这篇日记。

redis的文档给出的scan返回结构如下:

一个数组内包含了一个cursor值以及具体的key=>value数据,下一次获取则带上cursor值

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
    10) "key:7"
    11) "key:1"

redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

然而惯性思维下我认为phpredis拓展下的hscan也应该是这样干的,然而这个方法在实际的调试中并没有给我返回具体的cursor值,下面是phpredis拓展下hscan的说明 (原文链接

hScan


Description: Scan a HASH value for members, with an optional pattern and count

Parameters

key: Stringiterator: Long (reference)pattern: Optional pattern to match againstcount: How many keys to return in a go (only a sugestion to Redis)

Return value

Array An array of members that match our pattern

Examples
$it = NULL;
/* Don't ever return an empty array until we're done iterating */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
while($arr_keys = $redis->hScan('hash', $it)) {
    foreach($arr_keys as $str_field => $str_value) {
        echo "$str_field => $str_value\n"; /* Print the hash member and value */
    }
}

以及代码:


phpredis源代码中的hScan方法在获取cursor时的传参方式是直接获取到了 &$i_iterator(前文提到的cursor值),也就是直接获取到了cursor值在内存中的地址,调用hScan时会在方法内将新的cursor值覆盖掉原有的值,所以函数的返回值里面不会有从redis中得到的cursor值,只会单独返回一个包含数据的数组。

如果业务需要分多次链接来获取hash表中的数据,则要单独保留住cursor值的内存地址或是在调用hscan后记录cursor的新值,在第二次请求时带上新的cursor值去获取接下来的数据。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值