redis知識盤點【陸】_客戶端Jedis
系列文章:
本篇文章主要介紹一下redis的客戶端Jedis。
首先明確兩點:一、redis客戶端與服務端之間的通訊協議是在TCP協議之上構建的;二、Redis制定了RESP(REdis Serialization Protocol,Redis序列化協議)實現客戶端與服務端的正常互動,這種協議簡單高效,既能夠被機器解析,又容易被人類識別。
在java工程中,我們一般使用Jedis作為客戶端和redis伺服器進行互動,而當我們配置Jedis連線池的時候,有如下引數需要關注:
GenericObjectPoolConfig配置項
客戶端常見異常
1.無法從連線池獲取到連線
JedisPool中的Jedis物件個數是有限的,預設是8個。這裡假設使用的預設配置,如果有8個Jedis物件被佔用,並且沒有歸還,此時呼叫者還要從JedisPool中借用Jedis,就需要進行等待(例如設定了maxWaitMillis>0),如果在maxWaitMillis時間內仍然無法獲取到Jedis物件就會丟擲如下異常:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resourcefrom the pool
…
Caused by: java.util.NoSuchElementException: Timeout waiting for idle objectat org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
還有一種情況,就是設定了blockWhenExhausted=false,那麼呼叫者發現池中沒有資源時,會立即丟擲異常不進行等待,下面的異常就是blockWhenExhausted=false時的效果:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Pool exhausted at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)
2.客戶端讀寫超時
Jedis在呼叫Redis時,如果出現了讀寫超時後,會出現下面的異常:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
造成該異常的原因也有以下幾種:
1.讀寫超時間設定得過短;
2命令本身就比較慢;
3客戶端與服務端網路不正常;
4·Redis自身發生阻塞;
3.客戶端連線超時
Jedis在呼叫Redis時,如果出現了連線超時後,會出現下面的異常:
redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: connect timed out
造成該異常的原因也有以下幾種:
1.連線超時設定得過短,可以通過下面程式碼進行設定:
2.Redis發生阻塞,造成tcp-backlog已滿,造成新的連線失敗;
3.客戶端與服務端網路不正常;
4.客戶端緩衝區異常
Jedis在呼叫Redis時,如果出現客戶端資料流異常,會出現下面的異常:
redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
造成這個異常的原因可能有如下幾種:
1)輸出緩衝區滿。例如將普通客戶端的輸出緩衝區設定為1M 1M 60:
config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456
67108864 60 pubsub 33554432 8388608 60"
2)長時間閒置連線被服務端主動斷開,上節已經詳細分析了這個問題。
3)不正常併發讀寫:Jedis物件同時被多個執行緒併發操作,可能會出現上述異常。
5.Redis正在載入持久化檔案
Jedis呼叫Redis時,如果Redis正在載入持久化檔案,那麼會收到下面的異常:
redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory
6.Redis使用的記憶體超過maxmemory配置
Jedis執行寫操作時,如果Redis的使用記憶體大於maxmemory的設定,會收到下面的異常,此時應該調整maxmemory並找到造成記憶體增長的原因:
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when
used memory > 'maxmemory'.
7.客戶端連線數過大
如果客戶端連線數超過了maxclients,新申請的連線就會出現如下異常:
redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached