從IDC到云端架構(gòu)遷移之路(GITC2016)

2018-09-06 18:00 更新
大家好,很高興來到GITC2016的舞臺,我是來自58到家的沈劍,今天我分享的主題是《58到家從IDC到云端架構(gòu)遷移之路》。

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

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

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


“單機房架構(gòu)-全連”

要說機房遷移,先來看看被遷移的系統(tǒng)是一個什么樣的架構(gòu)。

單機房軟件架構(gòu)

上圖是一個典型的互聯(lián)網(wǎng)單機房系統(tǒng)架構(gòu)

(1)上游是客戶端,PC瀏覽器或者APP;

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

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

(4)底層是數(shù)據(jù)層,數(shù)據(jù)層又分為緩存數(shù)據(jù)數(shù)據(jù)庫;


至于為什么要做分層架構(gòu),不是今天的重點,不做展開討論,這是一個典型的互聯(lián)網(wǎng)單機房分層架構(gòu):所有的應用、服務、數(shù)據(jù)是部署在同一個機房,這個架構(gòu)有的一個關(guān)鍵詞,叫做“全連”

(1)站點層調(diào)用業(yè)務服務層,業(yè)務服務復制了多少份,上層就要連接多少個服務;

(2)業(yè)務服務層調(diào)用基礎(chǔ)服務層,基礎(chǔ)服務復制了多少份,上層就要連多少個服務;

(3)服務層調(diào)用數(shù)據(jù)庫,從庫冗余了多少份,上層就要連多少個從庫;


比如說,站點接入層某一個應用有10臺機器,業(yè)務服務層某一個服務有8層機器,那肯定是上游的10臺會與下游的8臺進行一個全相連的。系統(tǒng)架構(gòu)的可用性保證,負載均衡保證,是服務的連接池去做的。不僅僅接入層連接業(yè)務服務層是這樣,業(yè)務服務層連接基礎(chǔ)服務層,服務層連接數(shù)據(jù)庫也都是這樣,這就是所謂的“全連”。

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

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

機房遷移

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

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

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

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

(1)可以分批遷移;

(2)隨時可以回滾;

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


“偽多機房架構(gòu)-同連”

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


多機房架構(gòu)是什么樣的架構(gòu)呢?剛剛提到了單機房架構(gòu),上層連中層,中層連下層,它是一個全連的架構(gòu),能不能直接將單機房的全連架構(gòu)套用到多機房呢?在另一個機房部署好站點層、服務層、數(shù)據(jù)層,直接使用“全連”的單機房架構(gòu),我們會發(fā)現(xiàn):會有非常多跨機房的連接

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

(2)業(yè)務服務層連接基礎(chǔ)服務層,一半的請求跨機房

(3)基礎(chǔ)服務層連數(shù)據(jù)層(例如從庫),一半的請求跨機房


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

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


用戶訪問一個動態(tài)頁面,需要用到很多數(shù)據(jù),這些數(shù)據(jù)可能需要10次的業(yè)務服務層調(diào)用,業(yè)務服務層可能又有若干次基礎(chǔ)服務層的調(diào)用,基礎(chǔ)服務層可能又有若干次數(shù)據(jù)層的調(diào)用,假設(shè)整個過程中有20次調(diào)用,其中有一半調(diào)用跨機房,假設(shè)機房之間延遲是5毫秒,因為跨機房調(diào)用導致的請求遲延就達到了50毫秒,這個是不能接受的。

因此,在多機房架構(gòu)設(shè)計時,要盡量避免跨機房調(diào)用(避免跨機房調(diào)用做不到,也要做到“最小化”跨機房調(diào)用),會使用“同連”的系統(tǒng)架構(gòu)。
偽多機房軟件架構(gòu)

“同連”也很好理解,在非必須的情況下,優(yōu)先連接同機房的站點與服務

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

(2)業(yè)務服務層只連接同機房的基礎(chǔ)服務層;

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

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


這個方案沒有完全避免跨機房調(diào)用,但其實它做到了“最小化”跨機房調(diào)用,寫主庫是需要跨機房的。但互聯(lián)網(wǎng)的業(yè)務,99%都是讀多寫少的業(yè)務,例如百度的搜索100%是讀業(yè)務,京東淘寶的電商99%的瀏覽搜索是讀業(yè)務,只有下單支付是寫業(yè)務,58同城99%帖子的列表詳情查看是讀業(yè)務,發(fā)布帖子是寫業(yè)務,寫業(yè)務比例相對少,只有這一部分請求會跨機房調(diào)用。

遷移機房的過程使用這樣一個多機房的架構(gòu),最大的好處就是,除了“配置文件”,整個單機房的架構(gòu)不需要做任何修改,這個優(yōu)點是很誘人的,所有的技術(shù)部門,所有的業(yè)務線,只需要配合在新機房部署應用與服務(數(shù)據(jù)庫是DBA統(tǒng)一部署的),然后使用不同的配置文件(如果有配置中心,這一步都省了),就能實現(xiàn)這個遷移過程,大大簡化了遷移步驟。

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

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

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


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

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

(1)掛掉的是不包含數(shù)據(jù)庫主庫的從機房,遷移流量后直接容錯;

(2)掛掉的是包含數(shù)據(jù)庫主庫的主機房,只遷移流量,其實系統(tǒng)整體99%的讀請求可以容錯,但1%的寫請求其實會受到影響,此時需要人工介入,將從庫變?yōu)橹鲙?,才能完全容錯。這個過程只需要DBA介入,不需要所有業(yè)務線上游修改(除非,除非,業(yè)務線直接使用的IP連接,這個,我就不說什么了)。


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

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

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


“站點與服務的遷移”
站點與服務的遷移

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


自頂向下的的遷移,最先遷移站點層和服務層:先在新機房,把站點層和服務層搭建好,并做充分的測試(此時數(shù)據(jù)層比如說緩存和數(shù)據(jù)庫還是在原來的機房)。測試,測試,測試,只要流量沒有遷移,在新機房想怎么玩都行,新機房準備的過程中,要注意“同連”,原有機房的配制文件是完全不動的,肯定也是“同連”。

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

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

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

“緩存的遷移”
緩存的遷移
站點層和服務層遷移完之后,接下來我們遷數(shù)據(jù)層,數(shù)據(jù)層又分為緩存層和數(shù)據(jù)庫層,先遷緩存。

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

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

這里要注意幾個點:

(1)有些公司緩存沒有使用內(nèi)網(wǎng)域名,而是采用IP直連的話,則需要業(yè)務層配合,換新機房IP重啟一下即可(如果是IP直連,說明這個架構(gòu)還有改進的空間喲);

(2)這個操作盡量選在流量低峰期,舊緩存中都是熱數(shù)據(jù),而新緩存是空數(shù)據(jù),如果選在流量高峰期,緩存切換之后,短時間內(nèi)可能會有大量請求透傳到數(shù)據(jù)庫上去,導致數(shù)據(jù)庫壓力過大;

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


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

“數(shù)據(jù)庫的遷移”

站點層,服務層,緩存層都遷移完之后,最后是數(shù)據(jù)庫的遷移。

數(shù)據(jù)庫的遷移
數(shù)據(jù)庫還是在舊機房,其他的緩存,服務,站點都遷移到新機房了,服務通過專線跨機房連數(shù)據(jù)庫。

如何進行數(shù)據(jù)庫遷移呢,首先肯定是在新機房搭建新的數(shù)據(jù)庫,如果是自建的IDC機房,需要自己搭建數(shù)據(jù)庫實例,58到家直接用的是阿里云的RDS。

搭建好數(shù)據(jù)庫之后,接下來進行數(shù)據(jù)同步,自建機房可以使用數(shù)據(jù)庫MM/MS架構(gòu)同步,阿里云可以使用DTS同步,DTS同步有一個大坑,只能使用公網(wǎng)進行同步,但問題也不大,只是同步的時間比較長(不知道現(xiàn)能通過專線同步數(shù)據(jù)了嗎?)。

數(shù)據(jù)庫同步完之后,如何進行切換和遷移呢?能不能像緩存的遷移一樣,運維改一個數(shù)據(jù)庫內(nèi)網(wǎng)DNS指向,然后切斷數(shù)據(jù)庫連接,讓服務重連新的數(shù)據(jù)庫,這樣業(yè)務服務不需要改動,也不需要重啟,這樣可以么?

這個方式看上去很不錯,但數(shù)據(jù)庫的遷移沒有那么理想:

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

第二,只有域名和端口不發(fā)生變化,才能不修改配置完成切換,但如果域名和端口(主要是端口)發(fā)生變化,是做不到不修改配置和重啟的。舉個例子,假設(shè)原有數(shù)據(jù)庫實例端口用了5858,很吉利,而阿里云要求你使用3200,就必須改端口重啟。


所以,我們最終的遷移方案,是DBA在舊機房的數(shù)據(jù)庫設(shè)置一個read only,停止數(shù)據(jù)的寫入,在秒級別,RDS同步完成之后,業(yè)務線修改數(shù)據(jù)庫端口,重啟連接新機房的數(shù)據(jù)庫,完成數(shù)據(jù)層的切換。

機房遷移
經(jīng)過上述站點、服務、緩存、數(shù)據(jù)庫的遷移,我們的平滑機房的目標就這么一步步完成啦。

總結(jié)與問答

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

做個簡要的總結(jié):

(1)互聯(lián)網(wǎng)單機房架構(gòu)的特點,全連,站點層全連業(yè)務服務層,業(yè)務服務層全連的基礎(chǔ)服務層,基礎(chǔ)服務層全連數(shù)據(jù)庫和緩存;

(2)多機房架構(gòu)的特點,同連,接入層同連服務層,服務層同連緩存和數(shù)據(jù)庫,架構(gòu)設(shè)計上最大程度的減少跨機房的調(diào)用;

(3)自頂向下的機房遷移方案先進行站點接入層、業(yè)務服務層和基礎(chǔ)服務層的遷移,搭建服務,逐步的遷移流量;然后是緩存遷移,搭建緩存,運維修改緩存的內(nèi)網(wǎng)DNS指向,斷開舊連接,重連新緩存,完成遷移;最后數(shù)據(jù)庫的遷移,搭建數(shù)據(jù)庫,數(shù)據(jù)進行同步,只讀,保證數(shù)據(jù)同步完成之后,修改配置,重啟,完成遷移。整個過程分批遷移,一個業(yè)務線一個業(yè)務線的遷移,一塊緩存一塊緩存的遷移,一個數(shù)據(jù)庫一個數(shù)據(jù)庫的遷移,任何步驟出現(xiàn)問題是可以回滾的,整個過程不停服務。


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

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

沈劍:非常好的問題,這個地方一方面要考慮壓力,更重要的是考慮跨機房的專線,風險最大的是在帶寬這一部分,你在第一步遷移完之后,其實所有的緩存,數(shù)據(jù)庫用其實都是跨機房的,都是通過專線去走的,這個專線帶寬是需要重點考慮與評估的,數(shù)據(jù)庫的壓力其實還好。


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

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

主持人:上午先到這里,也歡迎大家關(guān)注沈老師的“架構(gòu)師之路”微信公眾號,下午我們準時開始,大家注意好休息時間,謝謝大家。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號