关于phpredis拓展hScan的一点小坑

来源:互联网 发布:写文章的软件 编辑:程序博客网 时间:2024/06/05 23:03

先交代一下踩坑的背景主要是用到了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 01) "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 171) "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值去获取接下来的数据。


原创粉丝点击