redis的read error on connection錯誤解決

    昨日,公司php調用redis報錯:read error on connection 2015-01-29 23:59:050.13330000,redis存放的是用戶session。php

    在網上查詢,你們說法都比較一致,說是php.ini文件中的一個配置項致使:redis

    default_socket_timeout = 60服務器

    因爲redis擴展也是基於php 的socket方式實現,所以該參數值一樣會起做用。session

解決方法是:socket

    一、直接修改php.ini,將其設置爲咱們想要的值(這個不推薦)日誌

    二、在咱們的腳本中經過如下方式設置,這樣就比較靈活,不對其餘腳本產生影響blog

ini_set('default_socket_timeout', -1);  //不超時內存

 

    可是,一看,修改的兩個參數,一個是php的全局參數,一個是redis的超時操做,都應該按照實際狀況來修改,並且,設置超長超時時間或者不超時都是不合理的;資源

 

    繼續檢查redis發現,/usr/local/redis_16379/src/redis-cli -p 16379 info(服務器配置的redis端口爲16379,分配內存爲8000M)同步

used_memory_human:7.49G,佔用內存已經7.49G

db10:keys=53090286,鍵值5000多萬

    居然是鍵值佔滿了內存,檢查php的調用代碼,發現php居然沒有設置redis的鍵值過時時間,修改php代碼,對鍵值設置過時時間

 

    設置完以後,發現以前的鍵值由於沒有設置過時時間,程序不會自動刪除,因而用腳本刪除主redis上對應的session,

/usr/local/redis_16379/src/redis-cli -p 16379 -n 10 keys "PHPSESSION_wc*" | xargs /usr/local/redis_16379/src/redis-cli -p 16379 -n 10 del

將大部分過時數據刪除掉,刪除必定數量的數據以後,報錯消失,redis鏈接正常。

 

    可是,發現redis主從,在這樣刪除以後,從數據居然沒有同步,主的數據和從數據差距有400多萬不一致,也沒有再發現bgsave操做,查看從日誌Trying a partial resynchronization,發現由於過濾keys佔用太多資源,形成服務器負載飆升,slave斷開與主機的鏈接,須要從積壓空間中找回斷開期間的數據更新記錄。可是由於刪除數據太多,斷開的時間足夠長,master 拒絕 slave 的部分同步請求,從而 slave 只能進行全同步。

至此,在slave上對數據進行全量同步,數據恢復正常,業務正常。

 

須要注意幾點:

    1.redis數據,正常狀況下,設置過時時間,不然可能出現,存儲鍵值過多,佔用完了預設內存,致使新的鍵值沒法存儲,調用redis失敗的;

    2.超時時間必須根據實際業務來設置;

    3.若是slave一直鏈接不上master,可能須要進行全量同步。

相關文章
相關標籤/搜索