Redis緩沖區設置


對於Redis服務器的輸出(也就是命令的返回值)來說,其大小通常是不可控制的。有可能一個簡單的命令,能夠產生體積龐大的返回數據。另外也有可能因為執行了太多命令,導致產生返回數據的速率超過了往客戶端發送的速率,這是也會導致服務器堆積大量消息,從而導致輸出緩沖區越來越大,占用過多內存,甚至導致系統崩潰。

所幸,Redis設置了一些保護機制來避免這種情況的出現,不同類型的客戶端有不同的限制參數。限制方式有如下兩種:

(1)、大小限制,當某一個客戶端的緩沖區超過某一個大小值時,直接關閉這個客戶端的連接;

(2)、持續性限制,當某一個客戶端的緩沖區持續一段時間占用過大空間時,會直接關閉客戶端連接。

 

我們來看看配置文件關於客戶端輸出緩沖區的配置:

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 8mb 2mb 60

 

不同客戶端有不同策略,策略如下:

Ø  對於普通客戶端來說,限制為0,也就是不限制。因為普通客戶端通常采用阻塞式的消息應答模式,何謂阻塞式呢?如:發送請求,等待返回,再發送請求,再等待返回。這種模式下,通常不會導致Redis服務器輸出緩沖區的堆積膨脹;

Ø  對於Pub/Sub客戶端(也就是發布/訂閱模式),大小限制是8M,當輸出緩沖區超過8M時,會關閉連接。持續性限制是,當客戶端緩沖區大小持續60秒超過2M,則關閉客戶端連接;

Ø  對於slave客戶端來說,大小限制是256M,持續性限制是當客戶端緩沖區大小持續60秒超過64M,則關閉客戶端連接。

上述三種規則都是可以修改的。可以通過CONFIG SET 命令設置或者直接修改redis.conf文件。

 

 

 

 

 

 

 

jedis 的 Unexpected end of stream 解決方案

  • redis 服務端版本號:2.8.X
  • Jedis 客戶端版本號:2.8.1
  • 單線程、無並發操作

Jedis單鏈接、JedisPool、ShardedJedisPool,無論使用哪一種方式對 redis 服務進行操作,均出現了 Unexpected end of stream 的問題。

通過查看源碼發現,報錯具體位置是:RedisInputStream 類的 ensureFill() 方法

private void ensureFill() throws JedisConnectionException { if (count >= limit) { try { limit = in.read(buf); count = 0; if (limit == -1) { throw new JedisConnectionException("Unexpected end of stream."); } } catch (IOException e) { throw new JedisConnectionException(e); } } }

 

解決方案:

第一步,檢查 redis config 中的 client-output-buffer-limit 配置

client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 0 0 0 client-output-buffer-limit pubsub 0 0 0
  • 1
  • 2
  • 3

請根據實際情況合理設置Redis輸出緩沖區限制,確定不是因為緩沖區太小,導致鏈接關閉,進而引起 Unexpected end of stream ,可以臨時都設置成 “0(關閉緩沖區限制)” 來驗證此種場景

第二步,檢查 redis config 中的 timeout 配置

當此時間設置過短時,同一個 jedis 鏈接,兩次訪問 redis 服務的時間間隔 > ${timeout} , 服務端會單方關閉這個jedis鏈接,第二次使用這個jedis對象 操作 redis 時,會發生 Unexpected end of stream , 可以將其設置成“0(無過期)”來驗證此種場景

第三步,優化客戶端代碼,增加重試機制

經過前兩步的調試,根據業務實際情況,調整配置,但這樣並不能完全杜絕 Unexpected end of stream 的發生,比如 “網絡抖動”之類的場景下,依然會發生此問題(實際生產環境中,此種情況發生概率極低), 
但是為了防止此異常引起 jvm宕機,建議在代碼層面上增加加重試機制。

話外篇:

使用 redis 做存儲層時,有可能出現數數據不一致的情況( redis 無事務)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM