自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

流量拆分:如何通過架構設計緩解流量壓力?

開發(fā) 架構
即使通過這么多技術來優(yōu)化架構,我們的服務仍舊無法完全承受過高的瞬發(fā)流量。對于這種情況,我們可以做一些服務降級的操作,通過隊列將修改合并或做網(wǎng)關限流。雖然這會犧牲一些實時性,但是實際上,很多數(shù)字可能沒有我們想象中那么重要。

今天,我打算以直播互動作為例子,引領大家一同去了解在面對讀多寫多的情況時,應當怎樣去應對所產生的流量壓力。通常而言,這類服務在多數(shù)情況下都屬于實時互動服務。由于其對時效性有著極高的要求,這就致使在許多場景當中,我們沒辦法借助讀緩存的方式來減輕核心數(shù)據(jù)所承受的壓力。

那么,為了有效降低這類互動服務器所面臨的壓力,我們能夠從架構層面著手,開展一些具有靈活性的拆分操作,并對其進行相應的設計改造。

實際上,這些設計是通過混合的方式來實現(xiàn)對外提供服務的。為了能夠讓大家更為清晰地理解這其中的原理,我將會針對直播互動里特定的一些場景展開詳細講解。

一般來講,直播場景是可以被劃分成兩種不同類型的,即可以預估用戶量的場景以及不可預估用戶量的場景。這兩種場景下的設計存在著很大的差異,接下來,我們就分別對它們進行深入的探討。

可預估用戶量的服務:游戲創(chuàng)建房間

想必不少熱衷于對戰(zhàn)游戲的小伙伴都曾有過這樣的經歷:在聯(lián)網(wǎng)玩游戲時,首先得創(chuàng)建房間才行。這種游戲設計方式呢,主要是依靠設定一臺服務器所能開啟的房間數(shù)量上限,以此來對一臺服務器可同時服務的用戶數(shù)量加以限制。

接下來,咱們從服務器端的資源分配這個角度出發(fā),深入剖析一下創(chuàng)建房間這一設計究竟是怎樣進行資源調配的。

當房間創(chuàng)建完成之后,用戶憑借房間號便能夠邀請其他伙伴加入游戲,從而展開對戰(zhàn)。無論是房主呢,還是后續(xù)加入的伙伴,都會依據(jù)房間的標識,由調度服務統(tǒng)一安排到同一服務集群之上,進而開展互動交流。

這里得給大家提個醒哦,開房間這個動作并非一定要由游戲用戶親自去完成呀,我們完全可以將其設置成用戶開啟游戲之時就自動為其分配房間。如此一來,不但能夠提前對用戶量進行預估,而且還能極為出色地對我們的服務資源加以規(guī)劃與掌控呢。

那么,要怎樣去評估一臺服務器能夠支持多少人同時在線呢?其實呀,我們可以通過壓力測試的方法,測出單臺服務器所能服務的在線人數(shù),進而依據(jù)這個數(shù)據(jù)來精確地預估所需要的帶寬以及服務器資源,從而算出一個集群(要知道,這個集群可是包含了若干臺服務器哦)究竟需要多少資源,又能夠承擔多少人在線開展互動活動。最后呢,再借助調度服務來對資源進行分配,把新來的房主分配到尚有空閑的服務集群當中。

下面給大家展示一下最終的實現(xiàn)效果:

圖片圖片

就像前面所展示的那樣,在創(chuàng)建房間的這個階段呀,我們的客戶端在進入?yún)^(qū)域服務器集群之前呢,都是依靠向調度服務發(fā)起請求,進而由調度服務來完成相應調度工作的。

調度服務器會按照一定的周期,去接收來自各個組服務器的服務用戶在線情況方面的信息哦。通過對這些信息的分析與處理,調度服務器就能夠評估出究竟需要調配多少用戶進入到不同的區(qū)域集群當中啦。

與此同時呢,客戶端在收到調度指令之后呀,會拿著調度服務所給予的 token,前往不同的區(qū)域去申請創(chuàng)建房間呢。

等到房間成功創(chuàng)建之后呀,調度服務就會在本地的集群內部,對這個房間的列表以及相關信息進行維護管理哦。這些信息呢,還會提供給其他那些想要加入游戲的玩家進行查看展示呢。

而那些后續(xù)加入游戲的玩家呀,同樣也會接入到對應房間所在的區(qū)域服務器當中,從而能夠和房主以及同房間的其他玩家開展實時的互動交流呢。這種通過限定配額房間個數(shù)的方式來進行服務器資源調度的設計呀,可不單單是在對戰(zhàn)游戲里面才會用到哦,在很多其他的場景當中呀,也都采用了類似的設計呢,就比如說在線小課堂這類涉及教學互動的場景呀。

我們完全可以預見到呀,通過采用這樣的設計呢,就能夠對資源實現(xiàn)精準的把控啦,如此一來,用戶的數(shù)量也就不會超出我們服務器所設計的容量范圍啦。

不可預估用戶量的服務

然而呢,在很多場景當中,情況是具有隨機性的,我們根本沒辦法確切地把握會有多少用戶進入到這個服務器來進行互動交流。就拿全國直播來說吧,根本就無法確定究竟會有多少用戶來訪問呀。

鑒于這種情況呢,很多直播服務首先會依據(jù)主播過往的情況來預測用戶量哦。通過對這個預估量的分析呢,提前把他們的直播安排到相對比較空閑的服務器群組里面。同時呢,還會提前準備好一些調度工具哦,比如說通過控制曝光度的方式來延緩用戶進入直播。通過這樣的操作呢,就能夠為服務器調度爭取到更多的時間,以便進行動態(tài)擴容啦。

由于這一類服務沒辦法預估到底會有多少用戶,所以之前那種服務器小組的模式呀,并不適用于這種情況哦,而是需要更高級別的調度呢。下面我們來分析一下這個場景哦。對于直播而言呢,用戶常見的交互形式包含了聊天、答題、點贊、打賞以及購物等等??紤]到這些交互形式各自具有不同的特點,我們接下來針對不同的關鍵點依次進行分析。

聊天:信息合并

聊天的內容普遍比較短,為了提高吞吐能力,通常會把用戶的聊天內容放入分布式隊列做傳輸,這樣能延緩寫入壓力。另外,在點贊或大量用戶輸入同樣內容的刷屏情境下,我們可以通過大數(shù)據(jù)實時計算分析用戶的輸入,并壓縮整理大量重復的內容,過濾掉一些無用信息。

圖片

壓縮整理后的聊天內容會被分發(fā)到多個聊天內容分發(fā)服務器上,直播間內用戶的聊天長連接會收到消息更新的推送通知,接著客戶端會到指定的內容分發(fā)服務器群組里批量拉取數(shù)據(jù),拿到數(shù)據(jù)后會根據(jù)時間順序來回放。請注意,這個方式只適合用在瘋狂刷屏的情況,如果用戶量很少可以通過長鏈接進行實時互動。

答題:瞬時信息拉取高峰

除了交互流量極大的聊天互動信息之外,還存在一些特殊的互動形式,比如做題互動。在直播間里,當老師發(fā)送一個題目時,題目消息會被廣播給所有用戶,而客戶端收到消息后會從服務端拉取題目的數(shù)據(jù)。

想象一下,如果有 10 萬用戶同時在線,那么很有可能會出現(xiàn)瞬間有 10 萬人在線同時請求服務端拉取題目的情況。如此龐大的數(shù)據(jù)請求量,若要承受得住,就需要我們投入大量的服務器和帶寬資源,但這樣做的性價比其實并不高。

從理論上來說,我們可以將數(shù)據(jù)靜態(tài)化,并通過 CDN 來阻擋這個流量。然而,為了避免出現(xiàn)瞬時的高峰情況,推薦在客戶端拉取時加入隨機延遲幾秒的操作,然后再發(fā)送請求。這樣做能夠大大延緩服務器的壓力,從而獲得更好的用戶體驗。

請務必牢記,對于客戶端而言,如果這種服務請求失敗了,就不要頻繁地進行請求重試,否則會將服務端 “打沉”。如果確實必須要進行重試,那么建議對重試的時間采用退火算法。通過這樣的方式,可以保證服務端不會因為一時的故障而收到大量的請求,進而避免服務器崩潰。

如果是在教學場景的直播中,有兩個可以緩解服務器壓力的技巧。

第一個技巧是在上課當天,把搶答題目提前交給客戶端做預加載下載。這樣一來,就能夠減少實時拉取的壓力。

第二個方式是針對題目搶答的情況。當老師發(fā)布題目的時候,提前設定發(fā)送動作生效后 5 秒再彈出題目。如此操作,能夠讓所有直播用戶的接收端 “準時” 地收到題目信息,而不至于出現(xiàn)用戶題目接收時間不一致的情況。

至于非搶答類型的題目,當用戶回答完題目后,我們可以先在客戶端本地先做預判卷,把正確答案和解析展示給用戶。然后,在直播期間異步緩慢地將用戶答題結果提交到服務端。通過這樣的方式,能夠保證服務器不會因用戶瞬時的流量而被沖垮。

點贊:客戶端互動合并

接下來,針對點贊的場景,我打算從客戶端以及服務端這兩個不同的角度來為大家詳細介紹一下。

咱們先來看客戶端這邊的情況。在很多時候呀,客戶端其實并不需要實時地去提交用戶所做出的全部交互動作哦。這是因為呀,有不少交互動作屬于那種機械性的重復動作,它們對于實時性的要求并沒有那么高呢。

給大家舉個例子吧,比如說用戶在本地特別快速地連續(xù)點擊了 100 下贊,在這種情況下呢,客戶端就完全可以把這些點贊操作合并起來,將其轉化為一條消息進行處理呀,就好比是 “用戶在 3 秒內點贊 10 次” 這樣的表述形式。

我相信呀,像大家這么聰明的人,肯定能夠把這種將互動動作進行合并的小妙招運用到更多的情景當中去哦。比如說,當用戶連續(xù)打賞 100 個禮物的時候,同樣也可以采用這樣的方式來處理呀。

通過運用這種方式呢,能夠極大幅度地降低服務器所承受的壓力哦。這樣一來呀,既可以確保直播間依舊保持那種火爆的氛圍,同時呢,還能夠節(jié)省下大量的流量資源呢,這可真是一件一舉多得的好事呀,大家何樂而不為呢?

點贊:服務端樹形多層匯總架構

我們回頭再看看點贊的場景下,如何設計服務端才能緩解請求壓力。如果我們的集群 QPS 超過十萬,服務端數(shù)據(jù)層已經無法承受這樣的壓力時,如何應對高并發(fā)寫、高并發(fā)讀呢?微博做過一個類似的案例,用途是緩解用戶的點贊請求流量,這種方式適合一致性要求不高的計數(shù)器,如下圖所示:

圖片圖片

這個方式可以將用戶點贊流量隨機壓到不同的寫緩存服務上,通過第一層寫緩存本地的實時匯總來緩解大量用戶的請求,將更新數(shù)據(jù)周期性地匯總后,提交到二級寫緩存。之后,二級匯總所在分片的所有上層服務數(shù)值后,最終匯總同步給核心緩存服務。接著,通過核心緩存把最終結果匯總累加起來。最后通過主從復制到多個子查詢節(jié)點服務,供用戶查詢匯總結果。

打賞 & 購物:服務端分片及分片實時擴容

前面的互動只要保證最終一致性就可以,但打賞和購物的場景下,庫存和金額需要提供事務一致性的服務。因為事務一致性的要求,這種服務我們不能做成多層緩沖方式提供服務,而且這種服務的數(shù)據(jù)特征是讀多寫多,所以我們可以通過數(shù)據(jù)分片方式實現(xiàn)這一類服務,如下圖:

圖片圖片

看過圖之后,是不是感覺理解起來輕松多了呀?下面我再詳細說一說哦。

我們可以依據(jù)用戶的 id 來進行 hash 拆分操作呢。具體做法是,通過網(wǎng)關把不同用戶的 uid 進行取模處理,然后按照取模所得的數(shù)值范圍,將用戶分配到不同的分片服務上去。之后呢,處于各個分片內的服務就會針對類似的請求開展內存實時計算更新的工作啦。

通過采用這樣的方式呀,能夠較為快速且便捷地實現(xiàn)負載的切分哦。不過呢,這種 hash 分配的方式也存在一定的弊端哦,那就是容易出現(xiàn)個別熱點的情況呢。當我們面臨的流量壓力大到服務器扛不住的時候呀,就需要對服務器進行擴容處理啦。

而且呀,要是采用 hash 這種方式,一旦出現(xiàn)個別服務器發(fā)生故障的情況,就會導致 hash 映射出現(xiàn)錯誤哦,這樣一來,請求就可能會被發(fā)送到錯誤的分片上去啦。

針對這些問題呀,其實是有很多類似的解決方案的哦。比如說一致性 hash 算法吧,這種算法的優(yōu)勢在于它可以針對局部的區(qū)域進行擴容操作,而且不會對整個集群的分片造成影響哦。但是呢,這個方法在很多時候呀,由于其算法本身不夠通用,并且無法由人來進行有效控制,所以使用起來就會顯得特別麻煩呢,還需要專門開發(fā)配套的工具才行哦。

除此之外呀,我再給大家推薦另外一種方式哦,那就是樹形熱遷移切片法啦。這是一種類似于虛擬桶的方式哦。打個比方來說吧,我們可以把全量數(shù)據(jù)拆分成 256 份呀,每一份就代表一個桶哦。假如有 16 個服務器的話,那么每個服務器就可以分到 16 個桶啦。

當我們發(fā)現(xiàn)個別服務器的壓力過大的時候呀,就可以給這個服務器增加兩個訂閱服務器哦,讓它們去做主從同步的工作呢,也就是把這個服務器上的 16 個桶的數(shù)據(jù)進行遷移操作啦。

等到同步遷移的工作成功完成之后呀,就可以把原本發(fā)送到這個服務器的請求流量進行拆分處理啦,然后分別轉發(fā)到兩個各有 8 個桶的服務器上去哦。之后呢,就讓這兩個訂閱服務器分別接收請求并繼續(xù)對外提供服務啦,而原來那個壓力過大的服務器呢,就可以把它摘除并進行回收處理啦。

在服務成功完成切換之后呀,因為進行的是全量遷移,所以這兩個新的服務會同時同步到原本并不屬于它們各自的 8 個桶的數(shù)據(jù)哦。在這種情況下呢,新服務器只需要去遍歷自己所存儲的數(shù)據(jù),然后把那些不屬于自己的數(shù)據(jù)給刪除掉就可以啦。

當然啦,還有另外一種做法哦,那就是在同步來自 16 桶服務的數(shù)據(jù)的時候呢,就直接把那些不屬于自身的相關數(shù)據(jù)給過濾掉呀。需要說明的是,這個方法對于 Redis、MySQL 等所有存在有狀態(tài)分片數(shù)據(jù)的服務來說,都是適用的哦。

不過呢,這個服務存在一個難點哦,那就是請求的客戶端并不會直接去請求分片哦,而是要通過代理服務來對數(shù)據(jù)服務發(fā)起請求呢。只有借助代理服務呀,才能夠實現(xiàn)對調度流量進行動態(tài)更新,進而達到平滑且無損地轉發(fā)流量的目的哦。

最后呀,咱們再來探討一下這樣一個問題哦,那就是如何讓客戶端知道應該去請求哪個分片才能夠找到它所需要的數(shù)據(jù)呢?在這里呀,我給大家分享兩種比較常見的方式哦。

第一種方式是這樣的哦,客戶端可以通過特定的算法來找到分片哦。比如說呢,可以采用這樣的算法:用戶 hash (uid) % 100 = 桶 id 哦。然后呢,在配置文件當中,通過這個桶 id 就能夠找到與之對應的分片啦。

第二種方式則是呢,當數(shù)據(jù)服務端接收到客戶端的請求之后呀,會把這個請求轉發(fā)到存有相關數(shù)據(jù)的分片那里哦。比如說吧,客戶端一開始請求的是 A 分片,然后再根據(jù)相應的數(shù)據(jù)算法以及對應的分片配置,發(fā)現(xiàn)所需要的數(shù)據(jù)其實是在 B 分片那里哦。這個時候呢,A 分片就會把這個請求轉發(fā)到 B 分片哦。等到 B 分片處理完這個請求之后呢,就會把數(shù)據(jù)返回給客戶端啦(這里的數(shù)據(jù)返回方式呢,是由 A 返回還是由 B 返回,這就要取決于客戶端是進行跳轉操作還是由服務端來進行轉發(fā)操作啦)。

服務降級:分布式隊列匯總緩沖

即使通過這么多技術來優(yōu)化架構,我們的服務仍舊無法完全承受過高的瞬發(fā)流量。對于這種情況,我們可以做一些服務降級的操作,通過隊列將修改合并或做網(wǎng)關限流。雖然這會犧牲一些實時性,但是實際上,很多數(shù)字可能沒有我們想象中那么重要。像微博的點贊統(tǒng)計數(shù)據(jù),如果客戶端點贊無法請求到服務器,那么這些數(shù)據(jù)會在客戶端暫存一段時間,在用戶看數(shù)據(jù)時看到的只是短期歷史數(shù)字,不是實時數(shù)字。十萬零五的點贊數(shù)跟十萬零三千的點贊數(shù),差異并不大,等之后服務器有空閑了,結果追上來最終是一致的。但作為降級方案,這么做能節(jié)省大量的服務器資源,也算是個好方法。

責任編輯:武曉燕 來源: 二進制跳動
相關推薦

2012-04-27 09:32:22

WAN優(yōu)化數(shù)據(jù)中心

2009-04-22 10:16:37

網(wǎng)站架構Web數(shù)據(jù)冗余

2023-12-14 08:39:52

2024-05-27 08:32:45

2020-01-17 11:00:23

流量系統(tǒng)架構

2020-04-22 14:25:48

云開發(fā)高可用架構

2022-02-22 10:29:24

分布式架構高可用

2010-10-26 11:22:26

2023-07-09 15:24:05

架構設計思想AKF

2009-05-05 10:24:48

應用架構設計原則

2020-09-29 08:32:03

數(shù)據(jù)中心故障緩解

2024-10-14 11:56:50

2022-09-01 21:56:34

KubernetesLinkerd

2021-12-03 10:47:28

WOT技術峰會技術

2013-05-10 09:40:46

OpenFlow標準接口協(xié)議SDN

2017-01-23 10:10:09

2015-10-12 08:53:49

程序員壓力

2011-03-23 12:49:53

NagiosSNMP流量

2021-09-02 10:37:53

分布式大型網(wǎng)站架構

2021-03-02 07:54:18

流量網(wǎng)關設計
點贊
收藏

51CTO技術棧公眾號