1. 程式人生 > >redis知識盤點【陸】_客戶端Jedis

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