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