Redis學習筆記7--[Redis管道(pipeline)](https://blog.csdn.net/freebird_lb/article/details/7778919)
* * * * *
redis是一個cs模式的tcp server,使用和http類似的請求響應協議。一個client可以通過一個socket連接發起多個請求命令。每個請求命令發出后client通常會阻塞并等待redis服務處理,redis處理完后請求命令后會將結果通過響應報文返回給client。基本的通信過程如下:
> Client: INCR X
> Server: 1
> Client: INCR X
> Server: 2
> Client: INCR X
> Server: 3
> Client: INCR X
> Server: 4
基本上四個命令需要8個tcp報文才能完成。由于通信會有網絡延遲,假如從client和server之間的包傳輸時間需要0.125秒。那么上面的四個命令8個報文至少會需要1秒才能完成。這樣即使redis每秒能處理100個命令,而我們的client也只能一秒鐘發出四個命令。這顯示沒有充分利用 redis的處理能力。除了可以利用mget,mset 之類的單條命令處理多個key的命令外我們還可以利用pipeline的方式從client打包多條命令一起發出,不需要等待單條命令的響應返回,而redis服務端會處理完多條命令后會將多條命令的處理結果打包到一起返回給客戶端。通信過程如下:
> Client: INCR X
> Client: INCR X
> Client: INCR X
> Client: INCR X
> Server: 1
> Server: 2
> Server: 3
> Server: 4
假設不會因為tcp報文過長而被拆分。可能兩個tcp報文就能完成四條命令,client可以將四個incr命令放到一個tcp報文一起發送,server則可以將四條命令的處理結果放到一個tcp報文返回。通過pipeline方式當有大批量的操作時候。我們可以節省很多原來浪費在網絡延遲的時間。需要注意到是用 pipeline方式打包命令發送,redis必須在處理完所有命令前先緩存起所有命令的處理結果。打包的命令越多,緩存消耗內存也越多。所以并是不是打包的命令越多越好。具體多少合適需要根據具體情況測試。下面是個jedis客戶端使用pipeline的測試:
~~~
package com.jd.redis.client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
publicclass PipelineTest {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
int count = 1000;
long start = System.currentTimeMillis();
withoutPipeline(count);
long end = System.currentTimeMillis();
System.out.println("withoutPipeline: " + (end-start));
start = System.currentTimeMillis();
usePipeline(count);
end = System.currentTimeMillis();
System.out.println("usePipeline: " + (end-start));
}
privatestaticvoid withoutPipeline(int count){
Jedis jr = null;
try {
jr = new Jedis("10.10.224.44", 6379);
for(int i =0; i<count; i++){
jr.incr("testKey1");
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(jr!=null){
jr.disconnect();
}
}
}
privatestaticvoid usePipeline(int count){
Jedis jr = null;
try {
jr = new Jedis("10.10.224.44", 6379);
Pipeline pl = jr.pipelined();
for(int i =0; i<count; i++){
pl.incr("testKey2");
}
pl.sync();
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(jr!=null){
jr.disconnect();
}
}
}
}
~~~
輸出:
> withoutPipeline: 11341
> usePipeline: 344
測試結果還是很明顯有較大的差距,所以多次操作用pipeline還是有明顯的優勢。我用的是Win7中的Jedis Java客戶端程序連接局域網的Linux虛擬機上的Redis Server。
- 目錄
- 安裝擴展
- 在 Windows 上安裝 PHP 擴展
- 測試Redis擴展函數
- 教程
- 簡介
- Redis 安裝
- Redis 配置
- 運行
- 測試
- 書籍
- 《Redis開發與運維》
- 《Redis入門指南》
- 《Redis實戰》
- 《當 Redis 遇上 ThinkPHP5》
- 參考站點
- 下載
- 命令參考
- 管理工具
- 視頻
- 云數據庫 Redis 版使用教程
- Redis 深入之道
- Redis高可用教程
- Redis入門
- NoSQL概述
- Redis概述
- Redis安裝
- Jedis入門
- PHP命令
- PHP中利用Redis管道加快執行
- Hash操作
- Set操作
- Gearman
- MySQL - Redis配合使用方案
- 應用場景
- 緩存應用
- Redis實現簡單的條件查詢功能
- 獲取網站中點擊量最高的前n篇文章
- 顯示最新的項目列表
- 排行榜相關
- 設計技巧
- SortedSets
- List列表
- 消息隊列
- 最新文章
- Set集合
- 共同好友
- 獨立 IP
- Linux教程
- 常用命令
- 哈希命令
- 字符串
- 集合
- 有序集合
- Redis 有序集合命令
- 有序集合命令(中)
- 發布訂閱
- 用例
- 列表
- Lindex
- Ltrim
- Rpush
- Lset
- Llen
- Lpush
- 信息
- info memory
- 安裝
- 數據類型
- Redis管道(pipeline)
- Memory Command
- 阿里云Redis
- 架構
- 4.0版本
- Redis 4.0 新功能介紹
- Redis Desktop Manager
- 創建hash列表數據
- Lua: 給 Redis 用戶的入門指導
- Lua入門
- 樂觀鎖介紹
- 悲觀鎖介紹
- 臟數據
- Redis核心概念
- Redis事務
- Lua
- 在Redis中使用lua腳本
- php-redis
- mysql緩存服務器
- redis setnx 實現分布式鎖和單機鎖
- 為什么分布式一定要有Redis?