首發於redis 的 管道 (pipelining)是用來打包多條無關命令批量執行,以減少多個命令分別執行帶來的網路互動時間。在一些批量運算元據的場景,使用管道可以顯著提公升 redis 的讀寫效能。樊浩柏科學院
redis 的管道實質就是命令打包批量執行,多次網路互動減少到單次。使用管道和不使用管道時的互動過程如下:
我們使用 nc 命令來直觀感受下 redis 管道的使用過程:
# 安裝nc命令
$ yum install nc
# nc打包多個命令
$ (printf "ping\r\nping\r\nping\r\n") | nc localhost 6379
# 響應
+pong
+pong
+pong
```
因此,只要通過管道進行命令打包後,redis 就可以批量返回命令的執行結果了。
首先,構造示例需要的 hash 使用者資料:
$keyprex = 'user:hash:u:';
for ($i=1; $i<=10000; $i++)
```
然後,檢視匯入 redis 中的資料:
127.0.0.1:6379> keys user:hash:u:*
9997) "user:hash:u:3013"
9998) "user:hash:u:8971"
9999) "user:hash:u:4761"
10000) "user:hash:u:1828"
127.0.0.1:6379> hgetall user#️⃣u:1828
「name」
「ggrg」
「age」
「23」
「***」
「0」「is_new」
「1」
在某個社交活動中,通過一系列篩選邏輯後取得種子使用者 uid,然後用這些 uid 去 hash 獲取使用者的資訊。這種情況下你會怎麼來處理呢?
一般情況下,在資料量較小時,我們會直接使用 hgetall 命令遍歷地獲取使用者資料。
$start = nowtime();
foreach (range(1, 1000) as $id)
因為通過 uid 批量獲取使用者資料,各個命令並沒有依賴關係,所以可以使用 redis 的管道來優化查詢。
$start = nowtime();
$redis->multi(redis::pipeline);
foreach (range(1, 1000) as $id)
$user = $redis->exec();
使用管道後,執行時間顯著地減少為:6ms。使用 tcpdump 抓取打包後的命令如下:
10:45:03.029049 ip localhost.58176 > localhost.6379: flags [p.], seq 2255478840:2255479211, ack 3144685411, win 342, options [nop,nop,ts val 17640474 ecr 17640474], length 371
e..../@[email protected][email protected].......
,.*2
$7hgetall
$13user:hash:u:1
*2$7
hgetall
$13user:hash:u:2
*2$7
... ...
在批量操作(查詢和寫入)資料時,我們應盡量避免多次跟 redis 的網路互動。這時,可以使用管道實現,也可以 redis 內嵌 lua 指令碼實現。需要注意的是:
在批量獲取資料時,儘管使用 redis 的管道效能會顯著提公升,但是使用管道時 redis 會快取之前命令的結果,最後一併輸出給終端,因此所打包的命令不宜太多,否則記憶體使用會很嚴重。
使用管道操作redis
1.利用管道獲取資料 獲取redis存的所有資料 return public static jsonarray getallentity pip.sync for string k responses.keyset catch exception e finally return array 2.利...
使用python操作redis(管道)
一 redis連線 redis提供兩個類redis和strictredis用於實現redis的命令,strictredis用於實現大部分官方的命令,並使用官方的語法和命令,redis是strictredis的子類,用於向後相容舊版本的redis py。redis連線例項是執行緒安全的,可以直接將re...
使用tcmalloc提公升mysql效能
網上搜到了tcmalloc,說是這個東西可以讓mysql在高併發下效能也很穩定,同時也說了mysql這個問題是因為malloc記憶體分配函式的bug,這個bug會使高併發的mysql效能急劇下降。使用google的tcmalloc 記憶體分配函式代替libc裡的標準malloc.google的開源效...