在 php 循环中将数据写入 redis 时发生了有趣的事情
Interesting thing happened while writing data into redis within a php loop
我写了一个 php 脚本来将数据从一台服务器(我们称之为服务器 A)拉到另一台服务器(服务器 B)。服务器A中的数据是一个redis列表,存储了所有需要写入服务器B的操作命令,如:
["setex",["session:xxxx",604800,"xxxx"]]
["set",["uid:xxx","xxxxx"]]
["pipeline",[]]
["set",["uid:xxx","xxxxx"]]
["hIncrBy",["Signin:xxxx","totalTimes",1]]
["pipeline",[]]
....
我的 php 代码是:
while($i < 1000){
$line = $redis['server_a']->rpop('sync:op');
list($op,$params) = json_decode($line,1);
$r = call_user_func_array(array($redis['server_b'], $op), $params);
$i++;
}
有线的是,当call_user_func_array方法错误执行redis命令时,队列中的所有rest命令都无法正确写入服务器B。
为了寻求答案,我在这个问题上卡了将近一个星期。经过数千次测试,我发现如果删除无法正确执行的 "bad commands",例如 ["pipeline",[]] 行。可以正确插入所有其他命令。所以它让我想起了一些redis交易问题。 也许有一些机制,当一个命令在 redis 中执行不当时,之后的所有其他命令都将被视为一个事务。所以我在 while 循环中添加了一个 exec() 命令:
while($i < 1000){
$line = $redis['server_a']->rpop('sync:op');
list($op,$params) = json_decode($line,1);
$r = call_user_func_array(array($redis['server_b'], $op), $params);
$redis['server_b']->exec(); //this is the significant update
$i++;
}
那么,我的问题就解决了!!!
我的问题是,谁能帮我解释一下redis的机制?我的假设正确吗?
您的图书馆可能出于某种原因正在使用事务处理流水线。 pipeline
不是实际的 Redis 命令,参见 http://redis.io/commands
只需删除所有带有空参数的 pipeline
命令,或者在您之前发出 pipeline
时只使用 ->exec
。
我写了一个 php 脚本来将数据从一台服务器(我们称之为服务器 A)拉到另一台服务器(服务器 B)。服务器A中的数据是一个redis列表,存储了所有需要写入服务器B的操作命令,如:
["setex",["session:xxxx",604800,"xxxx"]]
["set",["uid:xxx","xxxxx"]]
["pipeline",[]]
["set",["uid:xxx","xxxxx"]]
["hIncrBy",["Signin:xxxx","totalTimes",1]]
["pipeline",[]]
....
我的 php 代码是:
while($i < 1000){
$line = $redis['server_a']->rpop('sync:op');
list($op,$params) = json_decode($line,1);
$r = call_user_func_array(array($redis['server_b'], $op), $params);
$i++;
}
有线的是,当call_user_func_array方法错误执行redis命令时,队列中的所有rest命令都无法正确写入服务器B。
为了寻求答案,我在这个问题上卡了将近一个星期。经过数千次测试,我发现如果删除无法正确执行的 "bad commands",例如 ["pipeline",[]] 行。可以正确插入所有其他命令。所以它让我想起了一些redis交易问题。 也许有一些机制,当一个命令在 redis 中执行不当时,之后的所有其他命令都将被视为一个事务。所以我在 while 循环中添加了一个 exec() 命令:
while($i < 1000){
$line = $redis['server_a']->rpop('sync:op');
list($op,$params) = json_decode($line,1);
$r = call_user_func_array(array($redis['server_b'], $op), $params);
$redis['server_b']->exec(); //this is the significant update
$i++;
}
那么,我的问题就解决了!!!
我的问题是,谁能帮我解释一下redis的机制?我的假设正确吗?
您的图书馆可能出于某种原因正在使用事务处理流水线。 pipeline
不是实际的 Redis 命令,参见 http://redis.io/commands
只需删除所有带有空参数的 pipeline
命令,或者在您之前发出 pipeline
时只使用 ->exec
。