簡體   English   中英

phpredis管道是否與使用協議進行大量插入相同?

[英]Is phpredis pipeline the same as using the protocol for mass insertion?

我正在將我的網站的某些部分從關系數據庫移動到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的vs 協議

     cat data.txt | redis-cli --pipe 

我是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兼容cat buffer.txt | redis-cli --pipe 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');
?>

然后你可以做這樣的事情:

➜  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

干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM