餓了么業務爆發性增長欠下的“技術債”,遲早都是要還的!
餓了么成立于 2008 年,2014 年底開始迎來業務的大規模爆發性增長,2015-2016 年餓了么進入高速發展期,業務和服務器的增長都在數十倍的規模,這種大規模的增長必然帶來很多挑戰。
本文將通過餓了么運維基礎設施的進化史和大家分享不同時期應對挑戰的措施和思路。
餓了么運維 1.0 時代
2014 年至 2015 年被稱為餓了么的 1.0 時代,業務迎來高速發展,這時考慮更多的是業務需要什么就趕緊上什么,而不是長遠的架構等問題。
每個人或團隊負責自己一部分的工作,全力配合業務的需求。可想而知,在這個過程中會有很多的由于考慮不周而產生的“技術債”,也就是所謂的“痛”點。
01網絡的痛
網絡的痛主要表現在以下幾點:
- 沒有標準化,IP 亂掛。外網 IP 直接掛到服務器上,有的服務器可能有 2 個甚至 3 個 IP;有的有 bonding;有的沒有。
- 攻擊多,業務高速增長的情況下還會遭遇大量的攻擊,一遇到攻擊就可能宕機。
- 帶寬收斂比較低,因為流量太大,如緩存高帶寬的情況,交換機上聯端口或者服務器千兆網卡很快被打滿。
- 監控缺失,出了問題技術團隊不知道,騎手或用戶說不能下單了之后各種投訴,由客服反饋過來。
- 單點,從業務到整體架構到每個業務甚至機器都存在很多單點。
- 鏈路質量不穩定。
02服務器的痛
資源的痛主要表現在:
- 服務器交付不及時,去年到今年,我們最高周交付量是 3700+ 臺邏輯服務器。平均下來每個月都是幾千臺的交付、回收,對效率要求非常高。
- 資產管理缺失,無標準,維護成本高。這時處于野蠻增長時期,需要服務器就趕緊買,不會考慮有多少服務器。也不知道服務器都是什么配置的,沒有標準化,可能這一臺有 SSD,另一臺就沒有。這樣導致維護起來成本非常高。
- 交付質量無保證,全部都是人肉裝機,2015 年底的情況是買進一批機器就臨時組成一個裝機小分隊,一起裝機。因為都是人肉操作,慢且交付質量無法保證,排查更困難。
03基礎服務缺失
基礎服務缺失主要體現在:
- 監控方面,最早是用 Zabbix,配置不一導致有些硬盤沒有監控、IOPS 是多少都是缺失的,業務層監控也沒有覆蓋全。
- 負載均衡,每個業務自己搞一兩臺服務器,掛個 Nginx 做反向代理,都是這么隨便做的。
- 集中式文件存儲,每一臺服務器會把很多文件存在本地,這為整個基礎設施管理帶來很多問題。
舉個例子,有的東西,比如理論上互聯網很多的 SOA 服務都是無狀態的,本地除了代碼之外,不應該有其他的東西,但發生故障的時候,業務因為監控不成熟無法確認問題,需要看日志,這就復雜了,有人說要保留一周,有人說要保留一個月,有時日志一天就是幾十個 G 怎么辦?那就加一塊硬盤,怎么加?誰來采購和管理?后面的標準化怎么做?集中式日志、集中式文件存儲都是為了解決標準化的問題。
- 基礎的服務也非常混亂。
1.0時代做了什么?
面對這么多的問題我們怎么辦?運維做以下三件事情就夠了:
- 標準化,從硬件到網絡到操作系統到使用的技術棧、軟件的安裝方式、日志的存放路徑、名稱、代碼部署方式、監控從上到下,要建立一套體系化的標準。有了標準就可以用代碼自動化,有了自動化和標準化之后就可以實現良性循環。
- 流程化,流程化是把很多的需求通過步驟進行規范化和標準化。
- 平臺,構建一個平臺實現標準化和自動化。
我理解的是運維需要做兩個生命周期的管理:
- 資源的生命周期管理,包括資源的采購、上架、部署、代碼、故障處理、服務器回收、報廢等。
- 應用的生命周期管理,包括應用開發、測試、上線、變更,應用下線、回收等。
01標準化
關于標準化有一個概念,就是要讓我們的用戶做選擇題,而不是問答題。
舉個例子,用戶經常會說我要一臺 24 核 32G 600G 硬盤的機器,這時你應該告訴用戶:我現在有 A、B、C、D 四種機型,分別是計算型、存儲型、內存型、高 I/O 型,你要哪種?
這很重要,很多用戶只是習慣了兩臺機器:一臺配 200G 硬盤,一臺配 250G 硬盤。用戶的需求千奇百怪,如果沒有標準化很難做到。
我們的服務器型號是統一的,提供各種型號,你需要和用戶談,收集用戶需求,盡量辨別出來用戶的真實需求。
機型采購的時候要做定制化,比如要不要把省電模式關掉。各個廠商還有一些坑,包括直通卡的盤符漂移等問題,如何做自動化,機器來了如何自動上線。
服務器出廠和上架也要做定制化,我們把資源標成一個個模塊,最小的模塊是 3 個機柜,每個機柜放多少臺服務器是固定的。
生產的時候,比如說我要采購一千臺服務器,我告訴廠商我已經規劃好了,這一千臺服務器放在哪一個機房里,哪一個機柜,哪一個 U 位,廠商會做定制化,機器到貨上架之后,廠家人或服務商把電一接,操作系統自動化安裝,甚至是網絡,每一層都是標準化的。
02流程+自動化
上圖展示的是餓了么的工作流引擎,可以理解為資源生命周期中有很多流程:
- 如服務器的申請,包括物理機申請、虛擬機申請、云服務申請等。
- 如大量狀態,包括回收等。
流程的背后是自動化,規范用戶輸入,讓用戶做選擇題,要什么樣的機型、什么樣的配置、多少數量,表單一填好,后臺就自動化地執行了。
03自動化+平臺
- 物理服務器自動化裝機及初始化。比如我有幾千臺服務器,能不能一天裝好?360 曾經一天最高裝了 5000 臺服務器,我們的最高紀錄是一天裝機 2500 臺物理服務器。
- 網絡設備上線自動化。
- 資源管理平臺。對所有的資源能做統一化管理,類似資源交付流程的管理后臺。
- 分布式文件系統,主要用于數據庫備份及圖片處理。
- 日志集中平臺,所有的日志集中到 elk 上,不用上服務器看日志了。
04私有云平臺(Zstack)
餓了么早期實行野蠻生長的方式,虛擬機就是自己創建。創建完了會有一個問題:怎么知道一個機器可以再創建呢?
比如說,我一個機器可以創建 6 臺虛擬機,現在已經創建 5 臺了,怎么知道還有一臺創建在哪里?
當需要把一個業務布置到 10 臺物理機,甚至是跨機柜的,為避免單點物理機或單個機柜出現故障,影響全局應用,這就涉及到了虛擬機的資源調度,這時我們選用了 ZStack。
為什么選用 ZStack 呢?
私有云比較火的三個開源技術選型分別是:
- OpenStack。
- CloudStack。
- ZStack。
本著越簡單越好的原則,我們排除了 OpenStack。它太重了,沒有人也沒有時間去 Hold 這么大的系統,而且從行業內得到一些反饋,總體來說不是很好。
CloudStack 的開發者也是 ZStack 的開發者,當時 CloudStack 社區已經沒有人維護了,并且它不支持 CentOS7。
所以我們選用了 ZStack,那個時候 ZStack 也有不少 Bug,但還是比較簡單的,我們可以做好。
ZStack 的特點:簡單、無狀態、接口化
ZStack比較簡單,安裝一下,就可以跑起來了。當然想要用好,后面還是有點難度的。
它是一個中心結構,所有的都是基于消息做的,我們的 ZStack 平臺看不到什么高大上的頁面,后面都是自定義的接口,前端的流程自動調后端的接口,通過一些消息來進行同步。ZStack 目前已經管理了超過 6000 臺虛擬機。
餓了么運維 2.0 時代
在 1.0 時代我們做了一些標準化、自動化的工作,讓我們的系統順暢地跑起來。從 2016 年開始,我們進入了 2.0 時代。
這個階段也存在一些痛點:
- SLA 是什么?
- 有數據嗎?
- 你說效率很高了,如何證明?
- 一天交付 1000 就是高嗎?
- 數據怎么衡量?
在 IT 圈里,除了上帝,所有的東西都要用數據說話,一切要可量化,可衡量。
2.0 時代做了什么?
這個時期我們解決痛點的措施從兩方面著手:精細化運維和數據化運營。運維和運營是不一樣的。
01精細化運維
精細化運維包括以下幾個方面:
- 網絡架構的持續升級。
- 服務器性能基線制定。
- 服務器交付質量校驗(不合格不交付)。
- 硬件故障報修自動化。
- 網絡流量分析。
- 服務器重啟自動化。
- Bug fix:省電模式、bonding 等。
網絡架構持續升級
早期我們有一個數據中心,使用的核心交換機是華為的 5700SE,這意味著什么?
在一次流量突發中,這個設備引發了我們 P0 級的事故。所有我們重新定義了網絡標準,并持續做了大量的網絡升級,包括核心、負載均衡、匯聚到核心的帶寬,以及網絡架構優化。
還有 IDC 間鏈路,最早我們一些 IDC 間鏈路是打的 VPN,現在同城的用裸纖,跨城的都是用傳輸,這里也有依稀持續的投入。
網絡優化
如圖中所示,北京和上海的 IDC,從辦公室訪問 IDC 我們都拉了裸纖和專線,全部做到足夠的強壯。還包括到第三方支付的,比如支付寶、微信支付等等。
服務器的性能基線制定,交付質量校驗
交付的服務器是否足夠好,要用數據說話。我們所有的服務器都有一個基線,比如一種計算型的機型,計算能力、I/O 能力是多少、網卡小包的 PPS 可以達到多少等都是可以測試的。
在交付的時候會進行性能測試,達到基線才可以交付,否則就不能交付。
網絡流量分析
我們當初遇到過匯聚到接入之間某根光纖帶寬跑滿的情況,因為早期帶寬收斂比不夠,4 個 10G 在上面,由于網絡流量的算法原因,導致 4 個 10G 端口的其中一個被跑滿了。
我們要知道關鍵節點的流量是哪一個業務在跑、跑的怎么樣,有問題要及時告警。
硬件故障保修自動化
目前我們的服務器數量很多,每周可能存在數十臺的故障,怎么第一時間知道故障,并且在不影響業務的情況下快速修復?
還有一些其他的工作,如服務器的自動化重啟,做運維都很辛苦,如果半夜有一個故障或者服務器壞了,需要重啟;如果你還得通過遠程管理卡輸入密碼登錄進去重啟,就太 Low 了,要實現自動化重啟。
服務器自動化報修總體來說是這幾個邏輯:
- 故障發現。
- 故障通知:用戶、IDC、供應商。
- 故障處理。
- 故障恢復校驗。
- 故障分析。
第一是故障發現,如何發現資源故障?監控,帶內、帶外、日志多方位監控。所有監控的報警到一個地方來做初步的收集,最后就會到這個系統。
這是 9 月 19 日的圖,可以看到有非常多的故障,發現這些故障之后要通知,通知也是很復雜的,是短信、電話還是內部的工具?
我們要多渠道地進行通知,有的用戶比較牛,他說你不用給我發郵件,我這邊有一個接口,可以做自動化的發送。
比如我們的服務器故障了,自動給他發一個消息:
- 收到這個消息之后,業務就開始把這個機器關掉,甚至把數據操作等一系列操作做完。
- 做完之后返還給報修系統一個消息:這個服務器你可以去維修了。
- 收到這個消息之后,通知 IDC、供應商:哪一個機房、哪一個機柜、哪一個 U 位、序列號多少的服務器發生了什么問題,請于什么時間段上門維修。
- 同時通過各種方式告訴 IDC:誰身份證號多少,什么時間會帶著什么設備上門做哪一個地方的維修。
我們數以萬計的服務器只有兩個人來進行運維。供應商維修、故障處理是人肉的,處理之后登陸外部系統,給我們發一個消息,告訴我們這個服務器修好了,我們的程序會自動檢查故障有沒有恢復。
如果恢復了,就通知用戶說資源什么時候修好了,用戶接到消息,會把服務器再拉回來。
同時所有的故障信息都會進入我的數據庫,自動進行分析,看到哪一個品牌的服務器不好、哪一個機型或者是哪一個配件壞的比較多,在做供應商和機型選擇的時候就可以有一個參考。
精細化運維還有各種 Bug Fix 等很多細節,細節是魔鬼。當初被省電模式坑得很慘,包括網卡的問題,從硬件到服務,代碼的 Bug 就更多了。
運維管理平臺
我們有很多機柜、機房,這些數據都通過自動化的系統進行采集和展示。
運維重點需要考慮三件事情:
- 質量。
- 效率。
- 成本。
從上圖中可以看到這是一個模塊,這個模塊當中有很多的機柜,這些機柜用電量很大,這就體現出了成本,我們大量的機柜是黃色,黃色是告警。
一個機柜的電量是 4000W、5000W,我們會盡量把資源充分利用起來,成本相對最優。所以我們的機柜都是一些比較高電的,比如說 47U 的機柜我們會放很多的設備。
02數據化運營
IT 所有的東西都要用數據說話。
資產情況
資產情況包括:我們有多少服務器、分布在哪些機房、有多少機柜、服務器是什么機型、品牌和型號、哪些是占用的、哪些是未用的等。
網絡流量分析
網絡流量分析包括:網絡流量來自于哪些人,比如說這里有一個異常突起,我就知道這是由跨城帶寬傳輸造成的。
跨城帶寬大家都知道,是非常貴的。10G 帶寬一下子跑滿了,擴容要三個月,這個時候整體業務會受到嚴重影響,我們要第一時間知道誰在用這些流量。
服務器去哪兒了
我們買了那么多公司的東西,得知道這些機器誰在用?圖中的這條線是資源利用率,這是大數據部門的使用情況,從圖中可以看到大數據的資源利用率是很高的,而其他的部門資源利用率不高。
通過這個數據我給你發報表,告訴你花了多少錢,用了多少服務器,什么類型的服務器,分布情況和利用率是多少。這是運營的思想,而不是運維的思想。
資源交付 SLA
我們的工作量如何衡量?我們交付了很多服務器,什么時間交付的、交付的是什么型號、交付的效率如何?一定要可衡量。
舉個例子,做年終 KPI 考核的時候,你說我們部門做了很多工作,這個工程、那個項目,這些都是廢話。
你只要告訴我,今年做了幾個項目,這些項目分別部署了多少資源、效率是什么,以前平均交付時間是 2 小時,現在是 20 分鐘,未來是 5 分鐘。
成本核算
今年我們花了很多錢,這么多錢花在哪里?誰花的?買了什么?給誰用了?用得怎么樣?
從各個維度來看,這些成本的構成等等,甚至我們的成本和友商的成本對比,都通過這些數據可以看出來。
供應商的質量評價
比如每個配件什么時候故障了,故障率是多少?自動給廠商打分,報表會自動交到采購,作為采購的一個技術評分,這個過程沒有人的介入。
包括質量方面,某一個廠商這一段時間的質量下降了,可以要對他進行售后管理。
總結
這次分析主要是資源生命周期管理,本文大部分內容偏向于底層資源,但思想可以落到所有的模塊,比如日志、不同運維系統、監控等。
最后談一些感想:
簡單及可用
我從入行到現在從事互聯網運維差不多十年時間,早期服務器的故障需要很懂的人一臺一臺地去看。
現在的做法是一臺服務器出問題了,直接拉掉,讓另外一臺服務器快速頂上去,成本可控、質量可控、效率第一,這種情況下一定要簡單及可用。
這句話最早是百度傳出來的,這也是我做運維的一個準則,一切的東西都要簡單。
有一些開源的解決方案具備很多很牛的功能,但你要深刻思考你真的需要嗎?它真的對你有幫助嗎?真正核心的價值是什么?所有軟件程序必須要做到高類聚低耦合,避免很強的依賴。
標準化和自動化
標準化能標準化的,自動化可以自動化的。標準化一定是未來的趨勢,現在隨著阿里云、騰訊云的發展,小的公司很多東西都會遷移到云上,未來混合云的架構,運維可以做什么?
怎么做到快速的擴容和彈性計算,彈性計算包括容量規劃、壓測等,這當中有很多的點,這些點的基石就是標準化、自動化。
自己造輪子
盡量不要重復造輪子,自己造輪子。搞開發的人很喜歡造輪子,總覺得我到一家公司,不寫點東西,顯得我很 Low 或者沒有績效。
“用好”軟件比用“好”軟件更重要。工具沒有好壞之分,就看你能不能用好,在對的時間做對的事情,不要對工具有偏見,它只是一塊磚,我們要做的是把這些磚做好合并,用好這些磚。
80 分萬歲
先有,后好(80分萬歲)。萬事起頭難,第一步一定要先有。不要說我想一個東西想得很宏大,各個方面設計特別牛,要考慮的是這個東西能落地嗎?
落地是最重要的。那有人會問做了很多東西,可是很爛怎么辦?先收口,收口之后慢慢優化。
快速迭代
互聯網快速發展,互聯網應用一定要快速迭代。我們公司每天有數百次發布,對于敏捷式開發快速更新非常重要。
這個過程一定是螺旋式上升的,甚至有前進兩步后退一步的情況。不要說誰家的架構就是最牛的,只有適合你才是最好的,而且不同階段適合你的東西是不一樣的,需要不斷重構和迭代。
現有用戶和新用戶同等重要
這是亞馬遜提出來的,亞馬遜有一件很有名的事情:當年有一個用戶要將服務遷移到亞馬遜,預計上千萬美金。
亞馬遜評價說,這個服務遷過來,要做什么樣的改造,這個改造會對現有業務的穩定性造成什么影響。經過層層上報,最后的結論是這個用戶我不要了。因為接受后現有用戶得不到保障。
這一點非常重要,2016 年 9 月份,我們的日志系統上線,剛剛上線的時候,峰值 8 萬/秒的請求量,到 10 月份達到 80 萬/秒,這時還不斷有用戶過來說要接入。
我當時感覺硬件、架構等方面都快 Hold 不住了,我跟大家說了這件事情,給自己爭取了 1 個月的緩沖期,做了大量的技術改造,現在峰值每天超過 260 萬條日志,也可以進行實時的收集、傳輸、存儲、分析。
這當中一定要找一個平衡,在服務好現有用戶的同時,逐步接入新用戶,當然也不能很生硬的說“no way”,這樣你的品牌就沒有了。
擁抱變化
擁抱變化,不要有玻璃心。我工作了很多年,也去過好幾家公司,可以看到每家公司在不同階段都有不同的變化。
比如我的團隊中基本上都是開發沒有運維了,標準化做好了,底層就是一個硬件軟件,一個操作系統專家,其他的都是一些程序員。
可是很多人本身是做運維的怎么辦?要開始學習代碼,要有變化和成長。
今年我給團隊的目標是 2017 年要把我們這個團隊做沒了。意思是要做到無人值守,或者只花 10%、20% 的時間和精力做后臺的 Bug Fix,其他 80% 的時間做價值輸出,現在這個目標已經在落地的過程當中了。
徐巍
餓了么高級運維經理
目前在餓了么負責基礎設施的運維及開發工作,曾就職于 PPTV、攜程、游族等公司,是一個擁有近十年經驗的運維老兵。