主要使用到eval命令
EVAL命令:
命令格式:EVAL script numkeys key [key …] arg [arg …]
- script
参数是一段 Lua5.1 脚本程序。脚本不必(也不应该[^1])定义为一个 Lua 函数
- numkeys
指定后续参数有几个key,即:key [key …]中key的个数。如没有key,则为0
- key [key …]
从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key)。在Lua脚本中通过KEYS[1], KEYS[2]获取。
- arg [arg …]
附加参数。在Lua脚本中通过ARGV[1],ARGV[2]获取。
示例
127.0.0.1:6379> EVAL "return KEYS[1]" 1 key1
"key1"
127.0.0.1:6379> EVAL "return ARGV[1]" 0 value1
"value1"
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
简单创建php类,这里创建了两个方法,用于批量hmget和hgetall
<?php
class RedisClient {
public static $redis_client;
const CONNECT_TIMEOUT = 2;
private static function _getInstance() {
if (self::$redis_client instanceof RedisClient) {
return self::$redis_client;
}
self::$redis_client = new \Redis;
self::$redis_client->connect('127.0.0.1', '6379', self::CONNECT_TIMEOUT);
return self::$redis_client;
}
/**
* @param $keys
* @param $fields
* @return array
*/
public static function hmgetbatch($keys, $fields = []) {
$res = [];
$keyNum = count($keys);
if (is_array($fields) && !empty($fields)) {
$argv_fields = implode("','", $fields);
$argv_fields = "'" . $argv_fields . "'";
} else {
return self::hgetallbatch($keys);
}
$lua_script = "local rtn = {};for i, v in ipairs(KEYS) do local item = redis.call('hmget', v, $argv_fields);if not item then rtn[i] = {} else rtn[i] = item;end;end;return rtn;";
$data = self::_getInstance()->eval($lua_script, $keys, $keyNum);
foreach ($data as $key => $item) {
$number = count($item);
$tmp = [];
for ($i = 0; $i < $number; $i++) {
$tmp[$fields[$i]] = $item[$i];
}
$res[$keys[$key]] = $tmp;
}
return $res;
}
/**
* @param $keys
* @return array
*/
public static function hgetallbatch($keys) {
$res = [];
$keyNum = count($keys);
if (is_array($fields) && !empty($fields)) {
$argv_fields = implode("','", $fields);
$argv_fields = "'" . $argv_fields . "'";
}
$lua_script = "local rtn = {};for i, v in ipairs(KEYS) do local item = redis.call('hgetall', v);if not item then rtn[i] = {} else rtn[i] = item;end;end;return rtn;";
$data = self::_getInstance()->eval($lua_script, $keys, $keyNum);
foreach ($data as $key => $item) {
$number = count($item);
$tmp = [];
for ($i=0; $i<$number; $i++) {
if ($i % 2 == 0) {
$tmp[$item[$i]] = $item[$i+1];
}
}
$res[$keys[$key]] = $tmp;
}
return $res;
}
}
调用方法
$keys = ["user.id:1000001", "user.id:1000002"];
$fields = ['username', 'email'];
$data1 = RedisClient::hmgetbatch($keys, $fields);
$data2 = RedisClient::hgetallbatch($keys);
var_dump($data1);
var_dump($data2);