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(); >来自redis.io的协议: cat data.txt | redis-cli --pipe 解决方法
我是phpredis的贡献者之一,所以我可以回答你的问题.简短的回答是它不一样,但我会提供更多细节.
将phpredis放入Redis :: PIPELINE模式时会发生什么,而不是在调用命令时发送命令,而是将其放入“待发送”命令列表中.然后,一旦调用exec(),就会创建一个包含所有命令的大命令缓冲区并发送给Redis. 在命令全部发送之后,phpredis读取每个回复并按照每个命令规范打包结果(例如,HMGET调用作为关联数组返回等). phpredis中流水线的性能实际上非常好,几乎每个用例都应该足够了.话虽这么说,你仍在通过PHP处理每个命令,这意味着你将通过为每个命令调用phpredis扩展本身来支付函数调用开销.此外,phpredis将花时间处理和格式化每个回复. 如果您的用例需要将大量数据导入Redis,特别是如果您不需要处理每个回复(而只是想知道所有命令都已处理),则可以使用批量导入方法. 我实际上创建了一个项目来执行此操作: 这个扩展背后的想法是你用命令调用它然后将缓冲区保存到磁盘,磁盘将采用原始Redis协议并与cat buffer.txt兼容. redis-cli – 管道样式插入. 需要注意的一点是,目前你不能简单地用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'); ?> 然后你可以做这样的事情: ? 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 干杯! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |