一、客戶端相關配置
①客戶端的限制maxclients
Redis提供了maxclients參數來限制最大客戶端連接數,一旦連接數超過 maxclients,新的連接將被拒絕
maxclients默認值是10000
可以通過info clients來查詢當前Redis的連接數:
可以通過config set maxclients對最大客戶端連接數進行動態設置:
但是這個參數會受到操作系統設置的限制,在后面“Redis實踐篇的陷阱文章中還會介紹”
②客戶端的限制timeout
一般來說maxclients=10000在大部分場景下已經絕對夠用,但是某些情況由于業務方使用不當(例如沒有主動關閉連接)可能存在大量idle連接, 無論是從網絡連接的成本還是超過maxclients的后果來說都不是什么好事,?因此Redis提供了timeout(單位為秒)參數來限制連接的最大空閑時間,一 旦客戶端連接的idle時間超過了timeout,連接將會被關閉
timeout默認為0,也就是不會檢測客戶端的空閑
該參數也可以動態設置。例如設置timeout為30秒:
演示案例
下面繼續使用Jedis進行模擬,整個代碼和上面是一樣的,只不過第2) 步驟休息了31秒:
String key = "hello";
// 1) 生成jedis,并執行get操作
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.get(key));
// 2) 休息31秒
TimeUnit.SECONDS.sleep(31);
// 3) 執行get操作
System.out.println(jedis.get(key));
// 4) 休息5秒
TimeUnit.SECONDS.sleep(5);
// 5) 關閉jedis連接
jedis.close();
執行上述代碼可以發現在執行完第2)步之后,client list中已經沒有了 Jedis的連接,也就是說timeout已經生效,將超過30秒空閑的連接關閉掉:
同時可以看到,在Jedis代碼中的第3)步拋出了異常,因為此時客戶端 已經被關閉,所以拋出的異常是JedisConnectionException,并且提示 Unexpected end of stream:
如果將Redis的loglevel設置成debug級別,可以看到如下日志,也就是客 戶端被Redis關閉的日志:
Redis源碼中redis.c文件中clientsCronHandleTimeout函數就是針對timeout 參數進行檢驗的,只不過在源碼中timeout被賦值給了server.maxidletime:
int?clientsCronHandleTimeout(redisClient?*c)?{//?當前時間time_t?now?=?server.unixtime;//?server.maxidletime就是參數timeoutif?(server.maxidletime?&&//?很多客戶端驗證,這里就不占用篇幅,最重要的驗證是下面空閑時間超過了maxidletime就會//?被關閉掉客戶端(now?-?c->lastinteraction?>?server.maxidletime)){redisLog(REDIS_VERBOSE,"Closing?idle?client");//?關閉客戶端freeClient(c);}}
Redis的默認配置給出的timeout=0,在這種情況下客戶端基本不會出現上面的異常,這是基于對客戶端開發的一種保護。例如很多開發人員在使用JedisPool時不會對連接池對象做空閑檢測和驗證,如果設置了timeout>0,可 能就會出現上面的異常,對應用業務造成一定影響,但是如果Redis的客戶 端使用不當或者客戶端本身的一些問題,造成沒有及時釋放客戶端連接,可能會造成大量的idle連接占據著很多連接資源,一旦超過maxclients;后果也是不堪設想。所在在實際開發和運維中,需要將timeout設置成大于0,例如 可以設置為300秒,同時在客戶端使用上添加空閑檢測和驗證等等措施,例如JedisPool使用common-pool提供的三個屬性:minEvictableIdleTimeMillis、 testWhileIdle、timeBetweenEvictionRunsMillis
③tcp-keepalive
檢測TCP連接活性的周期
默認值為300
如果需要設置,建議為60,那么Redis會每隔60秒對它創建的TCP連接進行活性檢測,防止大量死連接占用系統資源
④tcp-backlog
TCP三次握手后,會將接受的連接放入隊列中,tcpbacklog就是隊列的大小
它在Redis中的默認值是511
修改方法也非常簡單,只需要執行如下命令
echo 511 > /proc/sys/net/core/somaxconn
通常來講這個參數不需要調整,但是這個參數會受到操作系統的影響。例如在Linux操作系統 中,如果/proc/sys/net/core/somaxconn小于tcp-backlog,那么在Redis啟動時會 看到如下日志,并建議將/proc/sys/net/core/somaxconn設置更大
二、客戶端統計片段
info clients
例如下面就是一次info clients的執行結果:
?
說明如下:
connected_clients:代表當前Redis節點的客戶端連接數,需要重點監控,一旦超過maxclients,新的客戶端連接將被拒絕
client_recent_max_output_buffer:當前所有輸出緩沖區中隊列對象個數的最大值
client_recent_max_input_buffer:當前所有輸入緩沖區中占用的最大容量
blocked_clients:正在執行阻塞命令(例如blpop、brpop、 brpoplpush)的客戶端個數
info stats
參數說明:
total_connections_received:Redis自啟動以來處理的客戶端連接數總數
rejected_connections:Redis自啟動以來拒絕的客戶端連接數,需要重點監控