pwk*_*wkc 5 php insert redis phpredis
我正在将我的网站的某些部分从关系数据库移动到Redis,并且需要在很短的时间内插入数百万个密钥.
在我的例子中,数据必须首先从MySQL中提取,由PHP准备,然后添加到相应的排序集(时间作为分数+ ID作为值).目前我正在使用Redis::PIPELINE参数的phpredis多方法的冒险.尽管速度明显提高,但在进行导入时,最终会阻止读取并减慢加载时间.
所以这里有一个问题 - 在phpredis中使用管道是否等同于http://redis.io/topics/mass-insert中描述的大量插入?
这是一个例子:
phpredis方式:
<?php
// All necessary requires etc.
$client = Redis::getClient();
$client->multi(Redis::PIPELINE); // OR $client->pipeline();
$client->zAdd('key', 1, 2);
...
$client->zAdd('key', 1000, 2000);
$client->exec();
Run Code Online (Sandbox Code Playgroud)来自redis.io的vs 协议:
cat data.txt | redis-cli --pipe
Run Code Online (Sandbox Code Playgroud)我是phpredis的贡献者之一,所以我可以回答你的问题.简短的回答是它不一样,但我会提供更多细节.
将phpredis置于Redis::PIPELINE模式时会发生什么,而不是在调用命令时发送命令,而是将其放入"待发送"命令列表中.然后,一旦调用exec(),就会创建一个包含所有命令的大命令缓冲区并发送给Redis.
在所有命令发送完毕后,phpredis会根据每个命令规范读取每个回复并打包结果(例如,HMGET调用以关联数组的形式返回等).
phpredis中流水线的性能实际上非常好,几乎每个用例都应该足够了.话虽这么说,你仍在通过PHP处理每个命令,这意味着你将通过为每个命令调用phpredis扩展本身来支付函数调用开销.此外,phpredis将花时间处理和格式化每个回复.
如果您的用例需要将大量数据导入Redis,特别是如果您不需要处理每个回复(而只是想知道所有命令都已处理),则可以使用批量导入方法.
我实际上已经在这里创建了一个项目:https: //github.com/michael-grunder/redismi
这个扩展背后的想法是你用你的命令调用它,然后将缓冲区保存到磁盘,磁盘将采用原始Redis协议并与cat buffer.txt | redis-cli --pipe样式插入兼容.
需要注意的一点是,目前你不能简单地用RedisMI对象调用替换任何给定的phpredis调用,因为命令被处理为变量参数调用(如hiredis),它适用于大多数但不是所有phpredis命令.
这是一个如何使用它的简单示例:
<?php
$obj_mi = new RedisMI();
// Some context we can pass around in RedisMI for whatever we want
$obj_context = new StdClass();
$obj_context->session_id = "some-session-id";
// Attach this context to the RedisMI object
$obj_mi->SetInfo($obj_context);
// Set a callback when a buffer is saved
$obj_mi->SaveCallback(
function($obj_mi, $str_filename, $i_cmd_count) {
// Output our context info we attached
$obj_context = $obj_mi->GetInfo();
echo "session id: " . $obj_context->session_id . "\n";
// Output the filename and how many commands were sent
echo "buffer file: " . $str_filename . "\n";
echo "commands : " . $i_cmd_count . "\n";
}
);
// A thousand SADD commands, adding three members each time
for($i=0;$i<1000;$i++) {
$obj_mi->sadd('some-set', "$i-one", "$i-two", "$i-three");
}
// A thousand ZADD commands
for($i=0;$i<1000;$i++) {
$obj_mi->zadd('some-zset', $i, "member-$i");
}
// Save the buffer
$obj_mi->SaveBuffer('test.buf');
?>
Run Code Online (Sandbox Code Playgroud)
然后你可以做这样的事情:
? tredismi php mi.php
session id: some-session-id
buffer file: test.buf
commands : 2000
? tredismi cat test.buf|redis-cli --pipe
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 2000
Run Code Online (Sandbox Code Playgroud)
干杯!
| 归档时间: |
|
| 查看次数: |
3524 次 |
| 最近记录: |