標籤:
江湖傳言,在redis中,一個command("get or set key value")中value的長度超過1k的時候,其效能急劇下降。
稍微看了下redis的代碼,發現它的網路模組關閉了nagel演算法,如果修改redis的源碼啟動這個演算法會如何呢?
1 採用redis預設代碼測試(即關閉nagel演算法)
為了驗證這個演算法啟用與否,是否影響了redis的效能。先不改變redis的代碼,利用redis-benchmark進行一番測試,執行下面的命令:
./redis-benchmark -p 30000 -n 50000 -k 1 -d 2048 -q
上面命令相關參數意義為:串連伺服器斷開30000、測試50000次、開啟keepalive選項、value長度2k、只輸出結果不輸出測試過程。
測試結果是:
SET: 51599.59 requests per secondGET: 50403.23 requests per secondINCR: 55493.89 requests per secondLPUSH: 54112.55 requests per secondLPOP: 48875.86 requests per secondSADD: 54644.81 requests per secondSPOP: 54112.55 requests per secondLPUSH (needed to benchmark LRANGE): 49067.71 requests per secondLRANGE_600 (first 600 elements): 400.68 requests per secondMSET (10 keys): 33134.53 requests per second
2 採用socket預設屬性
下面是/redis-2.8.19/networking.c的createClient函數:
53 redisClient *createClient(int fd) { 54 redisClient *c = zmalloc(sizeof(redisClient)); 55 56 /* passing -1 as fd it is possible to create a non connected client. 57 * This is useful since all the Redis commands needs to be executed 58 * in the context of a client. When commands are executed in other 59 * contexts (for instance a Lua script) we need a non connected client. */ 60 if (fd != -1) { 61 anetNonBlock(NULL,fd); 62 // anetEnableTcpNoDelay(NULL,fd); 63 if (server.tcpkeepalive) 64 anetKeepAlive(NULL,fd,server.tcpkeepalive); 65 if (aeCreateFileEvent(server.el,fd,AE_READABLE, 66 readQueryFromClient, c) == AE_ERR) 67 { 68 close(fd); 69 zfree(c); 70 return NULL; 71 } 72 }
請注意,我已經把line 62注釋掉,採用系統預設設定。
執行同樣的命令,其測試結果為:
SET: 50968.40 requests per secondGET: 50607.29 requests per secondINCR: 55432.37 requests per secondLPUSH: 47438.33 requests per secondLPOP: 49950.05 requests per secondSADD: 54945.05 requests per secondSPOP: 55187.64 requests per secondLPUSH (needed to benchmark LRANGE): 47709.93 requests per secondLRANGE_600 (first 600 elements): 398.41 requests per secondMSET (10 keys): 26766.60 requests per second
3 明確啟用Nagel演算法
同樣地,可以修改代碼以明確啟用Nagel演算法,同樣的代碼塊修改後為:
53 redisClient *createClient(int fd) { 54 redisClient *c = zmalloc(sizeof(redisClient)); 55 56 /* passing -1 as fd it is possible to create a non connected client. 57 * This is useful since all the Redis commands needs to be executed 58 * in the context of a client. When commands are executed in other 59 * contexts (for instance a Lua script) we need a non connected client. */ 60 if (fd != -1) { 61 anetNonBlock(NULL,fd); 62 // anetEnableTcpNoDelay(NULL,fd); 63 anetDisableTcpNoDelay(NULL,fd); 64 if (server.tcpkeepalive) 65 anetKeepAlive(NULL,fd,server.tcpkeepalive); 66 if (aeCreateFileEvent(server.el,fd,AE_READABLE, 67 readQueryFromClient, c) == AE_ERR) 68 { 69 close(fd); 70 zfree(c); 71 return NULL; 72 } 73 }
明確地啟用Nagel演算法後,其測試結果為:
SET: 49164.21 requests per secondGET: 48496.61 requests per secondINCR: 52910.05 requests per secondLPUSH: 50556.12 requests per secondLPOP: 49164.21 requests per secondSADD: 53937.43 requests per secondSPOP: 53248.14 requests per secondLPUSH (needed to benchmark LRANGE): 48169.56 requests per secondLRANGE_600 (first 600 elements): 406.73 requests per secondMSET (10 keys): 34106.41 requests per second
4 總結
從以上對比結果來看,大部分情況下啟用nagel演算法後,redis的效能約有百分之二的提升。
提高redis效能一指禪