Redis使用的是客戶端-服務端這種CS模型和請求/響應的TCP服務器。這意味着一般狀況下一個請求會遵循如下步驟:java
redis確實是非阻塞,可是redis服務端處理是非阻塞,用戶端來說仍是阻塞。
至於redis爲何這麼快,能夠看這個一文帶你完全掌握Redis爲何這麼快?web
也就是說一個客戶端能夠經過一個socket鏈接發起多個請求命令,每一個請求命令發出後客戶端一般會阻塞並等待redis服務器處理,redis處理完請求命令後會將結果經過響應報文返回給客戶端。由於當執行多條命令的時候都須要等待上條命令執行完畢才能執行,好比:redis
set k1 1 keys * get k1
Redis採起IO因爲通訊會有網絡延遲,假如 client 和 server 之間的包傳輸時間須要0.125秒。那麼上面的三個命令6個報文至少須要0.75秒才能完成。這樣即便 redis 每秒能處理100個命令,而咱們的 client 也只能一秒鐘發出四個命令。這顯然沒有充分利用 redis 的處理能力。編程
咱們已經知道上面的問題了,也知道性能是耗費再了通訊上,這時候pipeline橫空出世,他的目的是將一批命令打包到一個內部維護的queue裏,而後創建socket與server交互,這時候是隻會發送一次命令,也就是隻會交互一次,而後queue內的命令都執行完後會一塊兒返回結果,這樣大大減小了通訊的次數,天然下降了通訊所耗費的時間。queue是先進先出,因此能夠保證執行順序。服務器
並非pipeline就無敵了,之後都用這個。這須要看需求的。好比你的需求get key 實時性很高,並且要用他的返回值作處理。那你把get key這個命令與其餘100個命令放到一塊兒去批處理進行,那反而在業務角度分析,效率更爲低下。微信
以下demo是從http://www.javashuo.com/article/p-gbozipgk-he.html這個地址而來,若有侵權請聯繫我~網絡
/* * 測試普通模式與 PipeLine 模式的效率: * 測試方法:向 redis 中插入 10000 組數據 */ public static void testPipeLineAndNormal(Jedis jedis) throws InterruptedException { Logger logger = Logger.getLogger("javasoft"); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { jedis.set(String.valueOf(i), String.valueOf(i)); } long end = System.currentTimeMillis(); logger.info("the jedis total time is:" + (end - start)); Pipeline pipe = jedis.pipelined(); // 先建立一個 pipeline 的連接對象 long start_pipe = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { pipe.set(String.valueOf(i), String.valueOf(i)); } pipe.sync(); // 獲取全部的 response long end_pipe = System.currentTimeMillis(); logger.info("the pipe total time is:" + (end_pipe - start_pipe)); BlockingQueue<String> logQueue = new LinkedBlockingQueue<String>(); long begin = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { logQueue.put("i=" + i); } long stop = System.currentTimeMillis(); logger.info("the BlockingQueue total time is:" + (stop - begin)); }
不適用場景:socket
適用場景:svg
好比羣發短信、郵件這種,失敗了我補償,我不須要及時知道發送結果的,這種用pipeline合適 。性能
微信公衆號【Java碼農社區】