QPS過萬,Redis大量連接超時怎么解決?
之前負責的一個服務總是在高峰時刻和壓測發(fā)生大量的redis連接超時的異常redis.clients.jedis.exceptions.JedisConnectionException,根據(jù)原有的業(yè)務規(guī)則,首先會從數(shù)據(jù)庫查詢,然后緩存到redis中,超時時間設置為3分鐘。
并且由于業(yè)務的特性,本身未做降級、限流等處理措施,而在巔峰的QPS基本上快達到20000的樣子,雖然這個現(xiàn)象只是單純的一個異常,并不會導致整個主鏈路的流程不可用,但是我們還是要找出問題的原因并且解決。
首先我們找到負責Redis同學排查,他們告訴我Redis現(xiàn)在很穩(wěn)定,沒有問題,以前現(xiàn)在未來都不會出問題,出了問題肯定是你們自己的問題。
... ...
說的好有道理,我竟無力反駁,真是讓人兩個頭一個大。
這樣的話,我們就只能去找找自身的原因了。
排查思路
查看異常分布
首先根據(jù)經(jīng)驗,我們看看自己的服務器的情況,看下異常到底出現(xiàn)在哪些機器,通過監(jiān)控切換到單機維度,看看異常是否均勻分布,如果分布不均勻,只是少量的host特別高,基本可以定位到出現(xiàn)問題的機器。
誒,這就很舒服了,這一下子就找到了問題,只有幾臺機器異常非常高。
不過不能這樣,我們繼續(xù)說排查思路......
Redis情況
再次按照經(jīng)驗,雖然負責redis的同學說redis賊穩(wěn)定巴拉巴拉,但是我們本著懷疑的態(tài)度,不能太相信他們說的話,這點很重要,特別是工作中,同學們,不要別人說啥你就信啥,要本著柯南的精神,發(fā)生命案的時候每個人都是犯罪嫌疑人,當然你要排除自己,堅定不移的相信這肯定不是我的鍋!
好了,我們看看redis集群是否有節(jié)點負載過高,比如以常規(guī)經(jīng)驗看來的80%可以作為一個臨界值。
如果有一個或少量節(jié)點超過,則說明可能存在熱key問題,如果大部分節(jié)點都超過,則說明存在redis整體壓力大問題。
另外可以看看是否有慢請求的情況,如果有慢請求,并且時間發(fā)生問題的時間匹配,那么可能是存在大key的問題。
嗯... ...
redis同學說的沒錯,redis穩(wěn)如老狗。
CPU
我們假設自己還是很無助,還是沒發(fā)現(xiàn)問題在哪兒,別急,接著找找別人的原因,看看CPU咋樣,可能運維偷偷滴給我們把機器配置給整差了。
我們看看CPU使用率多高,是不是超過80%了,還是根據(jù)經(jīng)驗,我們之前的服務一般高峰能達到60%就不錯了。
再看看CPU是不是存在限流,或者存在密集的限流、長時間的限流。
如果存在這些現(xiàn)象,應該就是運維的鍋,給我們機器資源不夠啊。
GC停頓
得嘞,運維這次沒作死。
再看看GC咋樣。
頻繁的GC、GC耗時過長都會讓線程無法及時讀取redis響應。
這個數(shù)字怎么判斷呢?
通常,我們可以這樣計算,再次按照我們一塌糊涂的經(jīng)驗,每分鐘GC總時長/60s/每分鐘GC個數(shù),如果達到ms級了,對redis讀寫延遲的影響就會很明顯。
為了穩(wěn)一手,我們也要對比下和歷史監(jiān)控級別是否差不多一致。
好了,打擾了,我們繼續(xù)。
網(wǎng)絡
網(wǎng)絡這塊我們主要看TCP重傳率,這個基本在大點的公司都有這塊監(jiān)控。
TCP重傳率=單位時間內(nèi)TCP重傳包數(shù)量/TCP發(fā)包總數(shù)
我們可以把TCP重傳率視為網(wǎng)絡質(zhì)量和服務器穩(wěn)定性的一個只要衡量指標。
還是根據(jù)我們的經(jīng)驗,這個TCP重傳率越低越好,越低代表我們的網(wǎng)絡越好,如果TCP重傳率保持在0.02%(以自己的實際情況為準)以上,或者突增,就可以懷疑是不是網(wǎng)絡問題了。
比如這張圖一樣,要是和心電圖一樣,基本上網(wǎng)絡問題就沒跑了。
容器宿主機
有一些機器有可能是虛擬機,CPU的監(jiān)控指標可能不準確,特別是對于IO密集型的情況會有較大差異??梢酝ㄓ闷渌侄蝸聿樵兯拗鳈C的情況。
最后
根據(jù)一系列的騷操作,我們根據(jù)定位到的機器然后排查了一堆情況,最終定位到是網(wǎng)絡問題,有單獨的幾臺機器在高峰時期TCP重傳率賊高,最后根據(jù)運維提供的解決方案:【重啟有問題的機器】,我們很順利的就解決了這個問題。
但是,這畢竟是治標不治本的辦法,最終怎么解決的?
在我的另外一篇文章我有寫到了,沒人告訴過你更復雜的緩存穿透怎么解決