Redis集羣搭建採坑總結

背景面試

    先澄清一下,整個過程問題都不是我解決的,我在裏面就是起了個打醬油的角色。由於實際上我負責這個項目,整個過程也比較清楚。以前也跟具體負責的同事說過,等過段時間帶他作作項目覆盤。結果一直忙,以前作的事情都快忘了也沒帶他作覆盤。因此趁着還記得,總結一下這個問題,也算一塊兒作個覆盤總結了。redis

    本週一的時候,咱們測試環境遇到一個問題:啓動一個服務就會致使後端調用耗時增長。當時諮詢了對這個問題以前有了解的同事獲得的答覆是由於一筆請求發到兩套測試環境(一個請求須要在兩套環境下運行結果作對比),由於這兩套環境共用同一套redis集羣。收到第二個相同請求的時候,會將這筆請求標記爲重複請求。下游接收到這筆請求是重複的,須要從新查詢數據庫驗證請求是否重複,不是的話作一個糾正。因此這時候會形成請求延遲升高。數據庫

    負責解決這個問題的同事小A就問我:那是否是再搭建一套將兩套Redis集羣分開就解決了。我說不必定,還有解釋不通的地方:一個環境服務不啓動不寫redis,另外一個環境服務啓動寫redis的時候也會遇到這個問題。後端

    因而小A找了這個服務相關負責的同事瞭解業務。由於測試環境的總責任人是我,因此瞭解業務的時候,小A也把我拉了一塊兒瞭解。經過同事的講述瞭解到一個環境中服務要寫兩個機房。若是兩個機房的Redis是同一套也會被標記成重複請求。緩存

    至此,解決環境問題的方法有了答案:每套環境要搭建兩套Redis集羣,兩個環境4套Redis集羣來解決問題。服務器

    每每,一個答案只是一系列問題的開始。架構

 

時間線ssh

    咱們的搭建方案是直接在使用Redis的服務上搭建鏈接它的兩套Redis集羣,只改下端口,多跑兩個進程。tcp

問題1:服務器退出登陸Redis服務會中止分佈式

     小A告訴我遇到問題的現象:按照網上經典的安裝啓動教程,啓動成功了。可是當幹會兒別的,ssh自動退出登陸以後再看Redis服務就中止了。

     我聽到這裏首先想到的是這個現象基本能夠判定是以非daemon進程在運行,因而我上網上找了以deamon方式運行的命令發給小A:

redis-server ./redis.conf --daemonize yes

     小A看了解決方法補充到那必定也能夠在配置文件裏直接配置daemon方式運行。我表示贊同,他也是這麼作的。我當時沒有點破,相信剛畢業的他不久也本身會發現配置文件和顯示命令其實是一回事。只是一個是永久生效,一個是每次運行時生效。而直接用這條命令只是爲了說明本質問題。

問題2:服務鏈接Redis報錯Not Auth

     小A又向我反饋報了一個錯,說他在網上查的是Redis版本問題,估計須要從新搭建Redis。我過去看了一下:Redis集羣是3.X的版本,jedis客戶端用的是2.9的版本。沒有據說過Redis3.X的版本有不向下兼容的問題,同時由於這個Redis是從負責Redis的團隊要過來的安裝包,應該和如今跑着的是一個版本。若是懷疑Redis的團隊發的安裝包與以前不同的話,我也確信以前確定版本不會低於3.0,由於Redis是從3.0以後才支持集羣的。因此我斷定不是Redis版本問題。讓他再查查。實際上個人意思是讓他換關鍵詞來查。好比能夠按照報錯的提示緣由來查,也能夠按照異常來查,不一樣的關鍵詞搜索能夠得到不一樣的信息。

    而後我看了報的錯:其餘的沒細看,只見赫然寫着:Not Auth。我就問:Redis服務有沒有設置密碼。他說沒有,還演示了一下,我在旁邊確認了沒有。就查看客戶端配置有沒有配置密碼。果真客戶端裏有密碼配置。這就與服務端不匹配了。

問題3:報錯cluster support disabled

    小A將客戶端密碼去掉從新打包部署以後,Not Auth的錯不報了,可是其實報了兩個錯,還有一個錯沒解決:就是提示cluster support disabled。

    我說集羣方式啓動應該就是一個配置,應該有個cluster-enabled什麼的從no改爲yes。我還出了個餿主意(注意這裏用到的餿主意,想一想《紅樓夢》裏每句話都是劇透,這裏也不例外):我說理論上一臺集羣也能夠算一個集羣。應該能夠直接改個配置就以集羣方式啓動了。

    小A按照我說的思路用直接改配置爲集羣的方法,客戶端再啓動果真沒有報錯了。

問題4:請求延遲沒有好轉,Redis服務端沒有寫入成功數據

    客戶端沒有報錯以後,小A重試原問題現場,請求延遲沒有好轉。另外,還發現Redis服務端沒有寫入成功的數據。

    此次我和小A首先一塊兒排查配置有沒有配置對。發現配置沒有問題,我就跟小A說:讓他多打日誌。客戶端鏈接的地方打一些,讀寫數據的地方打一些。

    經過這個方法,小A定位到客戶端鏈接的鏈接池爲空。最終本身排查到是一臺機器的集羣的哈希槽在一臺機器狀況下哈希槽分配有問題,數據寫入失敗。最後每一個集羣多起了2個Redis進程作成3個節點的集羣解決了問題。

 

可優化的排查思路分析

    在問題4排查的時候,我和小A一塊兒檢查了配置是否正確來確認Redis請求是請求到了正確的服務端。其實,有個更爲直接和說明問題的方法:抓包。能夠tcpdump端口查請求流量是否是正確從客戶端發出來了,被轉發到了哪裏。

    在《技術方案設計的方法》裏我也提到,不少時候搜索不到本身想要的信息極可能是關鍵詞的問題。排查問題的時候也能夠試着換換關鍵詞來搜索。

 

根本緣由分析

    這裏面有個問題沒有完全搞清楚:爲何一臺機器的Redis集羣會有問題。

    問了小A,當時異常時getSlots方法時返回了空。就是說問題實際上多是slot沒有被分配。

    我就問他單臺機器的時候有沒有在redis-cli客戶端上運行cluster info命令。他給我發了下面的運行狀況截圖。

 

 

    這張截圖驗證了個人猜測,slot沒有被分配,集羣狀態爲失敗,因此鏈接不上。

    那須要鏈接上的條件並不是是集羣裏有幾個節點,而是slots分配,集羣狀態成功。

 

 

    爲了驗證這個猜測,我搭建了一個一個節點的集羣,手動cluster addslots了0到16383個slot。集羣判斷16384個slot都分配完畢,自動狀態改爲OK。

    

    這整個過程說明了:網上都是說Redis集羣必須是3個節點以上的最好是單數個節點來啓動。單數個節點是爲了投票的時候能夠三局兩勝得出結論:一半以上的節點掛掉整個集羣不可用。而對於Redis根本上判斷集羣是否可用是根據slot有沒有完整的16384個slot在提供服務決定的。

 

總結

    我以爲在整個過程當中小A的表現我以爲很OK的。有4點:

1>主觀能動性

    在過程當中,他本身經過網上搜素找資源,本身解決了不少問題。整個問題處理過程當中其實沒花費我多少時間,花時間的事情他都本身解決了。

2>合理的利用了各類資源

    對於業務不理解,他找了理解業務的同事。技術問題搞不定他找了我。由於我對項目負責,因此找我是很合情合理的。同時,我是很但願他遇到這種事情來找個人。由於他找我證實他是信任個人,相信我能必定程度幫到他。第二,他找我是把我當成一種資源。做爲資源我被須要,是有價值的。被須要讓人以爲很踏實。

    我在有搞不定的事情的時候也向上尋求幫助。好比以前須要其餘組協做的時候人家有排期遇到困難,領導出面幫忙搞定了。還有申請資源因爲暫時性資源緊張,申請不到,也是更上級出面幫忙搞定了。一個稱職的上級必定能夠成爲一種資源,也願意讓本身成爲資源。可是成爲資源的形式不一樣,有的可能提供的是戰略,有的提供的是精神支持等。

3>過後總結

    問題解決後,小A有本身寫wiki總結事情通過,避免後人採坑,同時自身也有總結收穫。

4>及時溝通

    中間過程當中,他每一個關鍵步驟都有及時跟我溝通。由於解決完後他反饋給我:他本身以爲對於redis原理尚未理解,因此不清楚爲何3個節點就OK的緣由。我由於瞭解他的想法,因此才本身又實驗給出一個根本緣由分析。

 

    關於Redis,就一句話:那些不少人說只有面試的時候才能用到的東西,我老是發現實際工做中頗有用。

 

相關閱讀

    MySQL常見6個考題在實際工做中的運用

    Tair分佈式緩存

    Elasticsearch實戰-磁盤IO被打滿

    業務開發轉基礎開發,這三種「高可用」架構你會麼?

相關文章
相關標籤/搜索