揭秘:千里送信為何能到瞬時到達

2022.11.28

揭秘:千里送信為何能到瞬時到達


在這個互聯網時代、眾多事物已實現信息化,無論是搜索還是發消息,幾乎瞬間就能完成。然而這一局面並非理所當然,其背後的體系精巧而又復雜,一旦出問題可能讓人焦頭爛額,卻又無可奈何。本短文旨在快速科普,幫助讀者了解這一體系高效運轉的關鍵原因。

一.引言

兩百年前,人們想給遠方的人傳個話,需要十天半個月。互聯網時代,我們只要按下回車,信息秒達,結果秒出。

那你可曾想過,信息傳送為什麼可以這麼快?

你可能會說,信息以光速級別傳輸,不論是光纖還是4G/5G用的電磁波,那當然快了!

可是,僅僅是光速嗎?那為什麼原本掃碼秒出結果的核酸系統,高峰時一個人可能卡十幾分鐘;為什麼火車票搶著搶著系統就崩了?

直覺告訴我們,因為用戶多了,而係統應用的承載能力有限。因此,一個成熟的互聯網應用面對海量用戶,是練就了十八般武藝(優化策略)來巧妙應對。

其中有些策略的重要性堪比光速,有些也能在日常生活經驗中找到影子。

二. 整體流程

在介紹優化策略前,有必要對網絡信號的請求流程有個整體印象:

圖1為通過APP控制攝像頭“轉頭”的流程示意圖,大致勾勒了一個信號(網絡請求)的典型旅程。

圖片

圖1 網絡傳輸流程

簡單來說,一個網絡請求的耗時主要來自網絡傳輸、數據中心處理。

具體來說,APP上點擊按鈕-->“轉頭”指令等信息,會被轉化為0和1的二進制序列-->手機通過內置天線發射電磁波-->基站-->運營商機房-->通過光纖傳送到千里之外的數據中心(圖1)。

數據中心存放著系統的雲端平台。平台處理後,將“轉頭”指令發出-->光纖傳輸-->到家中路由器,通過無線信號發給攝像頭-->攝像頭接收信號並轉為0和1的序列-->還原為攝像頭軟件可理解的指令-->操控電機進行旋轉。

圖片

圖2 數據中心的平台組成

一眨眼的功夫,就完成了這麼多環節(實際過程遠比此復雜)。

從中可見,光速解決的僅僅是長距離傳輸的耗時問題,如果哪個節點卡住,效率直線下降,就如同短板木桶,盛水能力將大打折扣。

優化策略有很多,本文將介紹其中最為關鍵的4種:索引,緩存,負載均衡,並發。

三. 優化策略

3.1 索引

索引可以說是非常偉大的發明了。用一句話說就是:事先分類排序,到時找起來方便。比如查字典,咱都是按索引查,如果沒索引,從頭找到尾可要累死個人。

數據中心裡的數據庫,幾千萬條數據也是司空見慣了。以mysql為例,用的索引方案一般是B+樹,找一條數據1~4次即可找到,耗時約幾十毫秒。而如果沒有索引則需要遍歷,可能十幾秒才能找到,差距達數百倍。

相信大家用過windows自帶的文件搜索,慢得令人無語;如果用everything等軟件則瞬間出結果,正體現了索引的強大威力。(注:windows不是完全不用索引,是沒用合適的索引)

當然索引並非全無代價:佔存儲空間;索引樹時常變化,引起性能消耗。雖有代價,但非常值得,正所謂磨刀不誤砍柴工嘛。

計算機的世界,索引無處不在,此處囿於篇幅不展開詳述,若感興趣詳見文末表格。正是每個環節盡可能地用上索引,用巧妙的“速達”取代笨拙的“遍歷”,才讓一次請求盡可能地快。

3.2 緩存

為什麼廚房的鹽、味精要從調料盒裡舀取,而不從包裝袋裡舀?因為從調料盒舀取方便、快。

為什麼某東自營的快遞那麼快?全國各大倉庫就近發貨嘛。

以上便是計算機緩存的兩種思路:把常用的數據拷貝到速度更快的地方,或離用戶更近的地方,這樣拿數據就快多了。

圖片

圖3 計算機各類耗時

上圖是計算機各部件單次訪問的耗時,可見網絡傳輸、硬盤的耗時是大頭,所以這兩者能免則免。

數據中心裡,還是以數據庫(Mysql)為例:它的全部數據存在硬盤上,但會將常用的熱點數據拷到內存的緩衝池裡,讀寫都在緩衝池,力求減免跟硬盤打交道而拖累整體效率。

這跟咱們寫文檔的情況是一樣的:打開文檔時文字被加載到電腦內存,新寫的文字也記錄到內存。

萬一電腦或程序崩潰卻沒保存,那新寫的可能就丟了,就是因為新寫的還沒來得及存到硬盤上呢(內存斷電後數據會消失,而硬盤不會)。

數據庫則無需擔心,它有額外機制確保數據的改動不丟失,即預寫式日誌:每次操作在硬盤裡簡單記錄下對硬盤的修改結果,這樣即使沒保存事後也能恢復。

打個不太恰當的比方,就像咱上課除了認真聽還要好好做筆記,即使課後有的忘了,也能根據筆記想起來。

3.3 負載均衡

俗話說得好:人多力量大。負載均衡就是以量取勝,通過增加節點來分攤壓力。生活中,像食堂如果有很多窗口都能排隊,是不是排隊時間就短多了呢?

數據中心裡,需要有負載均衡器(如Nginx)來起到對請求分流的作用,將請求轉發到各後端節點。

面對流量高峰,後端節點的數量擴展如今挺方便,只要平台實現了容器化部署,加節點就是點幾下按鈕的事。

數據庫也能負載均衡,即分庫分錶,將一張大表拆分成若干小表,分散到各機器上。正所謂船大難掉頭,改成若干艘小船當然就輕鬆靈活了。

但分庫分錶不是點幾下按鈕就能解決的,它涉及到數據遷移、改代碼、測試、上線。因此數據庫的擴容,需要未雨綢繆,早做謀劃;否則流量高峰期系統可能被沖垮,這樣所有人都用不了了。

3.4 並發

雖說人多力量大,但個體太弱也不行。如何讓個體變強,即如何提升單台服務器的性能呢?

並發是一種思路。如今的計算機可以同時放歌、聊微信、下載視頻,似乎這對於萬能的計算機是理所當然的。

然而,早期的計算機,同一時間只能運行一個軟件、給一個用戶用,相當不方便。

後來分時操作系統解決了這個問題,原理是將CPU的時間分成一片片(幾十到幾百毫秒),輪流分給不同的軟件使用(此處指單核CPU)。這體現了並發的思想:若干事件微觀上先後輪流進行,但宏觀表現為同時進行。

你可能想,這不是騙人嗎,而且每個軟件的效率會明顯降低吧?

其實,一個軟件(或進程)不是一直佔著CPU,很多時候是在休息(即阻塞),比如讀寫硬盤,等待網絡請求的回應。此時CPU閒著也是閒著,拱手讓給其他軟件用豈不美哉。

就如泡茶問題:等水燒開期間去洗茶杯、放茶葉才是明智之舉,而不是等水燒開了再乾活。

因此,操作系統的這種時間分片輪流使用的策略,一方面充分利用了CPU;另一方面,即使是一個真的連續幹活的任務拆解為若干次分散執行,多數情況下人宏觀上也感知不到微觀層面的這種卡頓。

3.5 CPU

最後補談一個重要因素:CPU。

你可能聽說過現在的軟件可複雜了,動不動幾十萬行代碼。實際上一次網絡請求涉及的代碼也是不計其數,而這一切在短短幾(十)毫秒內就能完成,已經不是人的思維能跟得上的了。

這實際上離不開CPU的高性能。如今常見CPU一秒可以執行幾十億次指令,而它誕生之初只能幾十萬次。如果沒有CPU的高速,互聯網精巧而龐雜的體係也無從談起了。

比如你盯著屏幕的這一刻,無論手機還是電腦,幕後英雄CPU正以我們無法想像的風馳電掣在干各種活。

當然,也不是CPU頻率越高就意味著軟件的性能越好,影響因素有很多,因此相信國產CPU後來居上也是有希望的。

四. 結語

用一個簡圖(圖4)概括本文:光速是“瞬時”傳輸的必要條件;如果用戶多處理不過來,那就通過負載均衡增加節點;每個節點都能利用索引、緩存、並發來大幅提升性能;而CPU,又是鏈路上所有節點能夠快速處理的基礎。

圖片

圖4 網絡請求的優化策略

網絡請求的優化策略遠不止上文提到的,還有IO多路復用、池化、批量處理、削峰填谷等等,都不容小覷。

本文提到的網絡鏈路上各環節的優化策略的舉例,匯總如下表:

表1 網絡請求鏈路上各環節的優化策略舉例

圖片