天天看點

redis 簡單整理——用戶端常見異常[十七]

前言

這個還是比較常見的,也就是比較對開發有用的部分。

正文

1.無法從連接配接池擷取到連接配接

JedisPool中的Jedis對象個數是有限的,預設是8個。這裡假設使用的默 認配置,如果有8個Jedis對象被占用,并且沒有歸還,此時調用者還要從 JedisPool中借用Jedis,就需要進行等待(例如設定了maxWaitMillis>0),如 果在maxWaitMillis時間内仍然無法擷取到Jedis對象就會抛出如下異常:

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at 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)
           

可能的原因:

用戶端:

1. 用戶端:高并發下連接配接池設定過小,出現供不應求,是以會出現上面 的錯誤,但是正常情況下隻要比預設的最大連接配接數(8個)多一些即可,因 為正常情況下JedisPool以及Jedis的處理效率足夠高。
2. 用戶端:沒有正确使用連接配接池,比如沒有進行釋放
3. 用戶端:存在慢查詢操作,這些慢查詢持有的Jedis對象歸還速度會比 較慢,造成池子滿了。
           

服務端:

服務端:用戶端是正常的,但是Redis服務端由于一些原因造成了客戶 端指令執行過程的阻塞,也會使得用戶端抛出這種異常。
           

2.用戶端讀寫逾時

造成該異常的原因也有以下幾種: 

·讀寫逾時間設定得過短。 

·指令本身就比較慢。 

·用戶端與服務端網絡不正常。 

·Redis自身發生阻塞。
           
  1. 用戶端連接配接逾時

-1. 連接配接逾時設定得過短

-2. Redis發生阻塞,造成tcp-backlog已滿,造成新的連接配接失敗。

-3. 用戶端與服務端網絡不正常。

  1. 用戶端緩沖區異常

造成這個異常的原因可能有如下幾種:

1)輸出緩沖區滿。例如将普通用戶端的輸出緩沖區設定為1M,如果使用get指令擷取一個bigkey(例如3M),就會出現這個異常。

2)長時間閑置連接配接被服務端主動斷開

  1. 不正常并發讀寫:Jedis對象同時被多個線程并發操作,可能會出現 上述異常

5.Lua腳本正在執行

如果Redis目前正在執行Lua腳本,并且超過了lua-time-limit,此時Jedis調用Redis時,會收到下面的異常。

這個時候使用kill script

  1. Redis正在加載持久化檔案

Jedis調用Redis時,如果Redis正在加載持久化檔案

  1. Redis使用的記憶體超過maxmemory配置

Jedis執行寫操作時,如果Redis的使用記憶體大于maxmemory的設定,會 收到下面的異常,此時應該調整maxmemory并找到造成記憶體增長的原因

  1. 用戶端連接配接數過大

如果用戶端連接配接數超過了maxclients,新申請的連接配接就會出現如下異常

解決方案:

繼續閱讀