1. 程式人生 > >從IDC到雲端架構遷移之路(GITC2016)

從IDC到雲端架構遷移之路(GITC2016)

大家好,很高興來到GITC2016的舞臺,我是來自58到家的沈劍,今天我分享的主題是《58到家從IDC到雲端架構遷移之路》。

機房遷移是一個很大的動作:

15年在58同城實施過一次(“逐日”專案),幾千臺物理機,從IDC遷到了騰訊的天津機房,專案做了10個多月,跨所有的部門,與所有的業務都相關;

16年在58到家又實施了一次(“凌雲”專案),幾百臺虛擬機器,從IDC遷到阿里雲,前後大概一個季度的時間,也是所有技術部門都需要配合的一個大專案。

“單機房架構-全連”

要說機房遷移,先來看看被遷移的系統是一個什麼樣的架構。


上圖是一個典型的網際網路單機房系統架構:

(1)上游是客戶端

,PC瀏覽器或者APP;

(2)然後是站點接入層,為了面對高流量,保證架構的高可用,站點冗餘了多份;

(3)接下來是服務層,服務層又分為與業務相關的業務服務,以及業務無關的基礎服務,為了保證高可用,所有服務也冗餘了多份;

(4)底層是資料層,資料層又分為快取資料資料庫

至於為什麼要做分層架構,不是今天的重點,不做展開討論,這是一個典型的網際網路單機房分層架構:所有的應用、服務、資料是部署在同一個機房,這個架構有的一個關鍵詞,叫做“全連”:

(1)站點層呼叫業務服務層,業務服務複製了多少份,上層就要連線多少個服務;

(2)業務服務層呼叫基礎服務層,基礎服務複製了多少份,上層就要連多少個服務;

(3)服務層呼叫資料庫,從庫冗餘了多少份,上層就要連多少個從庫;

比如說,站點接入層某一個應用有10臺機器,業務服務層某一個服務有8層機器,那肯定是上游的10臺會與下游的8臺進行一個全相連的。系統架構的可用性保證負載均衡保證,是服務的連線池去做的。不僅僅接入層連線業務服務層是這樣,業務服務層連線基礎服務層,服務層連線資料庫也都是這樣,這就是所謂的“全連”。

“機房遷移的目標是平滑”

單機房架構的特點是“全連”,那麼機房遷移我們是要做一個什麼樣的事情呢?先看這張圖:


之前單機房架構部署在機房A內,遷移之後仍然是單機房架構,只是換了一個B機房,做完這個遷移,有什麼好的方案?最容易想到的一個方案,把所有服務在新機房全部搭一套,然後流量切過來了。

當系統有幾千臺機器,有非常非常多的業務的時候,這是一種“不成功便成仁”的方案。做技術的都知道,設計時要考慮回滾方案,如果只有上線方案而沒有回滾方案,這便是一個“不成功便成仁”的方案,根據經驗,不成功便成仁的操作結果,往往就“便成仁”了。

最重要的是,全量搭建一套再流量切換,資料層你怎麼搭建一套?怎麼切?資料層原來都在A機房,B機房還沒有全量的資料,是沒辦法直接切的。要做一個數據同步的方案,最簡單的,停兩個小時服務,把資料從舊機房導到新機房,資料導完流量再切過去,這是一個數據遷移的簡單方案。這個方案對業務有影響,需要停止服務,這個是無法接受的,何況像58同城一樣有兩千多臺機器,無限多的資料庫例項,無限多的資料表的時候,停服務遷移資料根本是不可能的。

所以,機房遷移的難點,是“平滑”遷移,整個過程不停服務,整體遷移方案的目標是:

(1)可以分批遷移;

(2)隨時可以回滾;

(3)平滑遷移,不停服務;

“偽多機房架構-同連”

如果想要平滑的遷移機房,不停服務,在10個月的逐步遷移過程中,肯定存在一箇中間過渡階段,兩邊機房都有流量,兩邊機房都對外提供服務,這就是一個多機房的架構了。

多機房架構是什麼樣的架構呢?剛剛提到了單機房架構,上層連中層,中層連下層,它是一個全連的架構,能不能直接將單機房的全連架構套用到多機房呢?在另一個機房部署好站點層、服務層、資料層,直接使用“全連”的單機房架構,我們會發現:會有非常多跨機房的連線

(1)站點層連線業務服務層,一半的請求跨機房

(2)業務服務層連線基礎服務層,一半的請求跨機房

(3)基礎服務層連資料層(例如從庫),一半的請求跨機房

大量的跨機房連線會帶來什麼樣的問題呢?

我們知道,同機房連線,內網的效能損耗幾乎可以忽略不計,但是一旦涉及到跨機房的訪問,即使機房和機房之間有專線,訪問的時延可能增加到幾毫秒(跟幾房間光纖距離有關)。

使用者訪問一個動態頁面,需要用到很多資料,這些資料可能需要10次的業務服務層呼叫,業務服務層可能又有若干次基礎服務層的呼叫,基礎服務層可能又有若干次資料層的呼叫,假設整個過程中有20次呼叫,其中有一半呼叫跨機房,假設機房之間延遲是5毫秒,因為跨機房呼叫導致的請求遲延就達到了50毫秒,這個是不能接受的。

因此,在多機房架構設計時,要儘量避免跨機房呼叫(避免跨機房呼叫做不到,也要做到“最小化”跨機房呼叫),會使用“同連”的系統架構。


“同連”也很好理解,在非必須的情況下,優先連線同機房的站點與服務

(1)站點層只連線同機房的業務服務層;

(2)業務服務層只連線同機房的基礎服務層;

(3)服務層只連線同機房的“讀”庫;

(4)對於寫庫,沒辦法,只有跨機房讀“寫”庫了;

這個方案沒有完全避免跨機房呼叫,但其實它做到了“最小化”跨機房呼叫,寫主庫是需要跨機房的。但網際網路的業務,99%都是讀多寫少的業務,例如百度的搜尋100%是讀業務,京東淘寶的電商99%的瀏覽搜尋是讀業務,只有下單支付是寫業務,58同城99%帖子的列表詳情檢視是讀業務,釋出帖子是寫業務,寫業務比例相對少,只有這一部分請求會跨機房呼叫。

遷移機房的過程使用這樣一個多機房的架構,最大的好處就是,除了“配置檔案”,整個單機房的架構不需要做任何修改,這個優點是很誘人的,所有的技術部門,所有的業務線,只需要配合在新機房部署應用與服務(資料庫是DBA統一部署的),然後使用不同的配置檔案(如果有配置中心,這一步都省了),就能實現這個遷移過程,大大簡化了遷移步驟。

這個方案當然也有它的不足

(1)跨機房同步資料,會多5毫秒(舉個栗子,不要叫真這個數值)延時(主從本來會有延時,這個延時會增大),這個影響的是某一個機房的資料讀取;

(2)跨機房寫,會多5毫秒延時,這個影響的是某一個機房的資料寫入,當然這個寫請求比例是很小的;

這個“同連”架構非常適用於做機房遷移,當然也可以用作多機房架構,用作多機房架構時,還有一個缺點:這個架構有“主機房”和“從機房”的區分。

多機房架構的本意是容機房故障,這個架構當出現機房故障時,例如一個機房地震了,把入口處流量切到另一個機房就能容錯,不過:

(1)掛掉的是不包含資料庫主庫的從機房,遷移流量後直接容錯;

(2)掛掉的是包含資料庫主庫的主機房,只遷移流量,其實系統整體99%的讀請求可以容錯,但1%的寫請求其實會受到影響,此時需要人工介入,將從庫變為主庫,才能完全容錯。這個過程只需要DBA介入,不需要所有業務線上遊修改(除非,除非,業務線直接使用的IP連線,這個,我就不說什麼了)。

也正是因為這個原因,在機房故障的時候,有一定概率需要少量人工介入,才能容100%的機房故障,因此這個架構才被稱為“偽多機房架構”,還不是完全的“多機房多活”架構。

“自頂向下的機房遷移方案”

話題收回來,機房遷移的過程中,一定存在一箇中間過渡階段,兩邊機房都有流量,兩邊機房都對外提供服務的多機房架構。具體到機房的逐步遷移,又是個什麼步驟呢?通常有兩種方案,一種是自頂向下的遷移,一種是自底向上的遷移,這兩種方案在58到家和58同城分別實行過,都是可行的,方案有類似的地方,也有很多細節不一樣,因為時間關係展開說一種,在58到家實施過的“自頂向下”的機房遷移方案,整個過程是平滑的,逐步遷移的,可回滾的,對業務無影響的。

“站點與服務的遷移”


遷移之前當然要做一些提前準備,新機房要準備就緒,專線要準備就緒,這個是前提。

自頂向下的的遷移,最先遷移站點層和服務層:先在新機房,把站點層和服務層搭建好,並做充分的測試(此時資料層比如說快取和資料庫還是在原來的機房)。測試,測試,測試,只要流量沒有遷移,在新機房想怎麼玩都行,新機房準備的過程中,要注意“同連”,原有機房的配製檔案是完全不動的,肯定也是“同連”。

站點層與服務層的遷移,也是一個業務一個業務的逐步遷移的,類似螞蟻搬家。充分的測試完一個業務的站點層和服務層之後,為了求穩,先切1%的流量到新機房,觀察新機房的站點與服務有沒有異常,沒有問題的話,再5%,10%,20%,50%,100%的逐步放量,直至第一波螞蟻搬完家。

第一個業務的站點和服務遷移完之後,第二個業務、第三個業務,螞蟻繼續搬家,直至所有的業務把站點層和服務層都全流量的遷移到新機房。

在整個遷移的過程中,任何一個業務,任何時間點發現有問題,可以將流量切回,舊機房的站點、服務、配置都沒有動過,依然能提供服務。整個遷移步驟,是比較保險的,有問題隨時可以遷回來。

“快取的遷移”


站點層和服務層遷移完之後,接下來我們遷資料層,資料層又分為快取層和資料庫層,先遷快取。

經過第一步的遷移,所有的入口流量都已經遷到了新的機房(當然舊機房的站點和服務還是不能停,只要舊機房不停,任何時間點出問題,最壞的情況下流量遷回來),接下來遷移快取,先在新機房要搭建好快取,快取的規模和體量與舊機房一樣大。

流程上仍然是螞蟻搬家,按照業務線逐步的遷快取,使用同連的方式。這個快取切換的步驟非常的簡單:運維做一個快取內網DNS的切換(內網域名不變,IP切到新機房),並殺掉原有快取連線,業務線不需要做任何修改,只需要配合觀察服務。運維殺掉原有快取連線之後,程式會自動重連,重連上的快取就是新機房的快取了,bingo,遷移完畢。

這裡要注意幾個點:

(1)有些公司快取沒有使用內網域名,而是採用IP直連的話,則需要業務層配合,換新機房IP重啟一下即可(如果是IP直連,說明這個架構還有改進的空間喲);

(2)這個操作儘量選在流量低峰期,舊快取中都是熱資料,而新快取是空資料,如果選在流量高峰期,快取切換之後,短時間內可能會有大量請求透傳到資料庫上去,導致資料庫壓力過大;

(3)這個通用步驟,適用於允許cache miss的業務場景,如果業務對快取有高可用的要求,不允許cache miss,則需要雙寫快取,或者快取使用主從同步的架構。大部分快取的業務場景都是允許cache miss的,少數特殊業務使用特殊的方案遷移。

快取的遷移也是按照業務線,一步步螞蟻搬家式完成的。在遷移過程中,任何一個業務,任何時間點發現有問題,可以將流量切回原來的快取。所以遷移的過程中,不僅是站點層和服務層,舊機房的快取層也是不停服務的,至少保證了流量遷回這個兜底方案。

“資料庫的遷移”

站點層,服務層,快取層都遷移完之後,最後是資料庫的遷移。


資料庫還是在舊機房,其他的快取,服務,站點都遷移到新機房了,服務通過專線跨機房連資料庫。

如何進行資料庫遷移呢,首先肯定是在新機房搭建新的資料庫,如果是自建的IDC機房,需要自己搭建資料庫例項,58到家直接用的是阿里雲的RDS。

搭建好資料庫之後,接下來進行資料同步,自建機房可以使用資料庫MM/MS架構同步,阿里雲可以使用DTS同步,DTS同步有一個大坑,只能使用公網進行同步,但問題也不大,只是同步的時間比較長(不知道現能通過專線同步資料了嗎?)。

資料庫同步完之後,如何進行切換和遷移呢?能不能像快取的遷移一樣,運維改一個數據庫內網DNS指向,然後切斷資料庫連線,讓服務重連新的資料庫,這樣業務服務不需要改動,也不需要重啟,這樣可以麼?

這個方式看上去很不錯,但資料庫的遷移沒有那麼理想:

第一,得保證資料庫同步完成,才能切流量,但資料同步總是有遲延的,舊機房一直在不停的寫如資料,何時才算同步完成呢?

第二,只有域名和埠不發生變化,才能不修改配置完成切換,但如果域名和埠(主要是埠)發生變化,是做不到不修改配置和重啟的。舉個例子,假設原有資料庫例項埠用了5858,很吉利,而阿里雲要求你使用3200,就必須改埠重啟。

所以,我們最終的遷移方案,是DBA在舊機房的資料庫設定一個read only,停止資料的寫入,在秒級別,RDS同步完成之後,業務線修改資料庫埠,重啟連線新機房的資料庫,完成資料層的切換。


經過上述站點、服務、快取、資料庫的遷移,我們的平滑機房的目標就這麼一步步完成啦。

總結與問答

四十分鐘很短,focus講了幾個點,希望大家有收穫。

做個簡要的總結:

(1)網際網路單機房架構的特點,全連,站點層全連業務服務層,業務服務層全連的基礎服務層,基礎服務層全連資料庫和快取;

(2)多機房架構的特點,同連,接入層同連服務層,服務層同連快取和資料庫,架構設計上最大程度的減少跨機房的呼叫;

(3)自頂向下的機房遷移方案:先進行站點接入層、業務服務層和基礎服務層的遷移,搭建服務,逐步的遷移流量;然後是快取遷移,搭建快取,運維修改快取的內網DNS指向,斷開舊連線,重連新快取,完成遷移;最後資料庫的遷移,搭建資料庫,資料進行同步,只讀,保證資料同步完成之後,修改配置,重啟,完成遷移。整個過程分批遷移,一個業務線一個業務線的遷移,一塊快取一塊快取的遷移,一個數據庫一個數據庫的遷移,任何步驟出現問題是可以回滾的,整個過程不停服務。

主持人:講的很細緻,大家有什麼問題嗎,可以提一些問題,可以舉手示意我。

提問:做資料遷移的時候,因為您講的資料中心的都是在同一個老機房,同時又在做同步,我就在想這個資料庫的壓力是不是特別大。

沈劍:非常好的問題,這個地方一方面要考慮壓力,更重要的是考慮跨機房的專線,風險最大的是在頻寬這一部分,你在第一步遷移完之後,其實所有的快取,資料庫用其實都是跨機房的,都是通過專線去走的,這個專線頻寬是需要重點考慮與評估的,資料庫的壓力其實還好。

提問:我想請教一個問題,你這個流量切換的過程中,有測試性的階段還是直接切過去的。

沈劍:在切流量之前,肯定是有測試的,在新機房將服務搭建,在切換流量之前,測試的同學需要進行迴歸,迴歸的過程可以提前發現很多問題。逐步的切流量也是為了保證可靠性,我們不是一次性百分之百流量都切過來,先切1%的流量過來,觀察服務沒有問題,再逐步增大流量切換。

原文連結: