揭秘:千里送信為何能到瞬時到達
一. 引言
兩百年前,人們想給遠方的人傳個話,需要十天半個月?;ヂ?lián)網(wǎng)時代,我們只要按下回車,信息秒達,結(jié)果秒出。
那你可曾想過,信息傳送為什么可以這么快?
你可能會說,信息以光速級別傳輸,不論是光纖還是4G/5G用的電磁波,那當(dāng)然快了!
可是,僅僅是光速嗎?那為什么原本掃碼秒出結(jié)果的核酸系統(tǒng),高峰時一個人可能卡十幾分鐘;為什么火車票搶著搶著系統(tǒng)就崩了?
直覺告訴我們,因為用戶多了,而系統(tǒng)應(yīng)用的承載能力有限。因此,一個成熟的互聯(lián)網(wǎng)應(yīng)用面對海量用戶,是練就了十八般武藝(優(yōu)化策略)來巧妙應(yīng)對。
其中有些策略的重要性堪比光速,有些也能在日常生活經(jīng)驗中找到影子。
二. 整體流程
在介紹優(yōu)化策略前,有必要對網(wǎng)絡(luò)信號的請求流程有個整體印象:
圖1為通過APP控制攝像頭“轉(zhuǎn)頭”的流程示意圖,大致勾勒了一個信號(網(wǎng)絡(luò)請求)的典型旅程。
圖1 網(wǎng)絡(luò)傳輸流程
簡單來說,一個網(wǎng)絡(luò)請求的耗時主要來自網(wǎng)絡(luò)傳輸、數(shù)據(jù)中心處理。
具體來說,APP上點擊按鈕-->“轉(zhuǎn)頭”指令等信息,會被轉(zhuǎn)化為0和1的二進制序列-->手機通過內(nèi)置天線發(fā)射電磁波-->基站-->運營商機房-->通過光纖傳送到千里之外的數(shù)據(jù)中心(圖1)。
數(shù)據(jù)中心存放著系統(tǒng)的云端平臺。平臺處理后,將“轉(zhuǎn)頭”指令發(fā)出-->光纖傳輸-->到家中路由器,通過無線信號發(fā)給攝像頭-->攝像頭接收信號并轉(zhuǎn)為0和1的序列-->還原為攝像頭軟件可理解的指令-->操控電機進行旋轉(zhuǎn)。
圖2 數(shù)據(jù)中心的平臺組成
一眨眼的功夫,就完成了這么多環(huán)節(jié)(實際過程遠比此復(fù)雜)。
從中可見,光速解決的僅僅是長距離傳輸?shù)暮臅r問題,如果哪個節(jié)點卡住,效率直線下降,就如同短板木桶,盛水能力將大打折扣。
優(yōu)化策略有很多,本文將介紹其中最為關(guān)鍵的4種:索引,緩存,負(fù)載均衡,并發(fā)。
三. 優(yōu)化策略
3.1 索引
索引可以說是非常偉大的發(fā)明了。用一句話說就是:事先分類排序,到時找起來方便。比如查字典,咱都是按索引查,如果沒索引,從頭找到尾可要累死個人。
數(shù)據(jù)中心里的數(shù)據(jù)庫,幾千萬條數(shù)據(jù)也是司空見慣了。以mysql為例,用的索引方案一般是B+樹,找一條數(shù)據(jù)1~4次即可找到,耗時約幾十毫秒。而如果沒有索引則需要遍歷,可能十幾秒才能找到,差距達數(shù)百倍。
相信大家用過windows自帶的文件搜索,慢得令人無語;如果用everything等軟件則瞬間出結(jié)果,正體現(xiàn)了索引的強大威力。(注:windows不是完全不用索引,是沒用合適的索引)
當(dāng)然索引并非全無代價:占存儲空間;索引樹時常變化,引起性能消耗。雖有代價,但非常值得,正所謂磨刀不誤砍柴工嘛。
計算機的世界,索引無處不在,此處囿于篇幅不展開詳述,若感興趣詳見文末表格。正是每個環(huán)節(jié)盡可能地用上索引,用巧妙的“速達”取代笨拙的“遍歷”,才讓一次請求盡可能地快。
3.2 緩存
為什么廚房的鹽、味精要從調(diào)料盒里舀取,而不從包裝袋里舀?因為從調(diào)料盒舀取方便、快。
為什么某東自營的快遞那么快?全國各大倉庫就近發(fā)貨嘛。
以上便是計算機緩存的兩種思路:把常用的數(shù)據(jù)拷貝到速度更快的地方,或離用戶更近的地方,這樣拿數(shù)據(jù)就快多了。
圖3 計算機各類耗時
上圖是計算機各部件單次訪問的耗時,可見網(wǎng)絡(luò)傳輸、硬盤的耗時是大頭,所以這兩者能免則免。
數(shù)據(jù)中心里,還是以數(shù)據(jù)庫(Mysql)為例:它的全部數(shù)據(jù)存在硬盤上,但會將常用的熱點數(shù)據(jù)拷到內(nèi)存的緩沖池里,讀寫都在緩沖池,力求減免跟硬盤打交道而拖累整體效率。
這跟咱們寫文檔的情況是一樣的:打開文檔時文字被加載到電腦內(nèi)存,新寫的文字也記錄到內(nèi)存。
萬一電腦或程序崩潰卻沒保存,那新寫的可能就丟了,就是因為新寫的還沒來得及存到硬盤上呢(內(nèi)存斷電后數(shù)據(jù)會消失,而硬盤不會)。
數(shù)據(jù)庫則無需擔(dān)心,它有額外機制確保數(shù)據(jù)的改動不丟失,即預(yù)寫式日志:每次操作在硬盤里簡單記錄下對硬盤的修改結(jié)果,這樣即使沒保存事后也能恢復(fù)。
打個不太恰當(dāng)?shù)谋确?,就像咱上課除了認(rèn)真聽還要好好做筆記,即使課后有的忘了,也能根據(jù)筆記想起來。
3.3 負(fù)載均衡
俗話說得好:人多力量大。負(fù)載均衡就是以量取勝,通過增加節(jié)點來分?jǐn)倝毫?。生活中,像食堂如果有很多窗口都能排隊,是不是排隊時間就短多了呢?
數(shù)據(jù)中心里,需要有負(fù)載均衡器(如Nginx)來起到對請求分流的作用,將請求轉(zhuǎn)發(fā)到各后端節(jié)點。
面對流量高峰,后端節(jié)點的數(shù)量擴展如今挺方便,只要平臺實現(xiàn)了容器化部署,加節(jié)點就是點幾下按鈕的事。
數(shù)據(jù)庫也能負(fù)載均衡,即分庫分表,將一張大表拆分成若干小表,分散到各機器上。正所謂船大難掉頭,改成若干艘小船當(dāng)然就輕松靈活了。
但分庫分表不是點幾下按鈕就能解決的,它涉及到數(shù)據(jù)遷移、改代碼、測試、上線。因此數(shù)據(jù)庫的擴容,需要未雨綢繆,早做謀劃;否則流量高峰期系統(tǒng)可能被沖垮,這樣所有人都用不了了。
3.4 并發(fā)
雖說人多力量大,但個體太弱也不行。如何讓個體變強,即如何提升單臺服務(wù)器的性能呢?
并發(fā)是一種思路。如今的計算機可以同時放歌、聊微信、下載視頻,似乎這對于萬能的計算機是理所當(dāng)然的。
然而,早期的計算機,同一時間只能運行一個軟件、給一個用戶用,相當(dāng)不方便。
后來分時操作系統(tǒng)解決了這個問題,原理是將CPU的時間分成一片片(幾十到幾百毫秒),輪流分給不同的軟件使用(此處指單核CPU)。這體現(xiàn)了并發(fā)的思想:若干事件微觀上先后輪流進行,但宏觀表現(xiàn)為同時進行。
你可能想,這不是騙人嗎,而且每個軟件的效率會明顯降低吧?
其實,一個軟件(或進程)不是一直占著CPU,很多時候是在休息(即阻塞),比如讀寫硬盤,等待網(wǎng)絡(luò)請求的回應(yīng)。此時CPU閑著也是閑著,拱手讓給其他軟件用豈不美哉。
就如泡茶問題:等水燒開期間去洗茶杯、放茶葉才是明智之舉,而不是等水燒開了再干活。
因此,操作系統(tǒng)的這種時間分片輪流使用的策略,一方面充分利用了CPU;另一方面,即使是一個真的連續(xù)干活的任務(wù)拆解為若干次分散執(zhí)行,多數(shù)情況下人宏觀上也感知不到微觀層面的這種卡頓。
3.5 CPU
最后補談一個重要因素:CPU。
你可能聽說過現(xiàn)在的軟件可復(fù)雜了,動不動幾十萬行代碼。實際上一次網(wǎng)絡(luò)請求涉及的代碼也是不計其數(shù),而這一切在短短幾(十)毫秒內(nèi)就能完成,已經(jīng)不是人的思維能跟得上的了。
這實際上離不開CPU的高性能。如今常見CPU一秒可以執(zhí)行幾十億次指令,而它誕生之初只能幾十萬次。如果沒有CPU的高速,互聯(lián)網(wǎng)精巧而龐雜的體系也無從談起了。
比如你盯著屏幕的這一刻,無論手機還是電腦,幕后英雄CPU正以我們無法想象的風(fēng)馳電掣在干各種活。
當(dāng)然,也不是CPU頻率越高就意味著軟件的性能越好,影響因素有很多,因此相信國產(chǎn)CPU后來居上也是有希望的。
四. 結(jié)語
用一個簡圖(圖4)概括本文:光速是“瞬時”傳輸?shù)谋匾獥l件;如果用戶多處理不過來,那就通過負(fù)載均衡增加節(jié)點;每個節(jié)點都能利用索引、緩存、并發(fā)來大幅提升性能;而CPU,又是鏈路上所有節(jié)點能夠快速處理的基礎(chǔ)。
圖4 網(wǎng)絡(luò)請求的優(yōu)化策略
網(wǎng)絡(luò)請求的優(yōu)化策略遠不止上文提到的,還有IO多路復(fù)用、池化、批量處理、削峰填谷等等,都不容小覷。
本文提到的網(wǎng)絡(luò)鏈路上各環(huán)節(jié)的優(yōu)化策略的舉例,匯總?cè)缦卤恚?/p>
表1 網(wǎng)絡(luò)請求鏈路上各環(huán)節(jié)的優(yōu)化策略舉例