知識學習 - 直播每秒百萬按讚:直播影片上的即時互動

Streaming a Million Likes/Second: Real-Time Interactions on Live Video

介紹人是 LinkedIn 的工程師在介紹他們怎麼處理在直播影片上的即時互動。演講上使用幾個不同階段的挑戰來說明技術上的選擇和處理。

挑戰 1:傳輸管道

一開始的需求很簡單,因為需要持續的互動。所以需要選擇一個可以長時間連線的手段,而這邊選擇使用了 Server-Sent Event 來做處理。因為其就跟常規的 HTTP 一樣只是給予不同的 Accept Header

挑戰 2:連線管理

有了連線的手段後,再來的挑戰就是有上千萬的連線而這些連線該怎麼管理呢?這邊採用的是 Akka ,每個連線 Akka 都會指派一個 Thread 來做處理,這邊專門處理當接收到 Message 的時候要怎麼處理。這邊選擇使用 Play 框架 來做處理。Play 將其轉換成持久的連線,被分配一個隨機的 connectionId。然後會將其 connectionId 和處理 EventSource 的部分實例化一個 Akka Actor 來管理這些連線。

所以現在流程上,每個 Client 的連線都會有一個對應的 Akka Actor 管理,然後所有的 Akka Actor 又會由 Akka Supervisor Actor 來管理。當有使用者送出 Like 的 HTTP 請求時,會將其送到 Akka Supervisor Actor,然後 Supervisor Actor 會在廣播給所有的 Akka Actor,而 Akka Actor 就只需要將其收到的訊息透過 EventSource 送到該 Client。

挑戰 3:多個直播影片

因為要導入訂閱的概念,所以需要管理發送的訊息要給正確的使用者。而這些訂閱的關係儲存在記憶體資料庫中。所以當使用者送出 HTTP 請求後,Supervisor Actor 需要去記憶體資料庫中找出要發送給誰。

挑戰 4:10k 併發觀眾

這邊開始就要邁向伺服器的擴展挑戰,今天這邊在前端節點的後面再加上一個 dispatcher。現在每個前端節點(Supervisor Actor)需要將目前有的連線發送到 Dispatcher。所以當有按讚請求發生時,將會先經過 Dispatcher -> 多個 Supervisor Actor -> 多個 Akka Actor -> 所有有訂閱的 Client。

挑戰 5:每秒 100 個讚

因為請求變高了,當然可以就很偷懶的在增加 Dispatcher 來乘載更多的請求。但是這邊就會有問題,因為每個 Dispatcher 都會需要每個前端節點發送連線狀態,而且一旦節點消失,就會丟失資料。所以需要將其提取出來成一個獨立的記憶體資料庫。任何的節點都可以隨時訪問。來解決擴充上和資料儲存的問題

挑戰 6:每秒 100 個讚、10k 觀看者總共發佈每秒 100 萬個讚

(重新展示前面的所有過程)

額外挑戰:另一個資料中心

當今天不只一個資料中心的時候怎麼處理。再討論是要以跨資料中心方式訂閱還是以跨資料中心方式發布之後,認為以後者方式在此處是更好的選擇。第一個資料中心的 Dispatcher 收到請求後,會像其他資料中心的 Dispatcher 發送通知,各資料中心的 Dispatcher 在各自查詢連線並發送給 Client。

成效 & 擴展

有做過一些嘗試,每一台機器都可以處理 100,000 個連線。所以已有處理得過的案例,英國皇家婚禮,有 1800 萬個觀眾,只需要 180 台機器就可以處理。但是當然沒有說的那麼容易,因為也還是有遇到一些額外的問題,例如 file descriptor limits, port exhaustion, even memory limits。在這裡都有記錄這些內容。

然後這些架構下每個 Dispatcher 節點可以接收每秒 5000 個事件。而延遲的話 p90 之下只有 75 毫秒。

問答

Q:對於不支援 Server-Sent Event 的 Client 有什麼備案嗎? A:因為 SSE 是一個常規的 HTTP,所以這跟一般的 HTTP 沒有差別。而且事實上 WebSockets 有時會在一些系統上被防火牆擋住。我們也沒遇過 SSE 不起作用的情況,大多數的防火牆也不會擋住。

Q:基本上,如何將直播跟喜歡的時間同步 A:您是想知道確保下次有人觀賞時點讚會同時出現嗎? Q:是的,因為直播在不同的伺服器上會有延遲,按讚發生的時間點可能不同 A:延遲是一定的,但是因為我們的延遲時間很短,對於使用者幾乎是沒有差別的

Q:如何保證一致性,尤其考慮到 Dispatcher 會跨資料中心的故障狀況 A:答案是我們沒有保證,因為我們追求的是速度,我們不保證其一定會完成。雖然這麼說但不表示我們會不管,我們依舊會監控前端發送的請求和實際被 Client 接受的比例,如果下降會找出原因並修正

可能有些人會說怎麼不用 Kafka,但問題在於你不知道直播何時會發起,也不知道何時會有人發送請求。這在於要讓我們發送和刪除事件時是很不容易的。

結語

是一篇看完頭有點痛的文章呢,好多英文想吐了

Reference