1. 程式人生 > >[redis]redis中的pipeline

[redis]redis中的pipeline

redis中的pipeline

second60  20181101

1 單操作命令分析

單操作命令操作時間 = 1次網路往返 + 1次命令執行

假如一次get key,那麼是單次操作

2 批量操作命令分析

如果我們要得到n個key, 如果迴圈呼叫get,那麼

迴圈操作單次命令時間= n次網路往返+ n次命令執行.

為此,redis中提供了批量操作的命令,如mget, mset,有效的減少RTT網路時間

批量操作命令時間 = 1次網路往返 + n 次命令執行

但是,這隻支援單類命令的批量操作,如果我要同時傳送不同命令,同時操作,怎麼辦?

這也就出現了pipeline.

3 pipeline簡介

pipeline 支援同時傳送多條不同型別的命令,並一次性得到結果!!!

pipeline操作時間 = 1次網路往返 + n次命令執行

pipeline解決了2中不同同時批量命令操作的問題。

pipeline(流水線)能將一組redis命令進行組裝,通過一次RTT傳輸給redis,再將這組redis命令的執行結果按順序返回給客戶端。

4 pipeline的使用

redis-cli的--pipe選項實際上就是使用Pipeline機制,例如下面操作將set

hello world和incr counter兩條命令組裝:

echo -en '*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n*2\r\n$4\r\nincr\r\

n$7\r\ncounter\r\n' | redis-cli --pipe

5 效能對比

操作型別

操作時間

是否支援多命令

效率

缺點

迴圈單命令

n次網路+n次命令

支援

速度最慢

批量命令

1次網路+n次命令

不支援

不支援多節點

pipeline

1次網路+n次命令

支援

不支援多節點

6 pipeline的優缺點

優點:

  1. 可以同時操作多條命令
  2. 速度快

缺點:

  1. 命令個數要有節制,不能資料量太大(可能會造成網路擁塞,太多可拆分多個小pipeline)
  2. 只能操作一個節點,不能同時操作多個節點,在分散式中,要注意使用

7 hiredis中pipline的使用

int pipeline_process(struct timeval access_timeout, std::vector<std::string> & pipeline_cmd, std::vector<std::string> &pipeline_resp, std::vector<bool> &pipeline_resp_status)
{
            if (0 == redis_ctx) {return -1;}
            redisSetTimeout(redis_ctx, access_timeout);

            for (int i = 0; i < pipeline_cmd.size();i++)
            {
                redisAppendCommand(redis_ctx, pipeline_cmd[i].c_str());
            }

            for (int i = 0; i < pipeline_cmd.size();i++)
            {
                bool status = false;
                std::string resp_str = "";
                redisReply *reply = 0;
                if(redisGetReply(redis_ctx, (void **)&reply) == REDIS_OK
                        && reply != NULL
                        && reply->type == REDIS_REPLY_STRING)
                {
                    status = true;
                    resp_str = reply->str;
                }

                //free
                freeReplyObject(reply);
                pipeline_resp_status.push_back(status);
                pipeline_resp.push_back(resp_str);
            }

            return 0;
}

引數:

struct timeval access_timeout:訪問的超時時間

std::vector<std::string> & pipeline_cmd:pipeline處理的多個請求命令字串

std::vector<std::string> &pipeline_resp:pipeline處理的多個請求返回的字串

std::vector<bool> &pipeline_resp_status:pipeline處理的多個請求返回的狀態