1. 程式人生 > >Redis測試分析(pipeline模式推薦)

Redis測試分析(pipeline模式推薦)

測試環境 
Redis測試版本:2.2.12 
使用Java Jedis客戶端進行測試 
測試資料量:50萬, 超過2億 

速度 
1) mset函式插入效率最高,插入Redis的速度達到20萬條資料/秒。但是該函式所耗記憶體較高,對於我們實際應用一表每天2.4億的資料量來說,需要消耗近32G記憶體; 
2) mset函式中當m值達到200以上時,插入速度接近飽和,因此實際應用中,應設定該值 >= 200,以達到最高的插入效率; 
3) set函式除非特定應用場景需求,否則應儘量不要使用,其插入效率為mset函式的1/20; 
4) 儘管不同的函式都有string與byte[]兩種不同的形式,但是對於Redis來說byte[]的形式也是將每個byte看成是一個字元來進行處理的。在實際應用中,對於較長的整型資料(例如:9824224123),可以將其轉換為byte[]的形式,4個byte[]可以儲存一個int資料,這樣會比採用string的形式儲存節省一部分的記憶體開銷; 

5) hset函式插入效率與set函式相當; 
6) hmset由於在實際應用中,每條資料對應的key不相同,需要維護一個本機的快取容器Map<key,Map<field, value>>,因此插入速度要比mset函式慢一些; 

記憶體 
1) hset和 hmset函式大約可以比set和mset函式節省三分之一的記憶體; 
2) hset和hmset函式對於每個key所儲存的<field, value>數目非常敏感。一旦超過限制,插入效率下降十分明顯,同樣,記憶體開銷也會顯著增加。在實際應用中,應儘量保證每個key下面的<field, value>的數目不超過限制(預設值為64)。 


Pipeline 
redis的pipeline(管道)功能在命令列中沒有,但redis是支援pipeline的,而且在各個語言版的client中都有相應的實現。 
Redis本身是一個cs模式的tcp server, client可以通過一個socket連續發起多個請求命令。 每個請求命令發出後client通常會阻塞並等待redis服務端處理,redis服務端處理完後將結果返回給client。 
Java程式碼  收藏程式碼
  1. Client: hset a1 field value  
  2. Server: 1  
  3. Client: hset a2 field value  
  4. Server: 1  
  5. Client: hset a3 field value  
  6. Server: 1  
  7. Client: hset a4 field value  
  8. Server: 1  

這種傳送模式中由於網路開銷延遲,即算redis server端有很強的處理能力,也由於收到的client訊息少,而造成吞吐量小。我們可以修改一種處理模式, 
Java程式碼  收藏程式碼
  1. Client: hset a1 field value  
  2. Client: hset a2 field value  
  3. Client: hset a3 field value  
  4. Client: hset a4 field value  
  5. Server: 1  
  6. Server: 1  
  7. Server: 1  
  8. Server: 1  

通過pipeline方式將client端命令一起發出,redis server會處理完多條命令後,將結果一起打包返回client,從而節省大量的網路延遲開銷。 
下面以Java的客戶端jedis來測試pipeline的效果。 
Java程式碼  收藏程式碼
  1. Pipeline pipeline = jedis.pipelined();  
  2. long start = System.currentTimeMillis();  
  3. for (int i = 0; i < 10000; i++) {  
  4.     pipeline.hset("server""" + i, "" + i);  
  5. }  
  6. List<Object> results = pipeline.execute();  
  7. long end = System.currentTimeMillis();  
  8. System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");  

測試的結果採用pipeline方式,效率幾乎與mset一樣,每秒插入約15萬資料,但記憶體佔用僅為mset的1/3.