管道傳輸__最佳實踐_雲數據庫 Redis 版-阿裏雲
管道傳輸(pipeline)
場景介紹
ApsaraDB for Redis 提供了與 Redis 相同的管道傳輸(pipeline)機製。管道(pipeline)將客戶端 client 與服務器端的交互明確劃分為單向的發送請求(Send Request)和接收響應(Receive Response):用戶可以將多個操作連續發給服務器,但在此期間服務器端並不對每個操作命令發送響應數據;全部請求發送完畢後用戶關閉請求,開始接收響應獲取每個操作命令的響應結果。
管道(pipeline)在某些場景下非常有用,比如有多個操作命令需要被迅速提交至服務器端,但用戶並不依賴每個操作返回的響應結果,對結果響應也無需立即獲得,那麼管道就可以用來作為優化性能的批處理工具。性能提升的原因主要是減少了 TCP 連接中交互往返的開銷。
不過在程序中使用管道請注意,使用 pipeline 時客戶端將獨占與服務器端的連接,此期間將不能進行其他“非管道”類型操作,直至 pipeline 被關閉;如果要同時執行其他操作,可以為 pipeline 操作單獨建立一個連接,將其與常規操作分離開來。
代碼示例1
性能對比
package pipeline.kvstore.aliyun.com;import java.util.Date;import redis.clients.jedis.Jedis;import redis.clients.jedis.Pipeline;public class RedisPipelinePerformanceTest {static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";static final int port = 6379;static final String password = "password";public static void main(String[] args) {Jedis jedis = new Jedis(host, port);//ApsaraDB for Redis的實例ID及密碼String authString = jedis.auth(password);// passwordif (!authString.equals("OK")) {System.err.println("AUTH Failed: " + authString);jedis.close();return;}//連續執行多次命令操作final int COUNT=5000;String key = "KVStore-Tanghan";// 1 ---不使用pipeline操作---jedis.del(key);//初始化keyDate ts1 = new Date();for (int i = 0; i < COUNT; i++) {//發送一個請求,並接收一個響應(Send Request and Receive Response)jedis.incr(key);}Date ts2 = new Date();System.out.println("不用Pipeline > value為:"+jedis.get(key)+" > 操作用時:" + (ts2.getTime() - ts1.getTime())+ "ms");//2 ----對比使用pipeline操作---jedis.del(key);//初始化keyPipeline p1 = jedis.pipelined();Date ts3 = new Date();for (int i = 0; i < COUNT; i++) {//發出請求 Send Requestp1.incr(key);}//接收響應 Receive Responsep1.sync();Date ts4 = new Date();System.out.println("使用Pipeline > value為:"+jedis.get(key)+" > 操作用時:" + (ts4.getTime() - ts3.getTime())+ "ms");jedis.close();}}
運行結果1
在輸入了正確的 ApsaraDB for Redis 實例訪問地址和密碼之後,運行以上 Java 程序,輸出結果如下。從中可以看出使用 pipeline 的性能要快的多。
不用Pipeline > value為:5000 > 操作用時:5844ms使用Pipeline > value為:5000 > 操作用時:78ms
代碼示例2
在 Jedis 中使用管道(pipeline)時,對於響應數據(response)的處理有兩種方式,請參考以下代碼示例。
package pipeline.kvstore.aliyun.com;import java.util.List;import redis.clients.jedis.Jedis;import redis.clients.jedis.Pipeline;import redis.clients.jedis.Response;public class PipelineClientTest {static final String host = "xxxxxxxx.m.cnhza.kvstore.aliyuncs.com";static final int port = 6379;static final String password = "password";public static void main(String[] args) {Jedis jedis = new Jedis(host, port);// ApsaraDB for Redis的實例ID及密碼String authString = jedis.auth(password);// passwordif (!authString.equals("OK")) {System.err.println("AUTH Failed: " + authString);jedis.close();return;}String key = "KVStore-Test1";jedis.del(key);//初始化// -------- 方法1Pipeline p1 = jedis.pipelined();System.out.println("-----方法1-----");for (int i = 0; i < 5; i++) {p1.incr(key);System.out.println("Pipeline發送請求");}// 發送請求完成,開始接收響應System.out.println("發送請求完成,開始接收響應");List<Object> responses = p1.syncAndReturnAll();if (responses == null || responses.isEmpty()) {jedis.close();throw new RuntimeException("Pipeline error: 沒有接收到響應");}for (Object resp : responses) {System.out.println("Pipeline接收響應Response: " + resp.toString());}System.out.println();//-------- 方法2System.out.println("-----方法2-----");jedis.del(key);//初始化Pipeline p2 = jedis.pipelined();//需要先聲明ResponseResponse<Long> r1 = p2.incr(key);System.out.println("Pipeline發送請求");Response<Long> r2 = p2.incr(key);System.out.println("Pipeline發送請求");Response<Long> r3 = p2.incr(key);System.out.println("Pipeline發送請求");Response<Long> r4 = p2.incr(key);System.out.println("Pipeline發送請求");Response<Long> r5 = p2.incr(key);System.out.println("Pipeline發送請求");try{r1.get(); //此時還未開始接收響應,所以此操作會出錯}catch(Exception e){System.out.println(" <<< Pipeline error:還未開始接收響應 >>> ");}// 發送請求完成,開始接收響應System.out.println("發送請求完成,開始接收響應");p2.sync();System.out.println("Pipeline接收響應Response: " + r1.get());System.out.println("Pipeline接收響應Response: " + r2.get());System.out.println("Pipeline接收響應Response: " + r3.get());System.out.println("Pipeline接收響應Response: " + r4.get());System.out.println("Pipeline接收響應Response: " + r5.get());jedis.close();}}
運行結果2
在輸入了正確的 ApsaraDB for Redis 實例訪問地址和密碼之後,運行以上 Java 程序,輸出結果如下:
-----方法1-----Pipeline發送請求Pipeline發送請求Pipeline發送請求Pipeline發送請求Pipeline發送請求發送請求完成,開始接收響應Pipeline接收響應Response: 1Pipeline接收響應Response: 2Pipeline接收響應Response: 3Pipeline接收響應Response: 4Pipeline接收響應Response: 5-----方法2-----Pipeline發送請求Pipeline發送請求Pipeline發送請求Pipeline發送請求Pipeline發送請求<<< Pipeline error:還未開始接收響應 >>>發送請求完成,開始接收響應Pipeline接收響應Response: 1Pipeline接收響應Response: 2Pipeline接收響應Response: 3Pipeline接收響應Response: 4Pipeline接收響應Response: 5
最後更新:2016-12-16 17:25:21
上一篇:
消息發布與訂閱__最佳實踐_雲數據庫 Redis 版-阿裏雲
下一篇:
事務處理__最佳實踐_雲數據庫 Redis 版-阿裏雲
停止實例__實例相關接口_API 參考_雲服務器 ECS-阿裏雲
導出數據庫__導出數據_數據管理_用戶指南(RDBMS)_數據管理-阿裏雲
刪除磁盤__磁盤相關接口_API 參考_雲服務器 ECS-阿裏雲
錯誤日誌__應用操作接口_API參考手冊_開放搜索-阿裏雲
計量計費說明__計量計費_大數據計算服務-阿裏雲
解析線路枚舉__枚舉類型_API文檔_雲解析-阿裏雲
資源申請__MQTT 接入準備_MQTT 接入(物聯)_消息隊列 MQ-阿裏雲
Google Authenticator安裝及使用指導__附錄2: _用戶指南_訪問控製-阿裏雲
ALIYUN::ECS::InstanceGroupClone__資源列表_資源編排-阿裏雲
快速指引__DataHub實時數據通道_大數據計算服務-阿裏雲
相關內容
常見錯誤說明__附錄_大數據計算服務-阿裏雲
發送短信接口__API使用手冊_短信服務-阿裏雲
接口文檔__Android_安全組件教程_移動安全-阿裏雲
運營商錯誤碼(聯通)__常見問題_短信服務-阿裏雲
設置短信模板__使用手冊_短信服務-阿裏雲
OSS 權限問題及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
消息通知__操作指南_批量計算-阿裏雲
設備端快速接入(MQTT)__快速開始_阿裏雲物聯網套件-阿裏雲
查詢API調用流量數據__API管理相關接口_API_API 網關-阿裏雲
使用STS訪問__JavaScript-SDK_SDK 參考_對象存儲 OSS-阿裏雲