某宝千万级规模高性能、高并发的网络架构
架構(gòu)以及我理解中架構(gòu)的本質(zhì)
在開(kāi)始談我對(duì)架構(gòu)本質(zhì)的理解之前,先談?wù)剛€(gè)人見(jiàn)解,千萬(wàn)級(jí)規(guī)模的網(wǎng)站感覺(jué)數(shù)量級(jí)是非常大的,對(duì)這個(gè)數(shù)量級(jí)我們戰(zhàn)略上 要重 視 它 , 戰(zhàn)術(shù)上又 要 藐 視 它。先舉個(gè)例子感受一下千萬(wàn)級(jí)到底是什么數(shù)量級(jí)?現(xiàn)在很流行的優(yōu)步(Uber),從媒體公布的信息看,它每天接單量平均在百萬(wàn)左右, 假如每天有10個(gè)小時(shí)的服務(wù)時(shí)間,平均QPS只有30左右。對(duì)于一個(gè)后臺(tái)服務(wù)器,單機(jī)的平均QPS可以到達(dá)800-1000,單獨(dú)看寫(xiě)的業(yè)務(wù)量很簡(jiǎn)單 。為什么我們又不能說(shuō)輕視它?第一,我們看它的數(shù)據(jù)存儲(chǔ),每天一百萬(wàn)的話,一年數(shù)據(jù)量的規(guī)模是多少?其次,剛才說(shuō)的訂單量,每一個(gè)訂單要推送給附近的司機(jī)、司機(jī)要并發(fā)搶單,后面業(yè)務(wù)場(chǎng)景的訪問(wèn)量往往是前者的上百倍,輕松就超過(guò)上億級(jí)別了。
今天我想從架構(gòu)的本質(zhì)談起之后,希望大家理解在做一些建構(gòu)設(shè)計(jì)的時(shí)候,它的出發(fā)點(diǎn)以及它解決的問(wèn)題是什么。
架構(gòu),剛開(kāi)始的解釋是我從知乎上看到的。什么是架構(gòu)?有人講, 說(shuō)架構(gòu)并不是一 個(gè)很 懸 乎的 東西 , 實(shí)際 上就是一個(gè)架子 , 放一些 業(yè)務(wù) 和算法,跟我們的生活中的晾衣架很像。更抽象一點(diǎn),說(shuō)架構(gòu)其 實(shí) 是 對(duì) 我 們 重復(fù)性業(yè)務(wù) 的抽象和我 們 未來(lái) 業(yè)務(wù) 拓展的前瞻,強(qiáng)調(diào)過(guò)去的經(jīng)驗(yàn)和你對(duì)整個(gè)行業(yè)的預(yù)見(jiàn)。
我們要想做一個(gè)架構(gòu)的話需要哪些能力?我覺(jué)得最重要的是架構(gòu)師一個(gè)最重要的能力就是你要有 戰(zhàn) 略分解能力。這個(gè)怎么來(lái)看呢:
-
第一,你必須要有抽象的能力,抽象的能力最基本就是去重,去重在整個(gè)架構(gòu)中體現(xiàn)在方方面面,從定義一個(gè)函數(shù),到定義一個(gè)類,到提供的一個(gè)服務(wù),以及模板,背后都是要去重提高可復(fù)用率。
-
第二, 分類能力。做軟件需要做對(duì)象的解耦,要定義對(duì)象的屬性和方法,做分布式系統(tǒng)的時(shí)候要做服務(wù)的拆分和模塊化,要定義服務(wù)的接口和規(guī)范。
-
第三, 算法(性能),它的價(jià)值體現(xiàn)在提升系統(tǒng)的性能,所有性能的提升,最終都會(huì)落到CPU,內(nèi)存,IO和網(wǎng)絡(luò)這4大塊上。
-
第一個(gè)例子,在分布式系統(tǒng)我們會(huì)做 MySQL分 庫(kù) 分表,我們要從不同的庫(kù)和表中讀取數(shù)據(jù),這樣的抽象最直觀就是使用模板,因?yàn)榻^大多數(shù)SQL語(yǔ)義是相同的,除了路由到哪個(gè)庫(kù)哪個(gè)表,如果不使用Proxy中間件,模板就是性價(jià)比最高的方法。
-
第二看一下加速網(wǎng)絡(luò)的CDN,它是做速度方面的性能提升,剛才我們也提到從CPU、內(nèi)存、IO、網(wǎng)絡(luò)四個(gè)方面來(lái)考慮,CDN本質(zhì)上一個(gè)是做網(wǎng)絡(luò)智能調(diào)度優(yōu)化,另一個(gè)是多級(jí)緩存優(yōu)化。
-
第三個(gè)看一下服務(wù)化,剛才已經(jīng)提到了,各個(gè)大網(wǎng)站轉(zhuǎn)型過(guò)程中一定會(huì)做服務(wù)化,其實(shí)它就是做抽象和做服務(wù)的拆分。第四個(gè)看一下消息隊(duì)列,本質(zhì)上還是做分類,只不過(guò)不是兩個(gè)邊際清晰的類,而是把兩個(gè)邊際不清晰的子系統(tǒng)通過(guò)隊(duì)列解構(gòu)并且異步化。
新浪微博整體架構(gòu)是什么樣的
接下我們看一下微博整體架構(gòu),到一定量級(jí)的系統(tǒng)整個(gè)架構(gòu)都會(huì)變成三層,客戶端包括WEB、安卓和IOS,這里就不說(shuō)了。
接著還都會(huì)有一個(gè)接口層, 有三個(gè)主要作用:
-
第一個(gè)作用,要做 安全隔離,因?yàn)榍岸斯?jié)點(diǎn)都是直接和用戶交互,需要防范各種惡意攻擊;
-
第二個(gè)還充當(dāng)著一個(gè) 流量控制的作用,大家知道,在2014年春節(jié)的時(shí)候,微信紅包,每分鐘8億多次的請(qǐng)求,其實(shí)真正到它后臺(tái)的請(qǐng)求量,只有十萬(wàn)左右的數(shù)量級(jí)(這里的數(shù)據(jù)可能不準(zhǔn)),剩余的流量在接口層就被擋住了;
-
第三,我們看對(duì) PC 端和移 動(dòng) 端的需求不一樣的,所以我們可以進(jìn)行拆分。接口層之后是后臺(tái),可以看到微博后臺(tái)有三大塊: 一個(gè)是 平臺(tái)服 務(wù),
-
第二, 搜索,
-
第三, 大數(shù)據(jù)。
-
到了后臺(tái)的各種服務(wù)其實(shí)都是處理的數(shù)據(jù)。 像平臺(tái)的業(yè)務(wù)部門(mén),做的就是 數(shù)據(jù)存儲(chǔ)和讀 取,對(duì)搜索來(lái)說(shuō)做的是 數(shù)據(jù)的 檢 索,對(duì)大數(shù)據(jù)來(lái)說(shuō)是做的數(shù)據(jù)的 挖掘。微博其實(shí)和淘寶是很類似
從 LAMP 的架構(gòu)到面向服 務(wù) 的架構(gòu),有幾個(gè)地方是非常難的,首先不可能在第一代基礎(chǔ)上通過(guò)簡(jiǎn)單的修修補(bǔ)補(bǔ)滿足用戶量快速增長(zhǎng)的,同時(shí)線上業(yè)務(wù)又不能停, 這是我們常說(shuō)的 在 飛 機(jī)上 換 引擎的 問(wèn)題。前兩天我有一個(gè)朋友問(wèn)我,說(shuō)他在內(nèi)部推行服務(wù)化的時(shí)候,把一個(gè)模塊服務(wù)化做完了,其他部門(mén)就是不接。我建議在做服務(wù)化的時(shí)候,首先更多是偏向業(yè)務(wù)的梳理,同時(shí)要找準(zhǔn)一個(gè)很好的切入點(diǎn),既有架構(gòu)和服務(wù)化上的提升,業(yè)務(wù)方也要有收益,比如提升性能或者降低維護(hù)成本同時(shí)升級(jí)過(guò)程要平滑,建議開(kāi)始從原子化服務(wù)切入,比如基礎(chǔ)的用戶服務(wù), 基礎(chǔ)的短消息服務(wù),基礎(chǔ)的推送服務(wù)。 第二,就是可 以做無(wú)狀 態(tài) 服 務(wù),后面會(huì)詳細(xì)講,還有數(shù)據(jù)量大了后需要做數(shù)據(jù)Sharding,后面會(huì)將。 第三代 架構(gòu) 要解決的 問(wèn)題,就是用戶量和業(yè)務(wù)趨于穩(wěn)步增加(相對(duì)爆發(fā)期的指數(shù)級(jí)增長(zhǎng)),更多考慮技術(shù)框架的穩(wěn)定性, 提升系統(tǒng)整體的性能,降低成本,還有對(duì)整個(gè)系統(tǒng)監(jiān)控的完善和升級(jí)。
大型網(wǎng)站的系統(tǒng)架構(gòu)是如何演變的
我們通過(guò)通過(guò)數(shù)據(jù)看一下它的挑戰(zhàn),PV是在10億級(jí)別,QPS在百萬(wàn),數(shù)據(jù)量在千億級(jí)別。我們可用性,就是SLA要求4個(gè)9,接口響應(yīng)最多不能超過(guò)150毫秒,線上所有的故障必須得在5分鐘內(nèi)解決完。如果說(shuō)5分鐘沒(méi)處理呢?那會(huì)影響你年終的績(jī)效考核。2015年微博DAU已經(jīng)過(guò)億。我們系統(tǒng)有上百個(gè)微服務(wù),每周會(huì)有兩次的常規(guī)上線和不限次數(shù)的緊急上線。我們的挑戰(zhàn)都一樣,就是數(shù)據(jù)量,bigger and bigger,用戶體驗(yàn)是faster and faster,業(yè)務(wù)是more and more。互聯(lián)網(wǎng)業(yè)務(wù)更多是產(chǎn)品體驗(yàn)驅(qū)動(dòng), 技 術(shù) 在 產(chǎn) 品 體驗(yàn)上最有效的貢獻(xiàn) , 就是你的性能 越來(lái)越好 。 每次降低加載一個(gè)頁(yè)面的時(shí)間,都可以間接的降低這個(gè)頁(yè)面上用戶的流失率。微博的技術(shù)挑戰(zhàn)和正交分解法解析架構(gòu)
下面看一下 第三代的 架構(gòu) 圖 以及 我 們 怎么用正交分解法 闡 述。 我們可以看到我們從兩個(gè)維度,橫軸和縱軸可以看到。 一個(gè) 維 度 是 水平的 分層 拆分,第二從垂直的維度會(huì)做拆分。水平的維度從接口層、到服務(wù)層到數(shù)據(jù)存儲(chǔ)層。垂直怎么拆分,會(huì)用業(yè)務(wù)架構(gòu)、技術(shù)架構(gòu)、監(jiān)控平臺(tái)、服務(wù)治理等等來(lái)處理。我相信到第二代的時(shí)候很多架構(gòu)已
經(jīng)有了業(yè)務(wù)架構(gòu)和技術(shù)架構(gòu)的拆分。我們看一下, 接口層有feed、用戶關(guān)系、通訊接口;服務(wù)層,SOA里有基層服務(wù)、原子服務(wù)和組合服務(wù),在微博我們只有原子服務(wù)和組合服務(wù)。原子服務(wù)不依賴于任何其他服務(wù),組合服務(wù)由幾個(gè)原子服務(wù)和自己的業(yè)務(wù)邏輯構(gòu)建而成 ,資源層負(fù)責(zé)海量數(shù)據(jù)的存儲(chǔ)(后面例子會(huì)詳細(xì)講)。技 術(shù)框架解決 獨(dú)立于 業(yè)務(wù) 的海量高并發(fā)場(chǎng)景下的技術(shù)難題,由眾多的技術(shù)組件共同構(gòu)建而成 。在接口層,微博使用JERSY框架,幫助你做參數(shù)的解析,參數(shù)的驗(yàn)證,序列化和反序列化;資源層,主要是緩存、DB相關(guān)的各類組件,比如Cache組件和對(duì)象庫(kù)組件。監(jiān) 控平臺(tái)和服 務(wù) 治理 , 完成系統(tǒng)服務(wù)的像素級(jí)監(jiān)控,對(duì)分布式系統(tǒng)做提前診斷、預(yù)警以及治理。包含了SLA規(guī)則的制定、服務(wù)監(jiān)控、服務(wù)調(diào)用鏈監(jiān)控、流量監(jiān)控、錯(cuò)誤異常監(jiān)控、線上灰度發(fā)布上線系統(tǒng)、線上擴(kuò)容縮容調(diào)度系統(tǒng)等。
下面我們講一下常見(jiàn)的設(shè)計(jì)原則。-
第一個(gè),首先是系統(tǒng)架構(gòu)三個(gè)利器: 一個(gè), 我 們 RPC 服 務(wù)組 件 (這里不講了),
-
第二個(gè),我們 消息中 間 件 。消息中間件起的作用:可以把兩個(gè)模塊之間的交互異步化,其次可以把不均勻請(qǐng)求流量輸出為勻速的輸出流量,所以說(shuō)消息中間件 異步化 解耦 和流量削峰的利器。
-
第三個(gè)是配置管理,它是 代碼級(jí)灰度發(fā)布以及 保障系統(tǒng)降級(jí)的利器。 第二個(gè) , 無(wú)狀態(tài) , 接口 層 最重要的就是無(wú)狀 態(tài)。我們?cè)陔娚叹W(wǎng)站購(gòu)物,在這個(gè)過(guò)程中很多情況下是有狀態(tài)的,比如我瀏覽了哪些商品,為什么大家又常說(shuō)接口層是無(wú)狀態(tài)的,其實(shí)我們把狀態(tài)從接口層剝離到了數(shù)據(jù)層。像用戶在電商網(wǎng)站購(gòu)物,選了幾件商品,到了哪一步,接口無(wú)狀態(tài)后,狀態(tài)要么放在緩存中,要么放在數(shù)據(jù)庫(kù)中, 其 實(shí) 它并不是沒(méi)有狀 態(tài) , 只是在 這 個(gè) 過(guò) 程中我 們 要把一些有狀 態(tài) 的 東 西抽離出來(lái) 到了數(shù)據(jù)層。
-
第三個(gè), 數(shù)據(jù) 層 比服 務(wù)層 更需要 設(shè)計(jì),這是一條非常重要的經(jīng)驗(yàn)。對(duì)于服務(wù)層來(lái)說(shuō),可以拿PHP寫(xiě),明天你可以拿JAVA來(lái)寫(xiě),但是如果你的數(shù)據(jù)結(jié)構(gòu)開(kāi)始設(shè)計(jì)不合理,將來(lái)數(shù)據(jù)結(jié)構(gòu)的改變會(huì)花費(fèi)你數(shù)倍的代價(jià),老的數(shù)據(jù)格式向新的數(shù)據(jù)格式遷移會(huì)讓你痛不欲生,既有工作量上的,又有數(shù)據(jù)遷移跨越的時(shí)間周期,有一些甚至需要半年以上。
-
第四,物理結(jié)構(gòu)與邏輯結(jié)構(gòu)的映射,上一張圖看到兩個(gè)維度切成十二個(gè)區(qū)間,每個(gè)區(qū)間代表一個(gè)技術(shù)領(lǐng)域,這個(gè)可以看做我們的邏輯結(jié)構(gòu)。另外,不論后臺(tái)還是應(yīng)用層的開(kāi)發(fā)團(tuán)隊(duì),一般都會(huì)分幾個(gè)垂直的業(yè)務(wù)組加上一個(gè)基礎(chǔ)技術(shù)架構(gòu)組,這就是從物理組織架構(gòu)到邏輯的技術(shù)架構(gòu)的完美的映射,精細(xì)化團(tuán)隊(duì)分工,有利于提高溝通協(xié)作的效率 。
-
第五, www .sanhao.com 的訪問(wèn)過(guò)程,我們這個(gè)架構(gòu)圖里沒(méi)有涉及到的,舉個(gè)例子,比如當(dāng)你在瀏覽器輸入www.sanhao網(wǎng)址的時(shí)候,這個(gè)請(qǐng)求在接口層之前發(fā)生了什么?首先會(huì)查看你本機(jī)DNS以及DNS服務(wù),查找域名對(duì)應(yīng)的IP地址,然后發(fā)送HTTP請(qǐng)求過(guò)去。這個(gè)請(qǐng)求首先會(huì)到前端的VIP地址(公網(wǎng)服務(wù)IP地址),VIP之后還要經(jīng)過(guò)負(fù)載均衡器(Nginx服務(wù)器),之后才到你的應(yīng)用接口層。在接口層之前發(fā)生了這么多事,可能有用戶報(bào)一個(gè)問(wèn)題的時(shí)候,你通過(guò)在接口層查日志根本發(fā)現(xiàn)不了問(wèn)題,原因就是問(wèn)題可能發(fā)生在到達(dá)接口層之前了。
-
第六,我們說(shuō)分布式系統(tǒng),它最終的瓶頸會(huì)落在哪里呢?前端時(shí)間有一個(gè)網(wǎng)友跟我討論的時(shí)候,說(shuō)他們的系統(tǒng)遇到了一個(gè)瓶頸, 查遍了CPU,內(nèi)存,網(wǎng)絡(luò),存儲(chǔ),都沒(méi)有問(wèn)題。我說(shuō)你再查一遍,因?yàn)樽罱K你不論用上千臺(tái)服務(wù)器還是上萬(wàn)臺(tái)服務(wù)器,最終系統(tǒng)出瓶頸的一定會(huì)落在某一臺(tái)機(jī)(可能是葉子節(jié)點(diǎn)也可能是核心的節(jié)點(diǎn)),一定落在CPU、內(nèi)存、存儲(chǔ)和網(wǎng)絡(luò)上,最后查出來(lái)問(wèn)題出在一臺(tái)服務(wù)器的網(wǎng)卡帶寬上。
-
針對(duì)上面的技術(shù)我特意整理了一下,有很多技術(shù)不是靠幾句話能講清楚,所以干脆找朋友錄制了一些視頻,很多問(wèn)題其實(shí)很簡(jiǎn)單,但是背后的思考和邏輯不簡(jiǎn)單,要做到知其然還要知其所以然。如果想學(xué)習(xí)Java工程化、高性能及分布式、深入淺出。微服務(wù)、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java進(jìn)階群:694549689,群里有阿里大牛直播講解技術(shù),以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費(fèi)分享給大家。
微博多級(jí)雙機(jī)房緩存架構(gòu)
接下來(lái)我們看一下微博的Feed多級(jí)緩存。我們做業(yè)務(wù)的時(shí)候,經(jīng)常很少做業(yè)務(wù)分析,技術(shù)大會(huì)上的分享又都偏向技術(shù)架構(gòu)。其實(shí)大家更多的日常工作是需要花費(fèi)更多時(shí)間在業(yè)務(wù)優(yōu)化上。這張圖是統(tǒng)計(jì)微博的信息流前幾頁(yè)的訪問(wèn)比例,像前三頁(yè)占了97%,在做緩存設(shè)計(jì)的時(shí)候,我們最多只存最近的M條數(shù)據(jù)。 這里強(qiáng)調(diào)的就是做系統(tǒng)設(shè)計(jì) 要基于用 戶 的 場(chǎng) 景 , 越細(xì)致越好 。舉了一個(gè)例子,大家都會(huì)用電商,電商在雙十一會(huì)做全國(guó)范圍內(nèi)的活動(dòng),他們做設(shè)計(jì)的時(shí)候也會(huì)考慮場(chǎng)景的,一個(gè)就是購(gòu)物車(chē),我曾經(jīng)跟相關(guān)開(kāi)發(fā)討論過(guò),購(gòu)物車(chē)是在雙十一之前用戶的訪問(wèn)量非常大,就是不停地往里加商品。在真正到雙十一那天他不會(huì)往購(gòu)物車(chē)加?xùn)|西了,但是他會(huì)頻繁的瀏覽購(gòu)物車(chē)。針對(duì)這個(gè)場(chǎng)景,活動(dòng)之前重點(diǎn)設(shè)計(jì)優(yōu)化購(gòu)物車(chē)的寫(xiě)場(chǎng)景, 活動(dòng)開(kāi)始后優(yōu)化購(gòu)物車(chē)的讀場(chǎng)景。
你看到的微博是由哪些部分聚合而成的呢?最右邊的是Feed,就是微博所有關(guān)注的人,他們的微博所組成的。微博我們會(huì)按照時(shí)間順序把所有關(guān)注人的順序做一個(gè)排序。隨著業(yè)務(wù)的發(fā)展,除了跟時(shí)間序相關(guān)的微博還有非時(shí)間序的微博,就是會(huì)有廣告的要求,增加一些廣告,還有粉絲頭條,就是拿錢(qián)買(mǎi)的,熱門(mén)微博,都會(huì)插在其中。分發(fā)控制,就是說(shuō)和一些推薦相關(guān)的,我推薦一些相關(guān)的好友的微博,我推薦一些你可能沒(méi)有讀過(guò)的微博,我推薦一些其他類型的微博。 當(dāng)然對(duì)非時(shí)序的微博和分發(fā)控制微博,實(shí)際會(huì)起多個(gè)并行的程序來(lái)讀取,最后同步做統(tǒng)一的聚合。這里稍微分享一下, 從SNS社交領(lǐng)域來(lái)看,國(guó)內(nèi)現(xiàn)在做的比較好的三個(gè)信息流:微博是基于弱關(guān)系的媒體信息流 ;
朋友圈是基于 強(qiáng) 關(guān)系的信息流 ;
另外一個(gè)做的比較好的就是今日頭條, 它并不是基于關(guān)系來(lái)構(gòu)建信息流 , 而是基于興趣和相關(guān)性的個(gè)性化推薦信息流 。
信息流的聚合,體現(xiàn)在很多很多的產(chǎn)品之中,除了SNS,電商里也有信息流的聚合的影子。比如搜索一個(gè)商品后出來(lái)的列表頁(yè),它的信息流基本由幾部分組成:第一,打廣告的;第二個(gè),做一些推薦,熱門(mén)的商品,其次,才是關(guān)鍵字相關(guān)的搜索結(jié)果。 信息流 開(kāi)始的時(shí)候很簡(jiǎn)單,但是到后期會(huì)發(fā)現(xiàn) ,你的這個(gè)流如何做控制分發(fā),非常復(fù)雜,微博在最近一兩年一直在做這樣 的工作。
剛才我們是從業(yè)務(wù)上分析,那么技術(shù)上怎么解決高并發(fā),高性能的問(wèn)題?微博訪問(wèn)量很大的時(shí)候,底層存儲(chǔ)是用MySQL數(shù)據(jù)庫(kù),當(dāng)然也會(huì)有其他的。對(duì)于查詢請(qǐng)求量大的時(shí)候,大家知道一定有緩存,可以復(fù)用可重用的計(jì)算結(jié)果。可以看到,發(fā)一條微博,我有很多粉絲,他們都會(huì)來(lái)看我發(fā)的內(nèi)容,所以 微博是最適合使用 緩 存 的系統(tǒng),微博的讀寫(xiě)比例基本在幾十比一。微博使用了 雙 層緩 存,上面是L1,每個(gè)L1上都是一組(包含4-6臺(tái)機(jī)器),左邊的框相當(dāng)于一個(gè)機(jī)房,右邊又是一個(gè)機(jī)房。在這個(gè)系統(tǒng)中L1緩存所起的作用是什么? 首先,L1 緩 存增加整個(gè)系 統(tǒng) 的 QPS, 其次 以低成本靈活擴(kuò)容的方式 增加 系統(tǒng) 的 帶寬 。想象一個(gè)極端場(chǎng)景,只有一篇博文,但是它的訪問(wèn)量無(wú)限增長(zhǎng),其實(shí)我們不需要影響L2緩存,因?yàn)樗膬?nèi)容存儲(chǔ)的量小,但它就是訪問(wèn)量大。這種場(chǎng)景下,你就需要使用L1來(lái)擴(kuò)容提升QPS和帶寬瓶頸。另外一個(gè)場(chǎng)景,就是L2級(jí)緩存發(fā)生作用,比如我有一千萬(wàn)個(gè)用戶,去訪問(wèn)的是一百萬(wàn)個(gè)用戶的微博 ,這個(gè)時(shí)候,他不只是說(shuō)你的吞吐量和訪問(wèn)帶寬,就是你要緩存的博文的內(nèi)容也很多了,這個(gè)時(shí)候你要考慮緩存的容量, 第二 級(jí)緩 存更多的是從容量上來(lái) 規(guī)劃,保證請(qǐng)求以較小的比例 穿透到 后端的 數(shù)據(jù) 庫(kù) 中 ,根據(jù)你的用戶模型你可以估出來(lái),到底有百分之多少的請(qǐng)求不能穿透到DB, 評(píng)估這個(gè)容量之后,才能更好的評(píng)估DB需要多少庫(kù),需要承擔(dān)多大的訪問(wèn)的壓力。另外,我們看雙機(jī)房的話,左邊一個(gè),右邊一個(gè)。 兩個(gè)機(jī)房是互 為 主 備 , 或者互 為熱備 。如果兩個(gè)用戶在不同地域,他們?cè)L問(wèn)兩個(gè)不同機(jī)房的時(shí)候,假設(shè)用戶從IDC1過(guò)來(lái),因?yàn)榫徒?#xff0c;他會(huì)訪問(wèn)L1,沒(méi)有的話才會(huì)跑到Master,當(dāng)在IDC1沒(méi)找到的時(shí)候才會(huì)跑到IDC2來(lái)找。同時(shí)有用戶從IDC2訪問(wèn),也會(huì)有請(qǐng)求從L1和Master返回或者到IDC1去查找。 IDC1 和 IDC2 ,兩個(gè)機(jī)房都有全量的用戶數(shù)據(jù),同時(shí)在線提供服務(wù),但是緩存查詢又遵循最近訪問(wèn)原理。 還有哪些多級(jí)緩存的例子呢?CDN是典型的多級(jí)緩存。CDN在國(guó)內(nèi)各個(gè)地區(qū)做了很多節(jié)點(diǎn),比如在杭州市部署一個(gè)節(jié)點(diǎn)時(shí),在機(jī)房里肯定不止一臺(tái)機(jī)器,那么對(duì)于一個(gè)地區(qū)來(lái)說(shuō),只有幾臺(tái)服務(wù)器到源站回源,其他節(jié)點(diǎn)都到這幾臺(tái)服務(wù)器回源即可,這么看CDN至少也有兩級(jí)。Local Cache+ 分布式 緩 存,這也是常見(jiàn)的一種策略。有一種場(chǎng)景,分布式緩存并不適用, 比如 單 點(diǎn) 資 源 的爆發(fā)性峰值流量,這個(gè)時(shí)候使用Local Cache + 分布式緩存,Local Cache 在 應(yīng)用 服 務(wù) 器 上用很小的 內(nèi)存資源 擋住少量的 極端峰值流量,長(zhǎng)尾的流量仍然訪問(wèn)分布式緩存,這樣的Hybrid緩存架構(gòu)通過(guò)復(fù)用眾多的應(yīng)用服務(wù)器節(jié)點(diǎn),降低了系統(tǒng)的整體成本。我們來(lái)看一下 Feed 的存 儲(chǔ) 架構(gòu),微博的博文主要存在MySQL中。首先來(lái)看內(nèi)容表,這個(gè)比較簡(jiǎn)單,每條內(nèi)容一個(gè)索引,每天建一張表,其次看索引表,一共建了兩級(jí)索引。首先想象一下用戶場(chǎng)景,大部分用戶刷微博的時(shí)候,看的是他關(guān)注所有人的微博,然后按時(shí)間來(lái)排序。仔細(xì)分析發(fā)現(xiàn)在這個(gè)場(chǎng)景下, 跟一個(gè)用戶的自己的相關(guān)性很小了。所以在一級(jí)索引的時(shí)候會(huì)先根據(jù)關(guān)注的用戶,取他們的前條微博ID,然后聚合排序。我們?cè)谧龉?#xff08;分庫(kù)分表)的時(shí)候,同時(shí)考慮了按照UID哈希和按照時(shí)間維度。很業(yè)務(wù)和時(shí)間相關(guān)性很高的,今天的熱點(diǎn)新聞,明天就沒(méi)熱度了,數(shù)據(jù)的冷熱非常明顯,這種場(chǎng)景就需要按照時(shí)間維度做分表,首先冷熱數(shù)據(jù)做了分離(可以對(duì)冷熱數(shù)據(jù)采用不同的存儲(chǔ)方案來(lái)降低成本),其次, 很容止控制我數(shù)據(jù)庫(kù)表的爆炸。像微博如果只按照用戶維度區(qū)分,那么這個(gè)用戶所有數(shù)據(jù)都在一張表里,這張表就是無(wú)限增長(zhǎng)的,時(shí)間長(zhǎng)了查詢會(huì)越來(lái)越慢。二級(jí)索引,是我們里面一個(gè)比較特殊的場(chǎng)景,就是我要快速找到這個(gè)人所要發(fā)布的某一時(shí)段的微博時(shí),通過(guò)二級(jí)索引快速定位。
分布式服務(wù)追蹤系統(tǒng)
分布式追蹤服務(wù)系統(tǒng),當(dāng)系統(tǒng)到千萬(wàn)級(jí)以后的時(shí)候,越來(lái)越龐雜,所解決的問(wèn)題更偏向穩(wěn)定性,性能和監(jiān)控。剛才說(shuō)用戶只要有一個(gè)請(qǐng)求過(guò)來(lái),你可以依賴你的服務(wù)RPC1、RPC2,你會(huì)發(fā)現(xiàn)RPC2又依賴RPC3、RPC4。分布式服務(wù)的時(shí)候一個(gè)痛點(diǎn),就是說(shuō)一個(gè)請(qǐng)求從用戶過(guò)來(lái)之后,在后臺(tái)不同的機(jī)器之間不停的調(diào)用并返回。
當(dāng)你發(fā)現(xiàn)一個(gè)問(wèn)題的時(shí)候,這些日志落在不同的機(jī)器上,你也不知道問(wèn)題到底出在哪兒,各個(gè)服務(wù)之間互相隔離,互相之間沒(méi)有建立關(guān)聯(lián)。所以導(dǎo)致排查問(wèn)題基本沒(méi)有任何手段,就是出了問(wèn)題沒(méi)法兒解決。
我們要解決的問(wèn)題,我們剛才說(shuō)日志互相隔離,我們就要把它建立聯(lián)系。建立聯(lián)系我們就有一個(gè)請(qǐng)求ID,然后結(jié)合RPC框架, 服務(wù)治理功能。假設(shè)請(qǐng)求從客戶端過(guò)來(lái),其中包含一個(gè)ID 101,到服務(wù)A時(shí)仍然帶有ID 101,然后調(diào)用RPC1的時(shí)候也會(huì)標(biāo)識(shí)這是101 ,所以需要 一個(gè)唯一的 請(qǐng)求 ID 標(biāo)識(shí) 遞歸迭代的傳遞到每一個(gè) 相關(guān) 節(jié)點(diǎn)。第二個(gè),你做的時(shí)候,你不能說(shuō)每個(gè)地方都加,對(duì)業(yè)務(wù)系統(tǒng)來(lái)說(shuō)需要一個(gè)框架來(lái)完成這個(gè)工作, 這 個(gè)框架要 對(duì)業(yè)務(wù) 系 統(tǒng) 是最低侵入原 則 , 用 JAVA 的 話 就可以用 AOP,要做到零侵入的原則,就是對(duì)所有相關(guān)的中間件打點(diǎn),從接口層組件(HTTP Client、HTTP Server)至到服務(wù)層組件(RPC Client、RPC Server),還有數(shù)據(jù)訪問(wèn)中間件的,這樣業(yè)務(wù)系統(tǒng)只需要少量的配置信息就可以實(shí)現(xiàn)全鏈路監(jiān)控 。為什么要用日志?服務(wù)化以后,每個(gè)服務(wù)可以用不同的開(kāi)發(fā)語(yǔ)言, 考慮多種開(kāi)發(fā)語(yǔ)言的兼容性 , 內(nèi)部定 義標(biāo) 準(zhǔn)化的日志 是唯一且有效的辦法。
最后,如何構(gòu)建基于GPS導(dǎo)航的路況監(jiān)控?我們剛才講分布式服務(wù)追蹤。分布式服務(wù)追蹤能解決的問(wèn)題, 如果 單一用 戶發(fā)現(xiàn)問(wèn)題 后 , 可以通 過(guò)請(qǐng) 求 ID 快速找到 發(fā) 生 問(wèn)題 的 節(jié) 點(diǎn)在什么,但是并沒(méi)有解決如何發(fā)現(xiàn)問(wèn)題。我們看現(xiàn)實(shí)中比較容易理解的道路監(jiān)控,每輛車(chē)有GPS定位,我想看北京哪兒擁堵的時(shí)候,怎么做? 第一個(gè) , 你肯定要知道每個(gè) 車(chē) 在什么位置,它走到哪兒了。其實(shí)可以說(shuō)每個(gè)車(chē)上只要有一個(gè)標(biāo)識(shí),加上每一次流動(dòng)的信息,就可以看到每個(gè)車(chē)流的位置和方向。 其次如何做 監(jiān) 控和 報(bào) 警,我們?cè)趺茨芰私獾缆返牧髁繝顩r和負(fù)載,并及時(shí)報(bào)警。我們要定義這條街道多寬多高,單位時(shí)間可以通行多少輛車(chē),這就是道路的容量。有了道路容量,再有道路的實(shí)時(shí)流量,我們就可以基于實(shí)習(xí)路況做預(yù)警?對(duì)應(yīng)于 分布式系 統(tǒng) 的話如何構(gòu)建? 第一 , 你要 定義 每個(gè)服 務(wù)節(jié) 點(diǎn)它的 SLA A 是多少 ?SLA可以從系統(tǒng)的CPU占用率、內(nèi)存占用率、磁盤(pán)占用率、QPS請(qǐng)求數(shù)等來(lái)定義,相當(dāng)于定義系統(tǒng)的容量。 第二個(gè) , 統(tǒng)計(jì) 線 上 動(dòng)態(tài) 的流量,你要知道服務(wù)的平均QPS、最低QPS和最大QPS,有了流量和容量,就可以對(duì)系統(tǒng)做全面的監(jiān)控和報(bào)警。
剛才講的是理論,實(shí)際情況肯定比這個(gè)復(fù)雜。微博在春節(jié)的時(shí)候做許多活動(dòng),必須保障系統(tǒng)穩(wěn)定,理論上你只要定義容量和流量就可以。但實(shí)際遠(yuǎn)遠(yuǎn)不行,為什么?有技術(shù)的因素,有人為的因素,因?yàn)椴煌拈_(kāi)發(fā)定義的流量和容量指標(biāo)有主觀性,很難全局量化標(biāo)準(zhǔn),所以真正流量來(lái)了以后,你預(yù)先評(píng)估的系統(tǒng)瓶頸往往不正確。實(shí)際中我們?cè)诖汗?jié)前主要采取了三個(gè)措施:
第一,最簡(jiǎn)單的就是有降 級(jí) 的 預(yù) 案,流量超過(guò)系統(tǒng)容量后,先把哪些功能砍掉,需要有明確的優(yōu)先級(jí) 。
第二個(gè), 線上全鏈路壓測(cè),就是把現(xiàn)在的流量放大到我們平常流量的五倍甚至十倍(比如下線一半的服務(wù)器,縮容而不是擴(kuò)容),看看系統(tǒng)瓶頸最先發(fā)生在哪里。我們之前有一些例子,推測(cè)系統(tǒng)數(shù)據(jù)庫(kù)會(huì)先出現(xiàn)瓶頸,但是實(shí)測(cè)發(fā)現(xiàn)是前端的程序先遇到瓶頸。
第三,搭建在線 Docker 集群 , 所有業(yè)務(wù)共享備用的 Docker集群資源,這樣可以極大的避免每個(gè)業(yè)務(wù)都預(yù)留資源,但是實(shí)際上流量沒(méi)有增長(zhǎng)造成的浪費(fèi)。
總結(jié)
接下來(lái)說(shuō)的是如何不停的學(xué)習(xí)和提升,這里以Java語(yǔ)言為例,首先, 一定要 理解 JAVA;第二步,JAVA完了以后,一定要 理 解 JVM;其次,還要 理解 操作系統(tǒng);再次還是要了解一下 Design Pattern,這將告訴你怎么把過(guò)去的經(jīng)驗(yàn)抽象沉淀供將來(lái)借鑒;還要學(xué)習(xí) TCP/IP、 分布式系 統(tǒng)、數(shù)據(jù)結(jié)構(gòu)和算法。最后就是我想說(shuō)的就是今天我所說(shuō)的可能一切都是錯(cuò)的!大家通過(guò)不停的學(xué)習(xí)、練習(xí)和總結(jié), 形成自己的一套架構(gòu)設(shè)計(jì)原則和方法,如果對(duì)你有幫助請(qǐng)動(dòng)動(dòng)小手關(guān)注下吧!謝謝大家。
總結(jié)
以上是生活随笔為你收集整理的某宝千万级规模高性能、高并发的网络架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 通过Anaconda在Ubuntu16.
- 下一篇: C#读取AD域用户信息