一封報警郵件,大量服務節點 redis 響應超時。html
又來,好煩。linux
redis 響應變慢,查看日誌,發現大量 TimeoutException。redis
大量TimeoutException,說明當前redis服務節點上已經堆積了大量的鏈接查詢,超出redis服務能力,再次嘗試鏈接的客戶端,redis 服務節點直接拒絕,拋出錯誤。安全
那究竟是什麼致使了這種狀況的發生呢?服務器
總結起來,咱們能夠從如下幾方面進行關注:網絡
redis服務所在服務器,物理機的資源競爭及網絡情況等。同一臺服務器上的服務必然面對着服務資源的競爭,CPU,內存,固存等。架構
redis屬於CPU密集型服務,對CPU資源依賴尤其緊密,當所在服務器存在其它CPU密集型應用時,必然會影響redis的服務能力,尤爲是在其它服務對CPU資源消耗不穩定的狀況下。併發
所以,在實際規劃redis這種基礎性數據服務時應該注意一下幾點:tcp
1)通常不要和其它類型的服務進行混部。高併發
2)同類型的redis服務,也應該針對所服務的不一樣上層應用進行資源隔離。
說到CPU關聯性,可能有人會問是否應該對redis服務進行CPU綁定,以下降由CPU上下文切換帶來的性能消耗及關聯影響?
簡單來講,是能夠的,這種優化能夠針對任何CPU親和性要求比較高的服務,可是在此處,有一點咱們也應該特別注意:咱們在 關於redis內存分析,內存優化 中介紹內存時,曾經提到過子進程內存消耗,也就是redis持久化時會fork出子進程進行AOF/RDB持久化任務。對於開啓了持久化配置的redis服務(通常狀況下都會開啓),假如咱們作了CPU親和性處理,那麼redis fork出的子進程則會和父進程共享同一個CPU資源,咱們知道,redis持久化進程是一個很是耗資源的過程,這種自競爭必然會引起redis服務的極大不穩定。
關於redis內存分析,內存優化 開篇就講過,redis最重要的東西,內存。
內存穩定性是redis提供穩定,低延遲服務的最基本的要求。
然而,咱們也知道操做系統有一個 swap 的東西,也就將內存交換到硬盤。假如發生了redis內存被交換到硬盤的情景發生,那麼必然,redis服務能力會驟然降低。
swap發現及避免:
1)info memory:
關於redis內存分析,內存優化 中咱們也講過,swap這種情景,此時,查看redis的內存信息,能夠觀察到碎片率會小於1。這也能夠做爲監控redis服務穩定性的一個指標。
2)經過redis進程查看。
首先經過 info server 獲取進程id:
查看 redis 進程 swap 狀況:cat /proc/1686/smaps
肯定交換量都爲0KB或者4KB。
3)redis服務maxmemory配置。
關於redis內存分析,內存優化 中咱們提到過,對redis服務必要的內存上限配置,這是內存隔離的一種必要。須要肯定的是全部redis實例的分配內存總額小於總的可用物理內存。
4)系統優化:
另外,在最初的基礎服務操做系統安裝部署時,也須要作一些必要的前置優化,如關閉swap或配置系統儘可能避免使用。
網絡問題,是一個廣泛的影響因素。
1)網絡資源耗盡
簡單來講,就是帶寬不夠了,整個屬於基礎資源架構的問題了,對網絡資源的預估不足,跨機房,異地部署等都會成爲誘因。
2)鏈接數用完了
一個客戶端鏈接對應着一個TCP鏈接,一個TCP鏈接在LINUX系統內對應着一個文件句柄,系統級別鏈接句柄用完了,也就沒法再進行鏈接了。
查看當前系統限制:ulimit -n
設置:ulimit -n {num}
3)端口TCP backlog隊列滿了
linux系統對於每一個端口使用backlog保存每個TCP鏈接。
redis配置:tcp_backlog 默認511
高併發情境下,能夠適當調整此配置,但須要注意的是,同時要調整系統相關設置。
系統修改命令:echo {num}>/proc/sys/net/core/somaxconn
查看由於隊列溢出致使的鏈接絕句:netstat -s | grep overflowed
4)網絡延遲
網絡質量問題,可使用 redis-cli 進行網絡情況的測試:
延遲測試:redis-cli -h {host} -p {port} --latency
採樣延遲測試:redis-cli -h {host} -p {port} --latency-history 默認15s一次
圖形線上測試結果:redis-cli -h {host} -p {port} --latency-dist
4)網卡軟中斷
單個網卡隊列只能使用單個CPU資源問題。
若是你的查詢老是慢查詢,那麼必然你的使用存在不合理。
1)你的key規劃是否合理
太長或過短都是不建議的,key須要設置的簡短而有意義。
2)值類型選擇是否合理。
hash仍是string,set仍是zset,避免大對象存儲。
線上能夠經過scan命令進行大對象發現治理。
3)是否可以批查詢
get 仍是 mget;是否應該使用pipeline。
4)禁止線上大數據量操做
查看redis服務運行情況:redis-cli -h {host} -p {port} --stat
keys:當前key總數;mem:內存使用;clients:當前鏈接client數;blocked:阻塞數;requests:累計請求數;connections:累計鏈接數
1)fork子進程影響
redis 進行持久化操做須要fork出子進程。fork子進程自己若是時間過長,則會產生必定的影響。
查看命令最近一次fork耗時:info stats
單位微妙,確保不要超過1s。
2)AOF刷盤阻塞
AOF持久化開啓,後臺每秒進行AOF文件刷盤操做,系統fsync操做將AOF文件同步到硬盤,若是主線程發現距離上一次成功fsync超過2s,則會阻塞後臺線程等待fsync完成以保障數據安全性。
3)THP問題
關於redis內存分析,內存優化 中咱們講過透明大頁問題,linux系統的寫時複製機制會使得每次寫操做引發的頁複製由4KB提高至2M從而致使寫慢查詢。若是慢查詢堆積必然致使後續鏈接問題。