《鏈家網(wǎng)技術(shù)總監(jiān)陳爾冬:鏈家網(wǎng)的第三種運維》要點:
本文介紹了鏈家網(wǎng)技術(shù)總監(jiān)陳爾冬:鏈家網(wǎng)的第三種運維,希望對您有用。如果有疑問,可以聯(lián)系我們。
陳爾冬
鏈家網(wǎng) 技術(shù)總監(jiān)
曾于新浪任職技術(shù)總監(jiān),負責(zé)私有云平臺研發(fā)與運維并支撐新浪微博從零至上市高速發(fā)展的過程.后于華為任職技術(shù)專家,致力于提升華為公有云運維能力.今年初受鳥哥邀請加入鏈家網(wǎng),負責(zé)基礎(chǔ)設(shè)施研發(fā)與運維工作.曾譯《奔跑吧,Ansible》一書.最近幾年一直致力于研究如何根據(jù)公司不同情況,打造出最適合的運維體系.
作者先前就職于新浪,是新浪私有云的負責(zé)人.從微博初始,一直到微博上市參與了項目全過程,歷次的比較大的技術(shù)改造都有參與.
作者受鳥哥邀請,加入鏈家做 SRE,鏈家是個比較特別的模式.
到鏈家之后發(fā)現(xiàn)鏈家既用公有云亞馬遜 AWS,同時也有自己的數(shù)據(jù)中心、服務(wù)器、基礎(chǔ)設(shè)施,可能未來鏈家會考慮把它逐漸做成混合云.
從私有云到公有云到混合云經(jīng)歷過來,作者的經(jīng)驗恰恰都可以覆蓋,本文的思路希望給讀者帶來一些新的想法.
為什么叫第三種運維?鏈家這兩年提出了一個概念:第三種中介.
其實鏈家很早以前就一直在探索我們怎么樣利用技術(shù)來加速業(yè)務(wù).最早是傳統(tǒng) IT 公司思路,現(xiàn)在是利用互聯(lián)網(wǎng),如何把互聯(lián)網(wǎng)和房產(chǎn)中介相結(jié)合.
很早以前鏈家的老板找到 IBM 做咨詢,探索到底要不要做互聯(lián)網(wǎng),要推翻線下的中介經(jīng)紀人制度嗎?
IBM 的專家們也給鏈家做了非常深度的咨詢,最后負責(zé)做戰(zhàn)略的這位 IBM 的專家就加入到了鏈家,也是我們鏈家網(wǎng)現(xiàn)在的 CEO.
鏈家在傳統(tǒng)線下中介和完全互聯(lián)網(wǎng)化的房產(chǎn)中介之間找到一個灰度,既不是傳統(tǒng)的中介也不是完全互聯(lián)網(wǎng)化去經(jīng)紀人的互聯(lián)網(wǎng)中介,而是一種線下的經(jīng)紀人和線上的互聯(lián)網(wǎng)產(chǎn)品相結(jié)合的新型中介,所以鏈家叫它第三種中介.
我思考自己的職業(yè)生涯,做了這么多年的運維,一直以來想要追求運維的模式和鏈家探尋的結(jié)果很像.我們現(xiàn)在會看到很多朋友們探索的理念,不管是某種運維還是 DevOps 還是 SRE.
其實我們都在謀求尋找最終的目標,到底是一個什么樣的運維狀態(tài)?它和我們的傳統(tǒng)運維在某種程度上可能是相對立的.
因為我們不希望利用人工,或利用自己的責(zé)任心和勞動時間,去解決這樣的問題,所以我們將這兩種運維的模式暫且放在對立的兩端.
我們在真實世界中存在的運維的模式實際上是第三種運維模式,是在這種完美理想化的運維模式和傳統(tǒng)的運維模式之間的一種運維模式.現(xiàn)實世界既是美好的又是真實的又是殘酷的,不可能完全按照你的理想復(fù)制.
我可以拿出一些我們的項目細節(jié)給大家舉例,但是有的項目是不開源的,我們和大家面臨的問題也很難完全一樣,只能在這吹一吹,也許對大家參考價值有限.
其實我更希望去介紹我們遇到某個問題的時候,是通過什么樣的思路去選擇什么樣的方案.根據(jù)我們的環(huán)境選擇什么樣的方案,也許我們選擇的方案或者我們選擇的技術(shù)點和大家所在的環(huán)境不一定適合.
但是我們所思考的方式,覺得應(yīng)該講一講,大家可能會有一些收獲.因為我們都是做計算機的,我們都會本能的覺得這個世界上可能就是 0 和 1,但是做了一時間工作以后,工作的種類是開發(fā)也好,運維也罷,你會發(fā)現(xiàn)這個世界不只是 0 和 1.
我們經(jīng)常會講上線要灰度,實際上我發(fā)現(xiàn)所有的事情都要灰度.我在華為的時候也有這樣的經(jīng)歷,華為的老板有一個很著名的講話,我們要灰度一切,要把一些的工作乃至管理都做到灰度化.
灰度一切的意思是說做事不能一刀切,要么這么干,要么那么干.在過程之中會有一個甚至多個中間狀態(tài),甚至最終落地也落在中間狀態(tài).這個工作的思路,恰恰和我對運維工作的一個理念相符.
首先我們聊聊虛擬化和容器,不管是虛擬化還是容器都是很專業(yè)的一個領(lǐng)域,可以聊得很深入.說到虛擬化和容器,大家可能會本能的想到兩個很有名的開源項目,一個是 OpenStack,一個是 Docker.
在做這些工作的時候我會聽到很多聲音,比如,我以前在新浪經(jīng)常會出來吹牛,說新浪幾乎在國內(nèi)最早做云計算的公司.有些人就會覺得很夸張,會覺得 04 年就敢說在做云計算,八成就是在公司搭一堆虛擬機,連管理平臺都沒有.
另外一個例子,有的朋友聽說鏈家想做混合云,問我:“你的方案是什么?是基于容器做還是基于 OpenStack?”
我還遇到這樣的朋友,在他們心里,私有云如果不用 OpenStack,就是基于 VM 去自己建設(shè),類似很多這樣的例子.
不過要說讓我感觸最深的,還是前陣子聽到有個朋友說“現(xiàn)在做運維,除了用 Docker 就沒啥新技術(shù)了.”
這些聲音代表了一類朋友,他們覺得容器就是混合云的唯一方案,覺得 OpenStack 或者虛擬化技術(shù)就是云計算的唯一方案,這些技術(shù)與產(chǎn)品之間是劃等號的.如果要做云計算,就一定要用容器、或者虛擬化技術(shù).
我認為這樣的觀點有失偏頗,所以想以容器這個技術(shù)為切入點,講述我對新技術(shù)的理解過程.
這是一張今年秋天日本京都的一張照片.具體地點是日本京都著名地標清水寺.清水寺秋天的時候會有很多紅葉,特別美.大家看清水寺舞臺下面的紅葉,密密麻麻的很美.但是仔細看,一大片紅葉還是挺亂的.
但是我們想象拿一片紅葉在手上,紅葉上會有脈絡(luò).就像上圖,它是很有序的,而且你拿到每一個紅葉一定是有很相近的脈絡(luò).
我們可以這樣理解,一片紅葉就是亂中有序.但這跟容器有什么關(guān)系呢?別著急,我們按照這樣的一個思考方式研究容器.
Container 本來的意思是集裝箱,集裝箱和剛才我講的紅葉有可以類比的.集裝箱其實與紅葉是相反的,序中有亂.我們看到這個碼頭全都是集裝箱,是不是特別有規(guī)律?可能顏色不一樣,但是大小都是一樣的.
我們?nèi)绻枰鞘羞\輸、輪船跨國運輸,以及在碼頭將貨物搬上或搬下貨輪,只要匹配這個尺寸,就可以完成工作.至于它里面運的什么東西,實際搬運的真實貨物都不用去考慮了.不管食品還是電器,只要把集裝箱運過來了,這個東西就過來了,我理解容器就像這樣,序中有亂.
什么時候你需要序中有亂?
我舉一個例子,如果我所在的公司很大.然后有上百個團隊去做開發(fā),每一個團隊開發(fā)的技術(shù)架構(gòu)都不一樣,使用的語言也不一樣:有的是 JAVA,有的是 PHP,有的是 Python,有的是 C/C++.即便同樣是 JAVA 語言,有的是 HTTP 協(xié)議的,有的是私有協(xié)議.
那么如果我的團隊來運維這所有的系統(tǒng),這個架構(gòu)相當亂.需要為所有的這些系統(tǒng)做運維,怎么做?
開發(fā)團隊很大,加起來有上萬人,我就算有幾百人,肯定也做不過來.這時候就適合使用容器技術(shù),實現(xiàn)序中有亂.亂在你集裝箱內(nèi),對我的團隊來講,這里就是上萬個集裝箱,每一個集裝箱的尺寸是完全一樣的,我做一個基礎(chǔ)設(shè)施可以去把集裝箱從這里搬到那里,就搞定了.
集裝箱內(nèi)的東西每個研發(fā)團隊自己去搞定,這是一種工作模式.我認為容器在這個領(lǐng)域是非常適合的,也就是沒有辦法讓架構(gòu)從頭到腳有序的時候.
但是,我們工作的場景是什么樣的呢?有的公司里面是不亂的.比如我原來在新浪的時候有一段階段新浪所有項目都是 PHP,而且都用 Apache 做 Web 服務(wù)器.我們又設(shè)立了一些規(guī)范讓研發(fā)團隊去遵守,整體架構(gòu)完全統(tǒng)一的.這時候我們還要必要容器嗎?
我個人覺得這是需要考慮的,為什么呢?因為如果你要引入容器,終究會增加成本.等價交換是這個世界的鐵則.你用了新的技術(shù)容器,它幫你解決了序中有亂的問題,你就要管理它.
我們?nèi)绻捎眯录夹g(shù),但只有五個人,首先我有疑問:這能搞得定嗎?是否可以不用容器,為什么一定要用呢?.再則,我們的架構(gòu)里其實已經(jīng)有容器了.Tomcat 就是個容器,從系統(tǒng)層看到的都是 Tomcat,但里面是不同的 JAVA 的程序,其實也是個亂之有序的架構(gòu).
這時候有朋友會提出問題,說 Docker 是可以實現(xiàn)資源隔離的.Tomcat 沒有這個功能,可能會資源互相影響.其實 Docker 實現(xiàn)資源隔離是利用了 CGroup.為什么 Docker 用了 CGroup,我們不能用呢?最后看看一個沒有 Docker 的彈性計算方案.
下面那三個我們可以認為跑在同一臺服務(wù)器上.同一臺服務(wù)器跑了多個應(yīng)用實例,我們可以理解為每個 Tomcat 監(jiān)聽不一樣的端口,我在七層負載均衡上把端口映射到不一樣的端口上.
這個時候一個服務(wù)器上就有多個容器了,只不過容器是 Tomcat,不是 Docker.我們再對這多個 Tomcat 利用?CGroup?做資源隔離甚至資源統(tǒng)計.如果你有一套強大的管理系統(tǒng),可以把這七層映射關(guān)系以及這些 Tomcat 配置文件配置起來的話,那么這套彈性計算云就完成了.
我個人理解,這套基礎(chǔ)設(shè)施比 Docker 對于我的團隊來講更容易管理.因為我的團隊這些工程師,他以前是做傳統(tǒng)運維的,對 Tomcat 很熟,對于 Ansible、Puppet、SaltStack 這些配管工具很熟.
他們管理物理服務(wù)器非常熟悉,但讓他們今天開始管容器,他需要一些時間.再加上容器項目本身成熟度問題,我認為對我團隊這就是目前為止最好的方案.
未來 Tomcat 會不會變成容器呢?不好說.也許以后 Docker 成熟了,某些方面比我這個方案更好.現(xiàn)在這個時間點,我認為對于我的團隊來講它是一個更好的方案.
話又回到開篇所提及.對于您的團隊是不是一定是這個方案是最好的方案呢?也許吧.
但我可以把我思考的思路以及我的理念寫出來去做一個分享.在您的場景可以按我們的方式重新去思考一下,也許對您的團隊來講用 Docker 是更好的方式,也許您會探索出新的方案也未可知.
今天,大家都愛講微服務(wù).不管這個服務(wù)微不微,服務(wù)化已經(jīng)是標配了.服務(wù)化后,整個架構(gòu)中有數(shù)十個或上百個服務(wù),每個服務(wù)做一件事,服務(wù)和服務(wù)之間的通信通過 RPC 實現(xiàn).
服務(wù)之間 RPC 是很常見的事.如果一切都正常,那么一切都好,但如果某一個可能會被調(diào)用的資源變得慢的話,這個問題就來了.
如果有一個資源被調(diào)用慢,會產(chǎn)生兩種結(jié)果:
對于超時這類的結(jié)果,一般調(diào)用方會重試,因為我調(diào)用沒成功,邏輯跑不下去了.本來執(zhí)行處理就慢,已經(jīng)存在問題的情況了,但調(diào)用方又重試,500 毫秒就重試一次,就把這個服務(wù)給壓死了.
友誼的小船說翻就翻,不光是服務(wù)會出現(xiàn)這樣的故障,不同服務(wù)的團隊也容易打翻友誼的小船互相指責(zé).這邊說我是被你拖死的,那邊說你是把我壓死的,你的超時時間設(shè)計不合理.
遇到這種情況怎么解決這個問題呢?回到剛才在容器技術(shù)用到的思考方式,要想去解決,我們先分析到底這個問題點在哪.
我覺得這里面有兩個問題:
在這個點我們團隊從系統(tǒng)層面角度給了一個方案,我們現(xiàn)在的方式是這樣:當我慢了之后,M 個服務(wù)器,N 個進程,你就是 M+N 全部調(diào)到服務(wù)方了.我有 M 臺機器,有 N 個進程,最后還是M個服務(wù)器去調(diào)這個服務(wù),我肯定還是有調(diào)用,可以讓它去嘗試,如果慢就不要再調(diào)了.
我們給的方案是這樣,針對問題一,如果說我調(diào)用超時時間設(shè)得比較慢,在系統(tǒng)層檢測到后端的延遲,在慢的時候快速失敗,防止堵塞.
針對問題二,超時時間設(shè)得比較短,后面會被壓死,實際上是給了后面資源一個負向的正反饋.我們把這個反饋隔離,不要讓這個調(diào)用到后面去,后面是不是就不會壓死了.
那么解決方案就出來了:我們把這個系統(tǒng)叫做 RASH.我們把 Rash 運行在每一個應(yīng)用服務(wù)器上.
首先我們先寫了一個動態(tài)鏈接庫,把這個動態(tài)連接庫配到了 LD_PRELOAD.這么做的目的是為了劫持所有調(diào)用.所有的網(wǎng)絡(luò)調(diào)用會被劫持到 Socks4 代理上.
Socks4 使用協(xié)程模型,每個協(xié)程處理一個連接.它會監(jiān)測后面資源端給我們響應(yīng)的第一個應(yīng)用包,第一個應(yīng)用協(xié)議的響應(yīng)包的延時是多大,如果很慢,我們就快速的反饋失敗,如果很快就讓它正常運作.
很快或者很慢,現(xiàn)在說起來很簡單,到底怎么做呢?這里有個算法來處理這個問題.
我們先做一些假設(shè),設(shè)最大超時時間是 M,初始連接時間是 0,以后一旦有過連接就有統(tǒng)計了,這個連接用時設(shè)為Tt,本次連接的用時就是 Tc,現(xiàn)在隊列中已經(jīng)有進程數(shù)為 N.有了 M,N,Tt,Tc,當來了一個新的連接,入不入隊列呢?
需要判斷 Tt*N 是否小于等于 M.如果小于等于 M,那么就入隊列,如果大于,直接結(jié)束,返回一個錯誤.如果連接完成了,比如入隊列了,有一個連接完成了,我們會對這個連接記一個應(yīng)用返回的響應(yīng)時間 Tc,將 (Tt+Tc)/2 作為新的 Tt 值.
這樣就給他上一次連接做了一次反饋,如果上一個連接很快,它的歷史連接時間就會越來越短,如果上一個連接很慢,它的歷史連接時間就會越來越長.
算法講起來比較抽象,給大家用實例解釋一下.首先設(shè)置連接總隊列的時長,比如說 1 秒.隨后處理了一個連接,如果這個連接首包是 500 毫秒,這個隊列里面我就可以讓他進兩個連接.
如果下一個連接完成了,用的是 100 毫秒,下次我就可以讓他進三個.如果變長了,變成 1 秒甚至超過 1 秒了,那么未來只會讓隊列保持一個連接,一個以上的連接通通反饋失敗.
這樣的一個基礎(chǔ)設(shè)施就實現(xiàn)了剛才講的功能,如果被調(diào)用方出現(xiàn)延遲,就給超出延遲的連接快速的反饋失敗.如果他還重試,我們就把這個重試的反饋中斷,不讓它調(diào)用到被調(diào)用方.
命名服務(wù)不是一個新的概念,現(xiàn)在各位的公司大概都有自己的命名服務(wù).實際上在有互聯(lián)網(wǎng)的時候就有命名服務(wù).命名服務(wù)就有點像我小時候的黃頁.
小時候去我父母的公司玩,那時候電話數(shù)量很少,可能也就每一個國企有一部電話,每一個機關(guān)單位有一個電話.這時候每個單位都會在電話旁放一本黃頁,這個黃頁里能查到所有的機關(guān)單位的電話.基本上查一下,交通局是什么電話,就可以打電話打過去,我覺得很像我們的命名服務(wù).
說到命名服務(wù)有很多方案,肯定有一種方案大家耳熟能詳,那就是 etcd.我們也用,但不僅僅用 etcd,還用了 kubernetes 項目中用到的 SkyDNS.
我加入到這些團隊的時候,不管是新浪、華為還是鏈家,我來的時候基礎(chǔ)設(shè)施已經(jīng)在用了.可能在已經(jīng)有基礎(chǔ)設(shè)施里面有很多環(huán)節(jié)沒有命名服務(wù),大家是直接 IP 端口連的.
這時候我給他們建議,我建議大家用命名服務(wù),開發(fā)工程師說你建議很好,我們會考慮,但是我現(xiàn)在開發(fā)的周期很緊張,我的工期很短,我的工作壓力很大,能不能你幫我做.
這個時候我就愁了,因為我是系統(tǒng)團隊,不能改應(yīng)用代碼嘛.如果用 etcd 做命名服務(wù)的話,需要應(yīng)用程序主動去聯(lián)命名服務(wù)獲取后端拓撲,再去連真正的服務(wù)器,這可能要涉及代碼改動.所以我想這么個轍,DNS 協(xié)議的命名服務(wù).
我在新浪也做過,但是這個基礎(chǔ)設(shè)施跟在新浪的時候已經(jīng)不一樣了.DNS 命名服務(wù)有什么優(yōu)勢呢?
如果你的代碼不想改,比如你連一個ip地址,你只需要把 IP 地址改成域名就可以了,域名就是我們互聯(lián)網(wǎng)最早也是最基礎(chǔ)的命名服務(wù).
域名作為命名服務(wù)的接口有一個問題,我們知道域名是有緩存的,緩存時間稱作 TTL.比如我設(shè) 30 秒,是為了不讓權(quán)威域名服務(wù)器過載,不能每一個域名都調(diào)用權(quán)威域名服務(wù)器,那權(quán)威域名服務(wù)器還不被壓垮了?
所以大家都緩存一下吧,30秒內(nèi)我不會變,直接用上次查詢結(jié)果.如果我這里有一個后端的資源故障了,我要把這個故障移除,我剛才設(shè)了 30 秒 TTL,30秒內(nèi)不會更新這個域名,30秒都可能繼續(xù)連到有故障的后端,這怎么辦?所以我們又引入了一個新的基礎(chǔ)設(shè)施,叫做 DNSMasq.
這個時候我們這個域名就可以在 TTL 之內(nèi)也完成這個變更.我們看最后這個架構(gòu),我們在一臺服務(wù)器上面安裝了一個 DNSMasq,如果應(yīng)用程序需要通過域名連接 MySQL,它會先查 DNSMasq 有沒有.有,給一個 IP 端口,如果沒有,DNSMasq 會查 SkyDNS.
如果這個時候有域名變更也能夠取到,但是 DNSMasq 有緩存怎么辦?我們看到后面我們有個 API 層,項目代碼叫馬其頓,我們每一個基礎(chǔ)設(shè)施都是 API 化的.
當你做 MySQL 監(jiān)控的時候,發(fā)現(xiàn)我一個從庫延遲太高,我要摘掉它.怎么摘呢?
調(diào)用馬其頓 API.馬其頓做兩件事,第一是更新 etcd,第二就是剛才我說的調(diào)我的 DNSMasq 的 API,這個時候如果業(yè)務(wù)再要連后面 MySQL 就會連 DNSMasq.DNSMaqs 這個緩存已經(jīng)被清除了,于是就會連 SkyDNS,就會給一個新的記錄,因為 etcd 里面記錄已經(jīng)被更新了.
最后還有個問題,后端服務(wù)拓撲不光有 IP 地址,還有可能是有端口號.這時候標準域名協(xié)議就搞不定了.這時候我們有兩個方法.
在鏈家應(yīng)用團隊覺得可接受,我們也樂得清閑,不用再改了.如果應(yīng)用團隊不接受怎么辦?就要去修改 Glibc 了.
最后部分是關(guān)于配置管理與自動化運維.我翻譯過了《奔跑吧 Ansible》這本書,所以我肯定是偏愛 Ansible.
現(xiàn)在在市面上我們能看到的主流的配管工具有這么多,左下角是一個燈泡,這個燈泡在淘寶上叫愛迪生燈泡,我用它替代自研系統(tǒng).
Puppet、Ansible、SaltStack 等配管工具各個有各自的特點,Ansible 是推模式,無 Agent,其他的是有 Agent 的.抽象層有薄有厚,在《奔跑吧 Ansible》一書中,作者的觀點是他喜歡 Ansible 的一點就是抽象層很薄,這點我也非常同意.
舉個例子,如果我這個團隊有上千臺服務(wù)器,都是 Linux,但是有多個發(fā)行版.Puppet 會傾向自己去適配不同發(fā)行版,形成抽象層.
Ansible 傾向于暴露這些差異,需要使用者去管理.或者使用者把發(fā)行版統(tǒng)一,或者使用者自己做一層抽象層來兼容不同發(fā)行版.
我認為 Ansible 的做法比較適合運維領(lǐng)域,但我覺得這幾個工具都蠻好的.我還是建議大家分析它的特點,如果你覺得這個東西用得順手,適合你的團隊你就用,Ansible 會有瓶頸,沒 Agent,又是 Python,內(nèi)存占用比較高.
另外 Ansible 所有的配置是靜態(tài)配置,如果我有些服務(wù)器變更,我希望它動態(tài)變更怎么辦?
在我們團隊初期,服務(wù)器規(guī)模還不大,直接使用 Ansible 落地很快.一方面不需要裝 Agent,所有服務(wù)器肯定都會啟動 SSH,Ansible 馬上可以落地.而且團隊歷史遺留一些腳本,用 Ansible 也很容易復(fù)用.
當你用 Ansible 遇到瓶頸的時候,團隊已經(jīng)已經(jīng)成長了,你就可以把它一定程度的改掉或者整個替換掉.
總結(jié)一下,就像我最開始時說的,我認為這個真實世界不是 0 與 1 兩面對立的,在 0 和 1 中間有無窮的灰度.到底這個灰度對于我們的公司或者對于您的公司在哪,需要結(jié)合團隊情況自己分析,自己去找.
對于新技術(shù),尤其是現(xiàn)在技術(shù)炒作問題這么嚴重,千萬不要迷信.某個技術(shù),解決什么問題?優(yōu)勢是什么?成本又是什么?對于我們團隊、環(huán)境適不適合?這些都是在使用前需要考慮好的問題.
一個系統(tǒng)不管怎么樣,在我們的應(yīng)用中,在我們的生產(chǎn)環(huán)境中真正運行里面才能發(fā)揮價值.
系統(tǒng)再好,不管是因為什么原因,只要在我們環(huán)境中運行不起來,那對我們公司沒有價值.最后就是不要忽略工程上和這些可以規(guī)范化、流程化上可以解決的問題.
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/4309.html