當前位置:
首頁 > 最新 > 通用Redis架構+實用輔助工具,逐一攻破DBA痛難點!

通用Redis架構+實用輔助工具,逐一攻破DBA痛難點!

講師介紹

強昌金

CRUG(Redis中國用戶組)創始人&副主席

前陌陌DBA、去哪兒高級DBA、MySQL OCP,《MySQL 運維內參》作者之一 。

今天將和大家介紹常見的Redis架構、以往我在陌陌、去哪兒網做Redis時的一些經驗,主要包括DBA日常維護MySQL或Redis時需要做的工作、如何根據日常工作和業務的需求來制定Redis架構,最後是分享一些好用的輔助工具,與大家共勉。

一、DBA的日常工作

我們DBA在日常工作中主要會遇到這些問題:如何更好地了解業務和需求所在?如何根據業務需求設計良好的架構?……

日常運維如搭建實例、部署高可用、做業務、查詢、元數據管理、監控與告警處理報警,這些還可通過一些人工來解決,但隨著時間的推移,實例越來越多、機器越來越多、業務越來越複雜,這時我們就得要知道每個業務對應的Redis實例,以及其它MySQL實例需要藉助自動化管理平台來簡化工作。

業務需求

面對業務需求(如一個業務要上Redis)時,DBA首先需要了解這個業務是幹什麼的。

去哪兒網有一個良好的習慣,就是DBA會深入業務線。以前我是負責機票系統的,幾乎常年在機票的業務線待著,會去深入了解機票每個Redis是怎麼用的,分清Redis使用時究竟是用在緩存還是存儲上。

如果是用在緩存上,最大容量、報警、配置怎麼配;如果是用在存儲上,功能又該怎麼管理。在使用緩存時是不是需要和業務溝通,每個Key有沒有設置過期時間,如果沒有設置,我則認為你是用來存儲而不是用來緩存。

前期我們可以做一些規定,對後期管理做得比較嚴格,如果業務是用於存儲的話,有可能導致無法寫入等問題,所以一定要跟業務溝通,搞清楚業務需求的真正用途。

還有的業務需求過來,說需要600G甚至1T的容量,這時面對大容量的業務需求,我們要怎麼搭建集群,並做好往後的擴容和維護。

還有的情況是業務需求容量很低,可能只需要1G,但是QPS達到了一百萬,這時我們部署的多個實例,將包括這個實例怎麼擴容、怎麼管理,以及多個實例進來以後怎麼用,這都需要有一個良好的架構。

運維需求

了解完業務需求後還需要了解運維需求,因為開始搭建Redis架構後,業務可能用起來很爽,但是DBA維護起來則很難,整個架構升級都非常困難。

如何解決?首先我們要了解業務,建立一些元數據。因為業務非常多,每個業務有可能對應多個集群,通過建立元數據管理,就可以在問題出現時快速聯繫到業務方,這需要我們配合業務去共同解決。

若是基於以前的人工運維,用自己的一些筆記或Wiki記錄就足夠了,但如果元數據記錄到自動化管理平台,則可以把這些元數據收集起來,包括日常操作、上下實例、關閉實例、調整主從狀態、清理數據等操作,這些都DBA需要去考慮。

此外,Redis後期的維護的操作能否在不影響上層業務使用的基礎上簡單地去做;監控報警、存儲監控如何設置;高可用使用過程中機器非常多,有可能每天都會面臨機器需要下線維護的情況,這時如何做在線切換;當機器宕機甚至整個機房都不可用時,如何在另一個機房快速重啟……

做運維DBA是非常累的,7x24小時,光靠人來盯是不足夠的,需要有良好的架構和運維平台相結合來實現快速響應。

面臨的問題

在此之後,再通過了解自身的需求,開始思考如何設計一個良好的架構,以及在這中間即將面臨的問題:

存儲&緩存集群設計

擴容

高可用

運維平台

二、Redis架構設計

架構的目標

在如何設計一個良好的Redis架構上,我們給自己定了個小目標——實現財務自由,對此,在這個過程應該做到以下幾點:

快。因為在業務快速發展中,我們每天都可能上線N個系統、搭建N套集群以及業務擴容。一個良好的架構,需要能夠讓業務在使用方面更加快捷與友好!

穩。隨著集群數量與機器數量上漲,運維的過程中,幾乎每天都會遇到擴容、機器搬遷、維護等需求。那麼底層Redis集群的節點發生變化時,應該做到保證業務不受影響。

准。由於宕機、誤操作以及其他原因,Redis都會發生切換,如何減少誤切換帶來的影響,這就需要一個良好的自動化切換的機制!

架構的選型

小目標定好,架構選型就該著手了。以下我們考慮到的一些點:

1、Redis主從or Redis Cluster?

Redis主從:穩定、維護簡單,但擴容成本高,有可能在牽引的過程中業務受到影響。

Redis Cluster:維護成本高、擴容簡單,相對來說較為複雜,卡死時需要研究源碼,加節點操作也更困難。

所以在使用時我們選擇一個Redis的主從,以及選用比較簡單且穩定的版本,當然目前仍然使用2.8等,只要性能OK即可。

2、Proxy或者類似Proxy

可以隔離業務與底層Redis集群的關係,便於運維人員管理後台集群;

可以管理連接池;

可以控制HASH規則。

3、高可用

我們提供了一個Sentinel,當主機出現問題時,就可以自動地把從機提升上來。

4、元數據管理

包括前面提到的元數據,會考慮是用MySQL還是ZooKeeper來做,用ZooKeeper的好處是當節點發生變化時可以通知所有的業務端。

而對我們來說,用MySQL首先是更簡單維護,也可以更清晰地看到哪個業務對應哪個節點信息。結果是,我們最初只用了ZooKeeper,隨著後期的發展變成MySQL+ZooKeeper同時使用。

架構設計

這是我們Redis架構訪問實例的流程圖,也是去哪兒近幾年在使用的架構,中間有升級過。

一開始客戶端通過Proxy集群,並根據Redis節點信息來訪問Redis集群,比如一個Key過來之後是通過某些一致性的Hash來進行訪問的,而Redis節點信息可以理解為是由Proxy集群或訪問客戶端打包到它們的業務客戶端里。

架構拓展——Proxy

1、變更

因為我們給每一個業務定了一個Namespace,裡面存了相關信息(一些主節點信息或連接池的大小都可在這裡設置)。當客戶端進來後,它首先從ZK里讀取Redis的信息,並根據從Namespace處拿到這個信息,如果是拿到三個節點信息就可根據上面配置的連接池大小直接建立對應多少的連接,於是這時我們業務過來的時候就已經拿到這幾個節點了。

如果這時業務又來了一個Key該怎麼訪問?這個Key首先在Proxy或者訪問客戶端中通過一致性演算法來進行計算,就可以把某個Key分配到集群中的一個節點上。我們都可以拿到這個節點並操作裡面的數據,但會存在一個問題:節點掛了怎麼辦?這裡就需要啟動我們的一組哨兵。

哨兵可以部署在多個機房,針對每一個實例分配一組哨兵(有可能每個實例有5個哨兵進行監控)。如果主節點掛了,我們可通過哨兵選舉機制將Redis的從實例提升為主實例,老的實例起來之後可自動變更為從實例。但此時業務方並不清楚他們拿到的還是以前的老實例,只是發現現在連不進去了。

這時我們通過哨兵來進行ZK信息的修改,因為哨兵切換之後就能知道哪個是新主實例,我們修改對應的信息即可,修改完之後再觸發客戶端,我們就能讓客戶端知道知道現在的新主節點是誰,知曉了之後就會把連接進行重接,進而發現客戶端連到新的地方了。這就是一個簡單的Redis架構。

但這個Redis架構存在一個問題:如果是集群開始為三個節點,那如何從三個節點擴容到五個節點?因為所有的數據要重新做Hash規則,我可以先搭建五個實例起來,再按照我們自己寫的同步工具和新的Hash規則來分析這三個實例的AOF文件,通過不停地分析AOF文件把這三組實例數據通過新的Hash規則Hash到五個節點上去,最後通過人工修改ZK信息,告知它現在已擴容到五個節點。

如果我們同步工具運行速度跟不上Redis的寫入速度,就可能導致永遠無法同步完成。因此,為了不影響業務運行,我們可以對這一塊進行改造。

最初我們用了一個簡單的一致性Hash,接著在這上面做了二層Hash,所以第一層Hash就是這個節點,第二層Hash就是可以為簡單的取余,對我們而言,這樣擴容就非常簡單了,可以用主從搭建的模式。

2、自定義Hash規則

我們可以自定義Hash規則,如果一層Hash解決不了問題,就搭建二層Hash,再擴容某一個節點。與之前只能擴容三個節點相比,此時可以擴容五個節點,但在做二層Hash時就可針對每一個節點進行擴容,這對於運維來說非常簡單,只需要搭建兩個從庫即可。

3、安全

安全方面表現為對客戶端進行危險命令的屏蔽,不允許一來就是危險的DEL操作,包括更危險的FLUSH操作和一些新操作。

這些操作容易導致Redis發生卡頓,因此我們要對危險的命令進行過濾。所以在做DBA運維的過程中,當節點信息發生變化時,客戶端能夠自動更新,包括集群信息和連接池信息等。

4、連接池

基於連接池的規則,有可能某一個節點連接數過大,可能達到8至9千甚至上萬個連接,而一個客戶可能不需要那麼多連接,並且裡面很多連接是廢棄的,所以就需要我們在MySQL里修改數據池的數量,讓其能在監控異常時快速響應,並通過ZK來通知,這便不會對我們的業務產生影響。

架構拓展——Sentinel

1、一對一:一組哨兵就一個節點,維修成本低一些。

2、多機房分散式:更加靈敏和準確。

3、自動切換:前提是從庫一般不提供服務,在主庫發生宕機時,它會進行自動切換,將新的主節點信息通過ZK和配置中心推送到業務端,讓從庫提升為主庫。

4、通知:包括ZK業務端自動的感應,包括在業務上線時需要人工做一次哨兵的切換,同時要檢測高可用、機器是否可用、架構是否有問題等,這時就可以通過哨兵修改ZK,Proxy也將自動感知。

5、DBA入場:入場之後需要查看監控信息和報警信息,確認哨兵是否做到真正切換或者ZK信息有沒有更新到,包括更新後業務端有沒有收到等,若沒有收到,需要人工再次檢測,但這種機制對我們來說稍微簡單一些,因為很多東西都可以通過工具來完成的。

架構拓展——ZooKeeper

ZooKeeper主要負責兩件事:記錄配置信息和訂閱通知。首先,它會針對每一個業務制定一個Namespace的概念,這樣業務對應的多個信息都可以在這裡設置。

此外,當集群節點信息發生變化後,會通過ZooKeeper來通知客戶端或者Proxy,以進行快速的響應。但這有一個問題就是會在通知時有可能發生失敗。

使用流程與規則

當我們設計了一個Redis架構之後可以如何使用呢?

1、描述業務需求與溝通。我們要確認業務的使用場景、容量、QPS等一系列信息。

2、制定集群模式。要設置一個良好的集群,有可能需要十到二十個節點,需要在前期制定一個模式判斷是否為緩存,如果不是,報警信息是不一樣的,設置信息監控點也不一樣。

3、自動化搭建集群。可通過自己的工具自把一些集群快速、自動化地搭建起來。

4、部署高可用與Failover。高可用部署一定要做好Failover機制,因為有可能布上去了但沒有做到真正的精細化,這樣人工上線時就會出現問題。

這裡我們做了一個簡單的工具,即我們搭建了一套集群(裡面有一百個實例),但不可能把每個實例都做檢測,所以我們可以對集群進行一個級別的界定,如果是核心集群,我挑90%自動做一次Failover,如果是非核心集群,則選擇60%自動做一次Failover。

5、初始化配置中心,把信息都填進去。

6、最後通知業務集群已搭建好。

自動化擴容

前文剛說了一下我們第一、二個版本的擴容方案與流程,這裡再仔細梳理下。

首先我們拿到一個業務,或許是壓力扛不住、反應慢了、容量不夠了或運維方觸發,使得運維方檢測到的實際內容一開始是10G,但我們監控出來時已達到15G,這時我們也許需要擴容了。

隨著日益的發展,我們一開始只定義了10個G,但慢慢地超過了10個G、20個G,因為當Redis一個節點的存儲量越來越大時,運維的成本也會越來越大。此外,10G以內做主從實例搭建是非常簡單的,但如果是20G或30G,做一次的恢復時間很長,所以運維方也會觸發一次需求。

如何做業務擴容,事實上業務並不關心,但對運維來說就很困難了,即剛說的第一種方案:自己寫同步工具去擴第一層Hash。

當我們有兩層Hash時擴容很簡單,搭兩個從庫、三個從庫就行了。但這裡搭完後會有一個問題:數據存在多餘的數據。

也就是說,當我們做環境整理、搭建主從,只需把數據遷移過去就OK了,接著更新配置,通知業務集群好了,讓他們查看一下。可這裡有可能一個集群由三個節點變為五個節點了,因為每個節點在擴容後存在一部分數據是垃圾數據,而這部分數據在做Hash時是不需要的,所以我們需要根據新的Hash數據,把老的信息清理掉,人工慢慢刪除就不會影響業務,這樣我們的容量也擴容完成了。

優點&缺點

1、優點:

便於擴容:直接搭建從庫即可。

便於調整:包括節點調整的信息、連接池的信息也可以控制,業務能做到自動感知。

維護簡單。

穩定:利用有哨兵機制來進行保障。

2、缺點:

縮容複雜。三個節點怎麼縮到兩個節點,目前還沒有想到好招,可以把最大內存調一調,比如把10個G調成5個G,當然實例個數保持不變。

客戶端升級困難。因為需要把所有業務都升級一遍,所有我們目前使用的原則就是老的業務有可能還在使用第一個版本的Hash規則,新的業務則上第二個版本。

三、輔助工具

當有了一套良好的Redis架構後,我們是不是還需要其它的工具或平台來輔助DBA進行管理?這部分簡單和大家介紹下心得。

運維小工具

我們可以做一些運維的小工具,包括部署相關的自動化小工具、平滑遷移、內存分析工具以及數據清理等。

Redis管理平台

除了簡單的小工具,還可以上一些人工智慧的東西。我們簡單做了一個平台,可以幫助我們實現元數據、日常操作、監控& 告警、自動化等管理。其中:

元數據的管理:包括對機器、集群、節點和業務負責人的管理。

日常操作:這些操作可提供給開發使用,包括查詢、參數調整、慢查詢和數據清洗。

監控&告警:對緩存來說,我們不設置最大內存的報警,正如前文我一直強調的,使用集群時要定義好到底是存儲還是緩存,對這塊進行分類後很多操作就可以在這個平台上進行。

自動化:包括自動化部署和自動化擴容。

備份&恢復

對DBA來說,備份是一項日常的工作,Redis也不例外,這裡我們可以結合RDB+AOF的功能。因為主庫有時可能壓力比較大,而RDB有可能是半小時做一次,如果在這半小時內主庫掛了怎麼辦?這時就可以開啟從庫。

那為什麼把RDB和AOF兩者結合?因為如果我們有RDB的時候數據有可能會丟失,而若只用AOF文件,這個恢復過程則非常慢。有的業務說,我可以允許丟一部分數據,但要能快速恢復。

因此我們選擇了兩者結合的方式,不僅恢復速度非常快,還能保證主從庫都掛的情況下數據依然可以恢復,當然我們還有另一個機房可以用,這只是針對核心的來說。按理說,一般平時這兩種方案的結合就滿足我們的需求了。

四、總結

最後做個總結,我們一定要深入業務,知道Redis具體用在哪、怎麼用,了解後可以選擇更簡單的、更適合我們的技術來做架構,包括做到良好的自動化。因為光靠堆人來運維會非常疲憊,如果有一個很好的管理平台和自動化工具來輔助我們,將會事半功倍。

而對於未來的探索,我們將對一些新技術進行調研。最理想的狀態,是通過一些簡單的自動化,讓DBA們能夠輕鬆一點,省點時間學習新技術,解決工作中其他的難題。

問答環節

【問題1】Redis架構底下是一個機房放了一個哨兵,還是一組哨兵?

答:如果目前你們公司只有一個機房,那哨兵只能放在同一個機房。但如果你們公司像去哪兒網或是陌陌這種有好幾個機房的話,就可以把哨兵放在不同的機房,其中每個機房放一個。舉例來說,如果想要監控這個實例,有五個機房就部署五組哨兵,一組哨兵就是五個節點。

【追問】那如果把哨兵部署在多個機房上,哨兵發生腦裂了怎麼辦?

答:所以我們要通過部署基數,來更好地避免這個問題。

【問題2】如果把元數據放在ZooKeeper上,那ZooKeeper要和Redis放在同一個機房嗎?

答:我們建議把一套ZooKeeper集群里的幾個節點放在不同的機房,因為多機房有可能存在問題,這是不可避免的,但目前我們這樣使用方面,從來沒有出現問題,可以做到比一般的網路監控還要更加靈敏。

【問題3】老師您好,我在做Redis監控時有這樣一個困惑:Redis根據不同的業務,它的QPS是不一樣的,如何滿足我們想去監控這個業務的Redis是否是異常呢?

答:每個業務的監控值設置不一樣的數。

【追問】這樣做設計起來會非常麻煩,而且業務在改變時那個值也不會去浮動,您這邊有什麼好辦法呢?

答:首先我們可以通過管理平台來看到每個實例,這樣就可以針對每個實例進行監控值的設置,包括QPS。我們可以設置兩萬報警、三萬報警,如果這時我們的業務訪問量比較大,假設可能是六萬,那我們就設置到七萬報警,這可以做到粒度很細,針對每個實例來進行設置。所以我們在搭建時就會了解「你這個業務的QPS大概是多少」,比如說我的QPS是六萬的,可能搭建四個節點,也有可能業務最初給的初始報警數就是六萬,一旦超過就可以報警,那我們就可以進行初始化,把這個報警的閾值設定出來。

【追問】也就是細化到實例級別?

答:對,細化到每個實例。每個實例的監控值都是不一樣的。

【問題4】老師可否再講講PPT上關於異地災備這塊?

答:我們可以做一個核心集群,並在異地機房再搭建一套從庫。

【追問】如果本地的機房掛掉之後是需要通知?

答:這時就有可能不用哨兵監控了,如果整個機房都掛了就需要人工了。因為這時的異地災備就是整個機房都不能使用了,我覺得是需要人工介入的。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 DBAplus社群 的精彩文章:

當雲服務融入分散式緩存系統架構,會擦出怎樣的火花?
關於分庫分表,這有一套大而全的輕量級架構設計思路

TAG:DBAplus社群 |