1. 程式人生 > >[總結]redis連線超時問題排查

[總結]redis連線超時問題排查

連線池無法獲取到連線或獲取連線超時

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

對於這類問題的原因有幾類,可以根據以下一一進行排查

連線配置錯誤

Jedis連線池配置不可用,redis.host或redis.ip或redis.password 配置有誤,手動檢查配置是否都配置正確。

本地連線池連線數達到最大  

連線池中有配置最大連線數maxTotal,本地連線使用達到最大連線數maxTotal。在訪問客戶端上通過netstat -an | grep 6379 | grep EST | wc -l 檢視客戶端連結數目,如果接近maxTotal, 說明本地連線池資源已經有過耗盡或者正在耗盡。

服務端連線數達到最大

服務端連線數已經超過最大值maxclients,單機的maxclients預設是10000,可以通過redis-cli登入服務端,使用info 命令檢視當前連線數。
$redis-cli -h 10.1**.2.*0 -p 6379
10.1**.2.*0:6379> info clients
# Clients
connected_clients:1004
client_longest_output_list:0
client_biggest_input_buf:1
blocked_clients:0
10.1**.2.*0:6379>
當服務端連線數達到最大,可以通過命令client list,列出連線數,檢視age=130222 idle=130222,這兩值表示連線存活的時間和已經空閒的時間。
假如有IP的連線數過大,有可能是客戶端連線使用不規範導致連線洩露。

網路問題

可以通過客戶端工具redis-cli -h ${IP} -p ${port} -a ${pwd},連線成功後,簡單執行set mykey-i i, del mykey-i 命令,測試redis是否可用。

或者telnet host 6379進行連線,執行多次簡單set del命令測試。

redis連線程式碼檢查

獲取JedisPool連線池中的jedis,使用jedis操作redis,每次getResource之後需要呼叫returnResource或者close進行歸還,可以檢視程式碼在使用完jedis之後是否returnResource,如果沒有歸還,則非常有可能產生連線洩露。

檢查是否發生nf_conntrack丟包

通過dmesg檢查客戶端是否有異常

nf_conntrack: table full, dropping packet

如果發生nf_conntract丟包可以通過修改設定sysctl -w net.netfilter.nf_conntrack_max=120000

檢查是否TIME_WAIT問題

通過ss -s 檢視time wait連結是否過多

[[email protected] ~]# ss -s
Total: 314 (kernel 4877)
TCP:   32 (estab 3, closed 1, orphaned 0, synrecv 0, timewait 0/0), ports 0


Transport Total     IP        IPv6
*  4877      -         -
RAW  1         0         1
UDP  2         1         1
TCP  31        13        18
INET  34        14        20
FRAG  0         0         0


如果TIME_WAIT過多可以修改以下引數
sysctl -w net.ipv4.tcp_max_tw_buckets=180000
sysctl -w net.ipv4.tcp_tw_recycle=1

linux檔案系統控制代碼數過小

設定redis同時可以與多少個客戶端進行連線。預設情況下為10000個客戶端。當你

無法設定程序檔案控制代碼限制時,redis會設定為當前的檔案控制代碼限制值減去32,因為redis會為自身內部處理邏輯留一些控制代碼出來。如果達到了此限制,redis則會拒絕新的連線請求,並且向這些連線請求方發出“max number of clients reached”以作迴應。


抓包分析

如果按照上面排查之後還有問題可以通過抓包進行分析。

抓包命令為sudo tcpdump -i eth0 tcp and port 6379 -n -nn -s 74 -w redis.cap。