行进中换轮胎——万字长文解析美团和大众点评两大数据平台是怎么融合的
本文根據作者在2017年ArchSummit的分享記錄整理而成。
背景
互聯網格局復雜多變,大規模的企業合并重組不時發生。原來完全獨立甚至相互競爭的兩家公司,有著獨立的技術體系、平臺和團隊,如何整合,技術和管理上的難度都很大。2015年10月,美團與大眾點評合并為今天的“美團點評”,成為全球規模最大的生活服務平臺。主要分布在北京和上海兩地的兩支技術團隊和兩套技術平臺,為業界提供了一個很好的整合案例。
本文將重點講述數據平臺融合項目的實踐思路和經驗,并深入地討論Hadoop多機房架構的一種實現方案,以及大面積SQL任務重構的一種平滑化方法。最后介紹這種復雜的平臺系統如何保證平穩平滑地融合。
兩家公司融合之后,從業務層面上,公司希望能做到“1+1>2”,所以決定將美團和大眾點評兩個App的入口同時保留,分別做出各自的特色,但業務要跨團隊劃分,形成真正的合力。比如麗人、親子、結婚和休閑娛樂等綜合業務以及廣告、評價UGC等,都集中到上海團隊;而餐飲、酒店旅游等業務集中到北京團隊。為了支撐這種整合,后臺服務和底層平臺也必須相應融合。
點評App和美團App的數據,原來會分別打到上海和北京兩地的機房,業務整合之后,數據的生產地和數據分析的使用地可能是不一樣的。同時,隨著公司的融合,我們跨團隊、跨業務線的分析會越來越多,并且還需要一些常態化的集團級報表,包括流量的分析表、交易的數據表,而這些在原來都是獨立的。
舉個例子,原點評側的分析師想要分析最近一年訪問過美團和大眾點評兩個App的重合用戶數,他需要經過這樣一系列的過程:如下圖所示,首先他要想辦法找到數據,這樣就需要學習原美團側數據平臺元數據的服務是怎么用的,然后在元數據服務上去找到數據,才能開始做分析。
而做分析其實是一個人工去做SQL分解的過程,他需要把原點評側的去重購買用戶數拉下來,然后發到原美團側的數據平臺,這個環節需要經歷一系列的操作,包括申請賬號、下載數據、上傳數據,可能還會踩到各種上傳數據限制的坑等等。最終,如果在這些都走完之后想做一個定期報表,那他可能每天都要去人工處理一回。如果他的分析條件變了怎么辦?可能還要再重新走一遍這個流程。
所以他們特別痛苦,最終的結果是,分析師說:“算了,我們不做明細分析了,我們做個抽樣分析吧!”最后他做了一個在Excel里就能做的去重數據量的分析。我們作為平臺開發的同學來說,看到這個事情是非常羞愧的。那怎么辦呢?
在經過一些磨合后,我們得出一個結論,就是必須進行數據口整合。
融合實踐
確立目標
我們定了一個整體的目標,希望最終是能做到一個集群、一套數據平臺的工具、一套開發規范。但是這個目標有點大,怎么把它變的可控起來呢?首先至少看來是一個集群,也就是說從用戶訪問的角度上來講,他通過一個Client或一套用戶視圖就能訪問。工具方面至少明確已有的兩套,哪些是新的員工進來之后還需要學,哪些是未來會拋棄掉的。最終,讓大家認同我們有了一套數據平臺規范,雖然這套規范短期內還沒有辦法做到完美。我們做的這些權衡其實是為了從整體上能將問題收斂。
但即使我們把這個目標縮小了,想要達到也是很難的。難點在哪呢?
難點
架構復雜,基礎設施限制
如上圖所示,整個數據平臺基本上分為數據接入、數據開發、數據分析、數據輸出等等幾個階段。我這里只列了其中涉及到跨機房、跨地域的部分,還有很多數據平臺產品的融合,在這里就不贅述了。在兩個公司融合之前,原點評側和美團側都已經在同地域進行多機房的部署了,也都很"默契"地抽象出了離線的機房是相對獨立的。在線的業務機房不管是通過消息隊列還是原點評自己當時做的Blackhole(一個類似DataX的產品),都會有一系列數據收集的過程、對應任務的調度系統和對應的開發工具,也會有一些不在數據開發體系內的、裸的開源客戶端的跳板機。雖然架構大體一致,但是融合項目會牽扯整套系統,同時我們有物理上的限制,就是當時跨機房帶寬只有10Gb。
可靠性要求
由于團購網站競爭激烈,兩家公司對于用數據去優化線上的一些運營策略以控制運營成本,以及用數據指導銷售團隊的管理與支撐等場景,都有極強的數據驅動意識,管理層對于數據質量的要求是特別高的。我們每天從零點開始進行按天的數據生產,工作日9點,老板們就坐在一起去開會,要看到昨天剛剛發生過什么、昨天的運營數據怎么樣、昨天的銷售數據怎么樣、昨天的流量數據怎么樣;工作日10點,分析師們開始寫臨時查詢,寫SQL去查數據,包括使用Presto、Hive,一直到22點;同時數據科學家開始去調模型。如果我們集群不能work,幾千人每天的工作就只能坐在電腦面前看著Excel……
當時的分析是這樣,如果考慮回滾的情況下,我們運維的時間窗口在平日只有一個小時,而且要對全公司所有用數據的同學進行通告,這一個小時就是他們下班之后,晚上6點至7點的時候開始,做一個小時,如果一個小時搞不定,回滾還有一個小時。周末的話好一點,可以做4小時之內,然后做全面的通告,相當于整個周末大家都沒法加班了,他們是非常不開心的。
體量
雖然沒有到BAT幾萬臺節點的規模,但是也不算小了,融合時原點評的節點數是500個,數據量是11個P;原美團的節點數是3000個,現在整體已經上6000了。這里有一個比較關鍵的數據就是每天生成的數據量,由于我們的集群上面以數倉的場景為主,會有很多重新計算,比如說我要看去年每月的去重,這些都是經過一些時間變化之后會進行重算的。它對于分析數據的迭代速度要求很高,我每天可能都會有新的需求,如果原來的數據表里面要加一個字段,這個字段是一個新的統計指標,這個時候我就要看歷史上所有的數據,就得把這些數據重新跑一遍。這里的生成數據量其中有50%是對歷史的替換,50%是今天新增的。這對于后面我們拷數據、挪數據是比較大的挑戰。
平臺化與復雜度
兩家公司其實都已經慢慢變成一個平臺,也就是說數據平臺團隊是平臺化的,沒法對數據的結果分析負責,數據平臺團隊其實對外暴露了數據表和計算任務這兩種概念。平臺化以后,這些數據表的owner和這些數據任務的owner都是業務線的同學們,我們對他們的掌控力其實是非常差的。我們想要改一個表的內容、一個數據任務的邏輯,都是不被允許的,都必須是由業務側的同學們來做。兩側的平臺融合難免存在功能性的差異,數據開發平臺的日活躍就有100和240,如果查詢就是每天作分析的日活躍的話,原點評和美團加起來有1000多。所以在平臺融合過程中,能讓這么多用戶覺得毫無違和感是非常有挑戰的。
綜上,我們做了一個項目拆解。
項目拆解
數據互訪打通
數據互訪打通其實是最早開始的,早在公司宣布融合以后,我們兩側平臺團隊坐在一起討論先做什么,當時做了一個投入產出比的權衡,首要任務是用相對少的開發,先保障兩邊分析師至少有能在我們平臺上進行分析的能力。接著是讓用戶可以去配置一些定時任務,通過配置一些數據拷貝任務把兩地數據關聯起來。
在這方面我們總共做了三件事。
原始層數據收集
在原美團側把原點評側線上業務機房一些DB數據以及Server的log數據同步過來。這個時候流式數據是雙跑的,已經可以提供兩邊數據合在一起的分析能力了。
集群數據互拷
集群數據互拷,也就是DistCp。這里稍微有一點挑戰的是兩邊的調度系統分別開了接口,去做互相回調。如果我們有一份數據,我想它ready之后就立即拷到另外一邊,比如原點評側有個表,我要等它ready了之后拷到原美團側,這個時候我需要在原美團側這邊配一個任務去依賴原點評側某一個任務的完成,就需要做調度系統的打通。本文主要討論大數據框架的部分,所以上面的調度系統還有開發平臺的部分都是我們工具鏈團隊去做的,就不多說了,下文重點描述DistCp。
其實Hadoop原生支持DistCp,就是我起一個MapReduce在A集群,然后并行地去從B集群拖數據到A集群,就這么簡單。只要你網絡是通的,賬號能認(比如說你在A集群跑的任務賬號能被B集群認),并且有對應的讀權限,執行端有計算資源,用開源版本的DistCp就可以搞定。
這方面我們做了一些權衡:
首先是因為涉及到帶寬把控的問題,所以同步任務是由平臺團隊來統一管理,業務側的同學們提需求。
然后我們兩側集群分別建立一個用于同步的賬號,原則是在讀的那一端提交任務。什么叫“讀的一端”?比如說我想把一個原點評側的數據同步到原美團側,原美團側就是要讀的那端,我在原美團側起這個任務去讀原點評側的數據,然后寫到原美團側。這里的主要考慮是讀端更多是需求端,所以,他要在他的資源池里去跑。另外,對集群的影響讀小于寫,我們希望對于被讀集群的影響能盡量減少。
當然,這都是一些臨時的項目,投入較小,但收益是磨合了兩地團隊。
Kerberos跨域認證架構
接著介紹一下認證部分是怎么打通的。原美團側和點評側恰好都用了Kerberos去做認證服務,這個Kerberos在這我不去詳細展開,只是簡單介紹一下。首先是KDC會擁有所有的Client和Server,Client就是HDFS Client,Server就是Name Node,KDC會有Client和Server的密鑰,然后Client和Server端都會保有自己的密鑰,這兩個甚至都是明文的。所有的密鑰都不在傳輸過程中參與,只拿這個密鑰來進行加密。基于你能把我用你知道的密鑰加密的信息解出來,這一假設去做認證。這也是Kerberos架構設計上比較安全的一點。
Kerberos不細講了,下面詳細講一下Kerberos跨域認證架構。
一般公司都不會需要這個,只有像我們這種兩地原來是兩套集群的公司合并了才需要這種東西。我們當時做了一些調研,原來的認證過程是Client和KDC去發一個請求拿到對應Server的ticket,然后去訪問Server,就結束了。但是如上圖所示,在這里它需要走3次,原來是請求2次。大前提是兩邊的Kerberos服務,KDC其中的TGS部分,下面存儲的內容部分分別要有一個配置叫krbtgt,它有A realm依賴 @ B realm這樣的一個配置。
兩邊的KDC基于這個配置是要一致的,包括其中的密碼,甚至是包括其中的加密方式。那這個時候我們認為這兩個KDC之間實際上是相互信任的。
流程是Client發現要請求的Server是在另外一個域,然后需要先去跟Client所屬的KDC發請求,拿一個跨域的ticket,就是上圖中1右邊那個回來的部分,他拿到了這個krbtgt CREALM @ REALM。然后Client拿著跨域的ticket去請求對應它要訪問Service那一個域的KDC,再去拿對應那個域的Service的ticket,之后再去訪問這個Service。這個流程上看文檔相對簡單,實則坑很多,下面就講一下這個。
上圖是Kerberos跨域認證的一些要求。
首先第一個比較大的要求就是密鑰的編碼一致,這有一個大坑,就是你必須讓兩個KDC拿到的信息是一樣的,它們基于這個信息去互信,去互相訪問。然后krb5.conf里面有一些比較詭異的domain_realm策略,這個在你網絡環境不一致的時候會有一定的影響,包括DNS也會影響這個。在你的網絡環境比較不可知的時候,你需要做做測試,嘗試去怎么配,然后在Hadoop端有兩個配置需要做,分別在Server端和Client端配置即可。其中比較惡心的是說,在測試的過程當中,需要去看Hadoop的詳細日志,需要開一下它的Debug,然后去看一下它真正請求的那個域是什么樣的。因為我們翻代碼發現,Hadoop底層有對log,Client去請求realm的隱改,就是說我認為我應該是這個realm啊,它為什么傳出來的是另外一個realm?這個是比較坑的一點。
我們做完這個項目之后,分析師就可以愉快地配置一些調度任務去同步數據,然后在對應的集群上去關聯他們的數據進行分析了。做完這個項目之后,我們兩邊的團隊也相互磨合,相互形成了一定的認可。因為這個小項目涉及到了數據平臺的每一個領域,包括工具鏈、實時計算、離線的團隊都做了一些磨合。
集群融合
粗看起來,打通了數據平臺,我們的大目標似乎已經完成了:一個集群、一套數據平臺的工具、一套開發規范。把數據拷過來,然后重新改它的任務,就可以形成在統一的一套工具和規范里面用一個集群,然后慢慢把原來團隊維護的服務都下掉就好了。事實上不是這樣的,這里面有大量的坑。如果接下來我們什么都不做的話,會發生什么情況呢?
數據RD會需要在遷移的目標平臺重建數據,比如說我們都定了,以后把原美團側平臺砍掉,那么好,以后都在原點評側的平臺,包括平臺的上傳工具、平臺的集群去使用、去開發。這個時候,至少原美團側的同學會說:“原點評那邊平臺的那些概念、流程,可能都跟我不一樣啊,我還需要有學習的時間,這都還好”。但他們怎么遷移數據呢?只能從源頭開始遷移,因為對端什么都沒有,所以要先做數據的拷貝,把上游所有的表都拷貝過去。然后一層一層地去改,一整套任務都要完全重新構建一遍。
那我們有多少任務呢?
我們當時有7000個以上,后來超過8000個任務,然后我們平均深度有10層。也就是說上游先遷過來,然后下游才能遷。整個流程會變成數據表的拷貝,然后上線任務進行雙跑。因為必須得有數據的校驗,我才能放心地切過來,花的時間大概是拷貝數據1~4天,然后改代碼加測試再加雙跑,可能要3~5天。這里我們有一個流水線的問題,如上圖所示,藍色的部分只有一層依賴的,當然我把這個左邊的ODS都遷完了之后,1層依賴的Task 1、Task 2、Task 3、Task 8中,Task 1、2、3就可以遷了,但是Task 8 還是不能遷的,因為Task 8依賴的Task 7還沒過來。我再走一層,Task 4的負責人要等上游相關任務都遷完了之后才能干活,那整個這個遷移就純線性化,我們大概估了一下,并行度不會超過50。如果是兩地兩份數據,這個項目的周期會變成特別長,會有長期的兩份數據、兩份任務。這個時候,第一是我們真存的下嗎?第二是如果我要遷移出來那個方向的業務有需求的變更,我怎么改?我要兩邊都再改一遍?所以這個是非常不可控的。
那這個時候怎么辦?
集群融合的問題本質
反思一下這個問題的本質,首先我們是不能雙跑的,因為一旦雙跑,我們必須有常態化的兩份數據,然后衍生一系列的校驗、存儲量、切換策略等問題。所以我們必須得有一套數據,一套任務執行機制。后續任務的改變,不管是替換工具鏈上的東西,替換計算引擎,比如說讓兩邊Hive、Spark和UDF去做一致化的時候,其實本質上是說對單個任務的修改,對每個任務灰度的修改就好了。
所以我們推斷出,必須自底向上地去進行融合,先合集群,然后后續再推動上游平臺和引擎的融合。
集群融合的解決思路
整體我們融合的思路是這樣的,集群融合先行,兩邊的Hadoop的服務架構和代碼先進行統一,其次拷貝原點評側集群的Block,同步到原美團側機房的兩個副本。這里有一個大的前提,第一個是原點評側的集群節點數相對來講確實小,再一個就是原點評側的機房確實放不下了,它當時只能擴容到10月,再往后擴就裝不下機器了。
所以我們將原點評側的集群,合并到原美團側機房,然后進行拷貝和切換。我們讓整個這個集群變成在原美團側機房一樣的樣子,然后進行融合。我們會把上面的客戶端和元數據統一,使得訪問任何一個集群的時候,都可以用一套客戶端來做。一旦我們做到這個樣子之后,基于統一的數據、集群的元數據和訪問入口之后,我們上面的工具鏈就可以慢慢地去做一個一個機制,一個一個模塊的融合了。
簡單總結下來就是四步:統一、拷貝、切換、融合,下面我們來展開說一下這四步。
統一
第一優先級要解決的是上圖中標紅的部分,兩邊的Hadoop版本是不一樣的,我們需要將原上海側的版本變成我們的2.7.1帶著跨機房架構的版本。同時因為我們后面要持續地去折騰Hadoop集群,所以必須先把原上海側的HDFS架構改全,改成高可用的。
這里有一個小經驗就是,我們自研的patch對改的bug或者是加的feature,一定要有一個機制能夠管理起來,我們內部是用Git去管理的,然后我們自研的部分會有特殊的標簽,能一下拉出來。我們當時其實互相review了上百個patch,因為當時兩個團隊都有對集群,包括Hive等等這些開源軟件的修改。這是統一的階段,相對容易,就是一個梳理和上線的過程。接下來是拷貝的階段。
拷貝
上圖是最終的效果圖,同步在運行的打通任務還是用DistCp,然后先把原點評側的HDFS跨機房部署。但是這個時候原點評側的YARN還是在上海機房。在這個過程當中,因為HDFS跨機房部署了,所以原新上線的DataNode可以承載更多在原點評側集群的冷數據。這個過程是慢慢進行拷貝的,大概持續了4個月,中間長期都是10Gbps的小管子。
切換
這個相當于把原點評側的NameNode(這個時候還沒有徹底下線)切換到原美團側機房,然后把對應的YARN重新啟動起來。這里有一個小trick就是原美團側機房的承載能力,大概是1000多臺節點,是原點評側的兩倍,所以我們才能做這個事,最近我們剛剛把上海機房的節點遷完。
那整個集群的拷貝和切換是怎么做的呢?其實就是用我們自研的一套Hadoop多機房架構。可能做Hadoop集群維護管理的同學們對這個有深刻的體會,就是不時地就要從一個機房搬到另一個機房。設計目標是說我們一個Hadoop集群可以跨機房去部署,然后在塊的力度上能控制數據副本的放置策略,甚至是進行主動遷移。
設計是怎么做的呢?整個Hadoop原生的架構其實沒有機房這個概念,只支持Rack也就是機架,所有服務器都被認為是在同一個機房的。這個時候不可避免地就會有很多跨機房的流量,就如果你真的什么都不干,就把Hadoop跨機房去部署的話,那么不好意思,你中間有好多的調用和帶寬都會往這兒走,最大的瓶頸是中間機房網絡帶寬的資源受限。
我們梳理了一下跨機房部署的時候大概都有哪些場景會真正引發跨機房流量,基本上就這3~4個。首先是寫數據的時候,大家知道會3副本,3個DataNode去建pipeline,這個時候由于是機器和機器之間建連接,然后發數據的,如果我要分機房部署的話,肯定會跨機房。那我要怎么應對呢?我們在NameNode專門增加zone的概念,相當于在Rack上面又加了一層概念,簡單改了一些代碼。然后修改了一下NameNode邏輯。當它去建立pipeline的時候,在那個調用里面hack了一下。建pipeline的時候,我只允許你選當前這個Client所屬的zone,這樣寫數據時就不會跨機房了。
這些Application在調度的時候有可能會在兩個機房上,比如說mapper在A機房,reducer在B機房,那么中間的帶寬會非常大。我們怎么做的呢?在YARN的隊列里面,也增加zone的概念,我們用的是Fair Scheduler。在隊列配置里面,對于每一個葉子隊列,都增加了一個zone的概念。一個葉子隊列,其實就是對應了這個葉子隊列下面的所有任務,它在分配資源的時候就只能拿到這個zone的節點。讀取數據的時候有可能是跨機房的,那這個時候沒有辦法,我們只有在讀取塊選擇的時候本地優先。我們有一些跨機房提交job的情況,提交job的時候會把一些job里面的數據進行上傳,這個時候加了一些任務的臨時文件上傳的是任務所在的目標機房。這里做一些簡單的改動,最重要的是提供了一個功能,就是我們在拷貝數據的時候,其實用balancer所用的那一套接口,我們在此基礎之上做了一層Hack,一層封裝。形成了一個工具,我們叫ZoneTransfer,又由它來按照我們一系列的策略配置去驅動DataNode之間的跨機房的block粒度的拷貝。
上圖是我們跨機房架構的架構圖,下面的Slave里面有DN(DataNode)和NM(NodeManager),上面跑的同顏色的是一個App。我們在RM(ResourceManager)里面的葉子隊列里配置了zone的概念,然后在調度的時候如大家所見,一個App只會在一個機房。然后下面黑色的線條都是寫數據流程,DN之間建立的pipeline也會在一個機房,只有通過root去做的,DN之間做數據transfer的時候才會跨機房進行,這里我們基本上都卡住了這個跨機房的帶寬,它會使用多少都是在我們掌控之內的。
在上線和應用這個多機房架構的時候,我們有一些應用經驗。
首先在遷移的過程當中我們需要評估一點就是帶寬到底用多少,或者說到底多長時間之內能完成這個整體數據的拷貝。這里需要面對的一個現實就是,我們有很多數據是會被持續更新的。比如我昨天看到這個塊還在呢,今天可能由于更新被刪,那昨天已經同步過來的數據就白費了。
那我昨天已經同步過來的數據就白費了。所以我們定義了一個概念叫拷貝留存率。經過4個月的整體拷貝,拷貝留存率大概是70%多,也就是說我們只有70%的帶寬是有效的,剩下的30%拷過去的數據,后面都被刪了。
第二個是我們必須得有元數據的分析能力,比如說有一個方法能抓到每一個塊,我要拷的塊當前分布是什么樣子。我們最開始是用RPC直接裸抓Active NameNode,其實對線上的影響還是蠻大的。后面變成了我們通過FsImage去拉文件的列表,形成文件和塊的列表,然后再到把請求發到standby,那邊開了一個小口子,允許它去讀。因為FsImage里面是沒有block在哪一個DataNode的元信息的。
這里需要注意的一點就是,我們每天都會有一個按天的數據生產,為了保證它的一致性,必須在當天完成。在切換之前,讓被切換集群的NN(NameNode)進入SafeMode的狀態,然后就不允許寫了,所有的寫請求停止,所有的任務停止。我們當時上線大概花了5~6個小時吧,先停,然后再去拷貝數據,把當天的所有新生產的數據都拷過來,然后再去做操作。這里最基本的要做到一點就是,我們離線的大數據帶寬不能跟線上的服務的帶寬搶資源,所以一定要跟基礎設施團隊去商量,讓他們做一些基于打標簽的帶寬隔離策略。
融合
當我們把集群搬到了原美團側的機房之后,又做了一層融合。想讓它看起來像一個集群的樣子,基本上只需要3步。首先是“把冰箱門打開”,把原點評側集群的那個NN作為一個federation合到原美團側的集群,只需要改cluster ID,去客戶端改mount table配置,cluster ID是在元數據里面。第二個是對Hive進行元數據的融合。我們恰好兩側元數據存儲都是用MySQL的,把對應的表導出來,灌到這邊,然后持續建一個同步的pipeline。它是長期活動的,到時候把上傳的服務一切就可以。
前面說的那個做了跨域認證的配置我們還是要拆掉的,必須進行服務認證的統一,不然的話以后沒法看起來像一個集群,這個時候把原來的KDC里面的賬號進行導出,之后逐步地去切換每一個配置,讓它慢慢切到新的KDC。切的過程當中,我們各種請求還是有跨域情況的,我們認為兩個域是一體的,是一樣的。等切干凈之后,也就是原來的KDC沒有請求了之后,我們再把它干掉。
開發工具融合
集群融合結束后,我們就做了開發工具的融合。由于這個跟大數據基礎架構這個主題關系不是特別大,開發工具都是我們內部自研的,涉及的程序也很復雜,是一個特別大的項目,涉及一系列復雜的工具,每個模塊的融合、打通。所以這個暫時不講了。另外我覺得比較有意思的是下面這一點,就是原點評側的一個拆庫,這個在很多公司的數據平臺慢慢擴大的過程當中可能會用到。
原點評側拆庫
難點
先說一下背景,由于原點評和原美團整體歷史上發展經驗、周期和階段不同,如上圖所示,原點評側的數據倉庫是先有的Hadoop集群,后有的數據倉庫平臺,因此有很多平臺完全沒法掌控的私有庫,但是他們對于數倉所在庫的掌控是非常強的,所有的任務都在這一個大的Hive庫里面,里面有七八千張表。而原美團側是先有的數據平臺,后來因為數據平臺整個體量撐不住了,底層改成了Hadoop。同時在平臺化的演進過程中,已經慢慢把各個業務進行獨立拆分了,每個業務都有一個獨立的私有庫,簡單來說就是庫名和庫名的規范不一樣。我們希望能讓這兩套規范進行統一。
我們如何去做呢?
原來任務的內容大概是insert into一個BI庫里面的一張表,接著select from BI庫里面的某兩張表,然后where group by。像這樣的任務我們有七八千個,它們在我們平臺上配置著每天的依賴調度。我們希望把它都改成下圖中的樣子。所有涉及到的這些表都需要改名字,說白了就是一個批量改名字的事兒。
改名字聽起來很簡單,實際上并不是,我們有近8000個這樣的任務需要改,同時這些任務相互之間都有非常復雜的依賴。下圖是我隨便找的一個,原美團側某一個任務所有上游和下游的依賴關系圖,如此復雜,任務的平均深度大概有10層,這還是平均數,最嚴重的可能要有大幾十層。如果我們改這里面的任務表達,就只能分層推動。但是,當我們每改其中一個的時候,可能上下游都得跟著改,具體是什么樣子的呢?
下圖是我們的原始結構,首先這里有一個大前提是每一個任務只對一個結果表。原始的結構中,a表只依賴o1表,b表依賴o1、o2,然后c表只依賴o2,它們之間相互關聯。這時候我希望可以對庫名和表名進行一次性的修改。那如果我們逐層地去改寫怎么辦呢?首先要先把最上層的mart表改了,而我一旦改上游的某一個表,所有跟對它有依賴的表都必須改任務內容。每推動一層改動,下面一層都要變動多次,這樣一來,我們這個流程就非常受限。
剛剛那個情況基本上是類似的,就是說我們對它們的改動沒法批量化、信息化、流水線化,所有的用戶和數據開發們,需要跟我們去聊,最近改了多少,然后誰誰誰沒改完,誰誰誰又說要依賴他,整個依賴圖是非常大的,我們整個項目又不可控了。那怎么辦呢?
解決方案
很簡單,我們只干了一件事情,就是在Hive層面上進行了一波Hack。比如說我要讓原來叫bi.o2的表未來會變成mart_b.o2,我就同時允許你以mart_b.o2和bi.o2這兩種方式去訪問bi.o2這張表就好了。不管是寫入還是讀取,我們只需要在Hive的元數據層面去做一層Hack,然后做一個對應表,這個對應表我們是有規范的、能梳理出來的。在這之后,任何一個人都可以把他的任務改寫成他希望的樣子而不受任何影響,他寫的那些表還是原來的那些表,真正在物理上的存在還是bi.什么什么這樣的表,我們整個項目就run起來了。
具體的實施流程是這樣,首先先梳理業務,確定整體的映射關系。然后Hive元數據入口上去做別名能力,我們是在Hive metaserver里面去改的,大部分請求都在這里面,包括Spark的、Presto的、Hive的等,都能兼容掉,推動分批次改寫,單任務內以及任務鏈條內完全不需要做依賴關系的約束,最終真正實現的是自動化地把SQL文本替換掉了。業務的同學們只需要批量看一個檢測報告,比如說數據對應上有沒有什么問題,然后一鍵就切了。
我們用了一個季度業務側來磨合、嘗試練習和熟練,同時做工具的開發。然后第二個季度結束后,我們就完成了7000多個任務中90%SQL任務批量的改寫。當任務都切完了之后,我們還有手段,因為所有的請求都是從Hive的metaserver去訪問的,當你還有原有的訪問模式的時候,我就可以找到你,你是哪一個任務來的,然后你什么東西改沒改,改完了之后我們可以去進行物理上的真正切分,干掉這種元數據對應關系。
物理上的真正切分其實就是把原來都統一的庫,按照配置去散到真實的物理上對應的庫上,本質還是改NN一個事情。
總結與展望
未來——常態化多機房方案
我們目前正在做的一個項目,就是常態化地把集群跨機房去跑,其中最核心的就是我們需要對跨機房的數據進行非常強的管理能力,本質上是一個Block粒度Cache的事情,比如說Cache的擊穿、Cache的預熱或者Cache的等待等等,都是一個Cache管理的事情。我們會引入一個新的server,叫zone Server,所有的Client請求,NameNode進行塊分布的時候,調整和修改。之后大家會在美團點評技術博客上看到我們的方案。
反思——技術換運營
數據平臺做起來是很痛苦的,痛苦在哪兒呢?第一,數據平臺對上層提供的不只是RPC接口,它要管的是數據表和計算任務。所以我們做SLA很難,但是我們還在努力去做。第二,就是最開始的時候一定是基于開源系統拼接出來的,然后再到平臺化,這一定是一個規范的收斂,也是限制增多的過程。在這個過程中,我們必須去推動上面應用的、不符合規范的部分,推動他們去符合新的規范。平臺的變更即使做到兼容,我們的整體收尾還是要盡快掃清的,不然整個平臺就會出現同時進行大量灰度、每一個模塊當前都有多種狀態的情況,這是不可維護的。
綜上,我們定義了一個概念叫“可運營性”,推動用戶去做遷移、做改動是一個"運營的事情"。可運營性基本上的要求如下。
可灰度。任務的改動是可灰度的。
可關門。當某一刻,我不允許你再新增不符合新規范的任務、表或者配置,我們內部叫“關門打狗”,就是說先把新增的部分限制住,然后再去慢慢清理老的。
進度可知。清理老的我們需要有一個進度可知,需要有手段去抓到還有哪些任務不符合我們新的規范。
分工可知。抓到任務的分工是誰,推動相關團隊去改動。
變更兼容/替代方案。我們肯定過程中會遇到一些人說:不行,我改不動了,你deadline太早了,我搞不定。這時候得有一些降級或者兼容變更的一些方案。
那我們什么時候去使用技術降低運營成本呢?前面已經有兩個例子,就集群的遷移和融合,還有Hive表別名去幫助他們改任務名,這都是用技術手段去降低運營成本的。
怎么做到呢?
第一是找核心問題,我們能否徹底規避運營、能不能自動化?在集群融合的過程當中,其實已經徹底避免了運營的問題,用戶根本都不需要感知,相當于在這一層面都抽象掉了。第二,是即使我沒法規避,那我能不能讓運營變得批量化、并行化、流水線化、自動化?然后當你抓核心問題有了一個方案之后,就小范圍去迭代、去測試。最后還有一點,引入架構變更的復雜度最終要能清理掉,新增的臨時功能最后是可被下線的。
體會——復雜系統重構與融合
最后稍微聊一下復雜系統的重構與融合。從項目管理的角度上來講,怎么去管控?復雜系統的重構還有融合本質上最大的挑戰其實是一個復雜度管理的事情,我們不可能不出問題,關鍵是出問題后,對影響的范圍可控。
從兩個層面去拆分,第一個層面是,先明確定義目標,這個目標是能拆到一個獨立團隊里去做的,比如說我們最開始那四個大的目標,這樣保證團隊間能并行地進行推動,其實是一點流水線的思路。第二,我們在團隊內進行目標的拆分,拆分就相對清晰了,先確定我要變更什么,然后內部brainstorming,翻代碼去查找、測試、分析到底會對什么東西產生影響,然后去改動、測試、制定上線計劃。
內部要制定明確的上線流程,我記得當時在做的時候從11月到12月我們拆分了應該是有11次上線,基本上每次大的上線都是在周末做的,10、11、12月總共有12個周末,一共上線11次,大的上線應該是占了7到8個周末吧。要提前準備好如何管理依賴,如何串行化,然后準備上線,上線完怎么管理,這些都是在整個項目管理過程當中需要考慮的。
其中,兩個可能大家都持續提的東西,第一個是監控,要知道改完了之后發生了什么,在改的時候就像加測試用例一樣把改動部分的監控加好。第二要有抓手,如果我線上垮了,這個時候重復恢復的成本太高,也就是完全重啟、完全回滾的成本太高,我能不能線上進行一些改動?
最后這張圖,獻給大家,希望大家在對自己系統改動的時候,都能像這哥們一樣從容。
上期獲獎名單:
Sprit^Moon
兔子什么都知道
王鵬
"雙曲線
無痕
請這5位同學把地址和聯系方式發送至后臺,小編將為你們寄出精美獎品。
熱門博客大數據
人工智能在線特征系統中的數據存取技術
美團點評酒旅數據倉庫建設實踐
美團點評數據庫中間件DBProxy開源
美團點評
技術團隊
http://tech.meituan.com
長按二維碼關注我們
總結
以上是生活随笔為你收集整理的行进中换轮胎——万字长文解析美团和大众点评两大数据平台是怎么融合的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: teechart的addarray_Te
- 下一篇: 使用SQL查询分析器删除所有用户表