如何打造千萬級Feed流系統

阿里云云棲社群發表於2019-03-04

摘要:Feed流是一個目前非常常見的功能,在眾多產品中都有展現,通過Feed流可以把動態實時的傳播給訂閱者,是使用者獲取資訊流的一種有效方式。在大資料時代,如何打造一個千萬級規模的Feed流系統仍然是一個挑戰。

在網際網路領域,尤其現在的移動網際網路時代,Feed流產品是非常常見的,比如我們每天都會用到的朋友圈,微博,就是一種非常典型的Feed流產品,還有圖片分享網站Pinterest,花瓣網等又是另一種形式的Feed流產品。除此之外,很多App的都會有一個模組,要麼叫動態,要麼叫訊息廣場,這些也是Feed流產品,可以說,Feed流產品是遍佈天下所有的App中。

概念

我們在講如何設計Feed流系統之前,先來看一下Feed流中的一些概念:

Feed:Feed流中的每一條狀態或者訊息都是Feed,比如朋友圈中的一個狀態就是一個Feed,微博中的一條微博就是一個Feed。

Feed流:持續更新並呈現給使用者內容的資訊流。每個人的朋友圈,微博關注頁等等都是一個Feed流。

Timeline:Timeline其實是一種Feed流的型別,微博,朋友圈都是Timeline型別的Feed流,但是由於Timeline型別出現最早,使用最廣泛,最為人熟知,有時候也用Timeline來表示Feed流。

關注頁Timeline:展示其他人Feed訊息的頁面,比如朋友圈,微博的首頁等。

個人頁Timeline:展示自己傳送過的Feed訊息的頁面,比如微信中的相簿,微博的個人頁等。

特徵

Feed流系統有一些非常典型的特點,比如:

多賬號內容流:Feed流系統中肯定會存在成千上萬的賬號,賬號之間可以關注,取關,加好友和拉黑等操作。只要滿足這一條,那麼就可以當做Feed流系統來設計。

非穩定的賬號關係:由於存在關注,取關等操作,所以系統中的使用者之間的關係就會一直在變化,是一種非穩定的狀態。

讀寫比例100:1:讀寫嚴重不平衡,讀多寫少,一般讀寫比例在10:1,甚至100:1以上。

訊息必達性要求高:比如傳送了一條朋友圈後,結果部分朋友看到了,部分朋友沒看到,如果偏偏女朋友沒看到,那麼可能會產生很嚴重的感情矛盾,後果很嚴重。

上面的就是Feed流產品的一些特點,下面我們來看一下Feed流系統的分類。

分類

Feed流的分類有很多種,但最常見的分類有兩種:

Timeline:按釋出的時間順序排序,先發布的先看到,後釋出的排列在最頂端,類似於微信朋友圈,微博等。這也是一種最常見的形式。產品如果選擇Timeline型別,那麼就是認為Feed流中的Feed不多,但是每個Feed都很重要,都需要使用者看到。

Rank:按某個非時間的因子排序,一般是按照使用者的喜好度排序,使用者最喜歡的排在最前面,次喜歡的排在後面。這種一般假定使用者可能看到的Feed非常多,而使用者花費在這裡的時間有限,那麼就為使用者選擇出使用者最想看的Top N結果,場景的應用場景有圖片分享、新聞推薦類、商品推薦等。

上面兩種是最典型,也是最常見的分類方式,另外的話,也有其他的分類標準,在其他的分類標準中的話,會多出兩種型別:

Aggregate:聚合型別,比如好幾個朋友都看了同一場電影,這個就可以聚合為一條Feed:A,B,C看了電影《你的名字》,這種聚合功能比較適合在客戶端做。一般的Aggregate型別是Timeline型別 + 客戶端聚合。

Notice:通知型別,這種其實已經是功能型別了,通知型別一般用於APP中的各種通知,私信等常見。這種也是Timeline型別,或者是Aggregate型別。

實現

上面介紹了Feed流系統的概念,特徵以及分類,接下來開始進入關鍵部分:如何實現一個千萬級Feed流系統。由於系統中的所有使用者不可能全部線上,且不可能同時重新整理和釋出Feed,那麼一個能支撐千萬量級Feed流的系統,其實在產品上可以支撐上億的使用者。

如果要設計一個Feed流系統,最關鍵的兩個核心,一個是儲存,一個是推送。

儲存

我們先來看儲存,Feed流系統中需要儲存的內容分為兩部分,一個是賬號關係(比如關注列表),一種是Feed訊息內容。不管是儲存哪一種,都有幾個問題需要考慮:

如何能支援100TB,甚至PB級資料量?

資料量大了後成本就很關鍵,成本如何能更便宜?

如何保證賬號關係和Feed不丟失?

我們後面再解答這三個問題,先繼續看推送

推送

推送系統需要的功能有兩個,一個是釋出Feed,一個是讀取Feed流。對於提送系統,仍然有一些問題需要在選型之前考慮:

如何才能提供千萬的TPS和QPS?

如何保證讀寫延遲在10ms,甚至2ms以下?

如何保證Feed的必達性?

再解答這些問題之前,我們先來大概瞭解下阿里雲的表格儲存TableStore。

TableStore

表格儲存(TableStore)是阿里雲自主研發的專業級分散式NoSQL資料庫,是基於共享儲存的高效能、低成本、易擴充套件、全託管的半結構化資料儲存平臺,

支撐網際網路和物聯網資料的高效計算與分析。

目前不管是阿里巴巴集團內部,還是外部公有云使用者,都有成千上萬的系統在使用。覆蓋了重吞吐的離線應用,以及重穩定性,效能敏感的線上應用。目前使用的系統中,有些系統每秒寫入行數超過3500萬行,每秒流量超過5GB,單表總行數超過10萬億行,單表資料量超過10PB。

表格儲存的具體的特性可以看下面這張圖片。

如何打造千萬級Feed流系統

這裡就不詳細介紹表格儲存(TableStore)的功能和特性了,有興趣的話可以到官網頁面和雲棲部落格瞭解,地址如下:

表格儲存的官網地址:www.aliyun.com/product/ots…

表格儲存雲棲部落格:yq.aliyun.com/teams/4/typ…

表格儲存釘釘交流群:11789671

儲存系統選擇

我們接下來解決之前提出來的問題。

Feed流系統中需要儲存的系統有兩類,一類是賬號關係(比如關注列表),一類是Feed訊息。

儲存賬號關係

我們先來看賬號關係(比如關注列表)的儲存,對於賬號關係,它有一些特點:

是一系列的變長連結串列,長度可達億級別。

這樣就會導致資料量比較大,但是關係極其簡單。

還有一點是效能敏感,直接影響關注,取關的響應速度。

最適合存賬號關係(關注列表)的系統應該是分散式NoSQL資料庫,原因是資料量極大,關係簡單不需要複雜的join,效能要求高。

對內設計實現簡單,對外使用者體驗好。

除了上面這些特點外,還有一個特點:

有序性:有序性並不要求具有排序功能,只需要能按照主鍵排序就行,只要能按照主鍵排序,那麼關注列表和粉絲列表的順序就是固定的,可預期的。

使用開源HBase儲存賬號關係

能滿足有序性的分散式NoSQL資料庫中,開源HBase就是一個,所以很多企業會選擇開源HBase來儲存賬號關係,或者是關注列表。

這樣雖然滿足了上述四個特徵,可以把系統搭建起來,但是會有一些麻煩的問題:

需要自己運維,調查問題,Fix bug,會帶來較大的複雜度和成本開支。

GC會導致比較大的毛刺,影響使用者體驗,

使用表格儲存(TableStore)儲存賬號關係

除此之外,阿里雲的表格儲存也屬於有序性的分散式NoSQL資料庫,之前有不少很有名的系統選擇使用表格儲存,在下面一些地方給系統帶來了收益:

單表支援10萬億行+,10PB+的資料量,再快的資料增長速度都不用擔心。

資料按主鍵列排序,保證有序性和可預期性。

單key讀寫延遲在毫秒級別,保證關注,取關的響應時間。

是全託管的分散式NoSQL資料庫服務,無需任何運維。

全部採用C++實現,徹底無GC問題,也就不會由於GC而導致較大的毛刺。

使用表格儲存(TableStore)來儲存賬號關係會是一個比較好的選擇。

接下來看一下Feed訊息的儲存。

儲存Feed訊息

Feed訊息有一個最大的特點:

資料量大,而且在Feed流系統裡面很多時候都會選擇寫擴散(推模式)模式,這時候資料量會再膨脹幾個數量級,所以這裡的資料量很容易達到100TB,甚至PB級別。

除此之外,還有一些其他特點:

資料格式簡單

資料不能丟失,可靠性要求高

自增主鍵功能,保證個人發的Feed的訊息ID在個人發件箱中都是嚴格遞增的,這樣讀取時只需要一個範圍讀取即可。由於個人釋出的Feed併發度很低,這裡用時間戳也能滿足基本需求,但是當應用層佇列堵塞,網路延遲變大或時間回退時,用時間戳還是無法保證嚴格遞增。這裡最好是有自增功能。

成本越低越好

潛在的儲存系統

根據上述這些特徵,最佳的系統應該是具有主鍵自增功能的分散式NoSQL資料庫,但是在開源系統裡面沒有,所以常用的做法有兩種:

關係型資料庫 + 分庫分表

關係型資料庫 + 分散式NoSQL資料庫:其中 關係型資料庫提供主鍵自增功能。

使用關係型資料庫儲存Feed訊息

目前業界有很多使用者選擇了關係係資料庫+ 分庫分表,包括了一些非常著名的Feed流產品,雖然這個架構可以執行起來,但是存在一些問題。

分庫分錶帶來了運維複雜性。

分庫分錶帶來了邏輯層和資料層的極大耦合性。

關係型資料庫,比如開源MySQL資料庫的主鍵自增功能效能差。不管是用MyISAM,還是InnoDB引擎,要保證自增ID嚴格遞增,必須使用表鎖,這個粒度非常大,會嚴重限制併發度,影響效能。

有些使用者覺得關係型資料庫的可靠性高一些,但是關係型資料庫的可靠性一般也就最多6個9,這個可靠性和分散式資料庫完全不在一個層級,要低4到5個級別。

使用TableStore儲存賬號關係

基於上述原因,一些技術公司開始考慮使用表格儲存(TableStore),表格儲存是一個具有自增主鍵功能的分散式NoSQL資料庫,這樣就只需要使用一種系統,除此之外還有以下的考慮:

單表可達10PB,10萬億行。

10個9的SLA保障Feed內容不丟失。

天然分散式資料庫,無需分庫分表

兩種例項型別:高效能例項採用全SSD儲存媒介,提供極佳的讀寫效能。混合儲存例項採用SSD+SATA儲存媒介,提供極低的儲存成本。

主鍵自增功能效能極佳,其他所有系統在做自增功能的時候都需要加鎖,但是表格儲存的主鍵自增功能在寫入自增列行的時候,完全不需要鎖,既不需要表鎖,也不需要行鎖。

從上面看,使用TableStore的話,不管是在功能,效能,擴充套件性還是成本方面都要更加適合一些。

看完推送系統選擇後,我們再來看看推送方案的選擇。

推送方案

我們先來回顧下之前說的Feed流系統最大的特點:

讀寫嚴重不平衡,讀多寫少,一般讀寫比例都在10;1,甚至100:1之上。

除此之外,還有一個方面會被推送方案影響:

釋出, 重新整理Feed時的延時本質上由推送方案決定,其他的任何操作都只能是優化,質量量變,無法質變。

推模式和拉模式對比

在推送方案裡面的,有兩種方案,分別是:

拉方案:也稱為讀擴散。

推方案:也成為寫擴散。

對於拉方案和推方案,他們在很多方面完全相反,在看對比之前有一點要強調下:

對Feed流產品的使用者而言,重新整理Feed流(讀取)時候的延遲敏感度要遠遠大於釋出(寫入)的時候。

如何打造千萬級Feed流系統

推模式的一個副作用

在上面的對比中可以明顯看出來,推模式要遠遠比拉模式更好一些,但是也有一個副作用:

資料會極大膨脹。

針對這個缺點,可以從兩個方面考慮:

目前的儲存價格很低很低了,就以表格儲存為例,容量型例項儲存10TB的資料量,在現在(2017年10月)每年費用是1萬六千元,以後價格會隨著硬體技術升級,軟體效能優化等繼續降低。還有資料量越大價格越便宜。

想省點錢,那繼續可以優化:

對大V採用拉模式,普通使用者使用推模式,這種模式有個缺點,後面會有分析。

對活躍粉絲採用推模式,非活躍粉絲採用拉模式(這種方式可以較好的避免大流量對平臺的衝擊)

適用場景

通過上述兩個方案的對比後,總結下各個方案的適用場景:

拉模式:

很多Feed流產品的第一版會採用這種方案,但很快就會拋棄。

另外,拉模式 + 圖計算 就會是另一番天地,但是這個時候重心就是圖計算了。

推模式:

Feed流系統中最常用、有效的模式;

使用者關係數比較均勻,或者有上限,比如朋友圈;

偏推薦類,同一個Feed對不同使用者價值不同,需要為不同使用者計算分數,比如pinterest。

推拉結合

大部分使用者的賬號關係都是幾百個,但是有個別使用者是1000萬以上,比如微博。

上面瞭解了推送方案,接下來看下推送系統選擇

推送系統

如果要實現一個千萬量級的Feed流產品,那麼推送系統需要具備一些特點:

具備千萬TPS/QPS的能力。

讀寫鏈路延遲敏感,讀寫直接會影響使用者釋出,重新整理Feed流時的延遲,尤其是極其敏感的重新整理時的延遲。

Feed訊息的必達性要求很高。

主鍵自增功能,仍然是保證使用者收件箱中的Feed ID是嚴格遞增的,保證可以通過Scan(上次讀取的最大ID —>MAX)讀取到最新未讀訊息。

最好能為使用者儲存Timeline中所有的Feed。

從上述特點來看,需要的推送系統最好是一個效能極佳,又可靠的有自增功能的NoSQL系統,所以,業內一般如果選擇開源系統的話,會在選擇了關係型資料庫作為儲存系統的基礎上,選擇開源Redis,這樣就能覆蓋上述的幾個特徵,也能保證Feed流系統正常執行起來,但是也會帶來一些其他問題:

純記憶體系統,記憶體價格極高,整體成本就比較高了。

屬於單機系統,為了支援千萬TPS和保證訊息必達性,需要使用cluster和replica模式,結果就是不僅帶來了運維的複雜性,而且帶來了成本的機器增加,成本再次上升。

成本上升了以後,就有架構師開始考慮是否可以節省一些成本,要節省成本只能是減少開源Redis裡面儲存的資料量,一般有兩種做法,這兩種做法都能減少存入Redis中的資料量:

只在開源Redis中儲存Feed ID,不儲存Feed內容。整體資料量會大量減少,但是在讀取的時候需要先讀Feed ID,然後在到儲存系統裡面去讀取Feed內容,網路開銷增長了一倍,而且是序列的,對使用者的重新整理延遲有較大影響。

只對普通使用者或者活躍使用者使用推模式,對大V和非活躍使用者直接使用拉模式。

上述兩個方案雖然可以節省成本,但是是以犧牲使用者體驗為代價的,最終需要在成本和使用者體驗之間權衡。

使用TableStore作為推送系統

除了使用開源系統外,還可以使用阿里雲的表格儲存(TahleStore),有不少使用者選擇TableStore作為推送系統的原因無非下面幾點:

天然分散式,單表可支援千萬級TPS/QPS。

LSM儲存引擎極大優化寫,高效能例項極大優化讀。

寫入成功即保證落盤成功,資料可靠性提供10個9的SLA保障。

磁碟性資料庫,費用比記憶體性的要低幾個量級。

單表可儲存十萬億行以上的資料,價格又低,輕鬆儲存使用者Feed流中的所有Feed資料。

上面說了使用開源Redis和阿里雲TableStore的異同,如果使用開源可以用Redis,如果選擇阿里雲自研NoSQL資料庫,可以使用TableStore。

架構圖

下面我們來看一下使用TableStore的架構圖,這裡為了通用性,選用推拉結合的方式,推模式更加簡單。

如何打造千萬級Feed流系統

儲存

我們先來看中間黑色框中的部分,這部分是使用TableStore的資料,從左往右分別是:

個人頁Timeline:這個是每個使用者的發件箱,也就是自己的個人頁頁面。

關注頁Timeline:這個是每個使用者的收件箱,也就是自己的關注頁頁面,內容都是自己關注人釋出的訊息。

關注列表:儲存賬號關係,比如朋友圈中的好友關係;微博中的關注列表等。

虛擬關注列表:這個主要用來個性化和廣告。

釋出Feed流程

當你釋出一條Feed訊息的時候,流程是這樣的:

1. Feed訊息先進入一個佇列服務。

2. 先從關注列表中讀取到自己的粉絲列表,以及判斷自己是否是大V。

3. 將自己的Feed訊息寫入個人頁Timeline(發件箱)。如果是大V,寫入流程到此就結束了。

4. 如果是普通使用者,還需要將自己的Feed訊息寫給自己的粉絲,如果有100個粉絲,那麼就要寫給100個使用者,包括Feed內容和Feed ID。

5. 第三步和第四步可以合併在一起,使用BatchWriteRow介面一次性將多行資料寫入TableStore。

6. 釋出Feed的流程到此結束。

讀取Feed流流程

當重新整理自己的Feed流的時候,流程是這樣的:

1. 先去讀取自己關注的大V列表

2. 去讀取自己的收件箱,只需要一個GetRange讀取一個範圍即可,範圍起始位置是上次讀取到的最新Feed的ID,結束位置可以使當前時間,也可以是MAX,建議是MAX值。由於之前使用了主鍵自增功能,所以這裡可以使用GetRange讀取。

3. 如果有關注的大V,則再次併發讀取每一個大V的發件箱,如果關注了10個大V,那麼則需要10次訪問。

4. 合併2和3步的結果,然後按時間排序,返回給使用者。

至此,使用推拉結合方式的釋出,讀取Feed流的流程都結束了。

更簡單的推模式

如果只是用推模式了,則會更加簡單:

釋出Feed:

不用區分是否大V,所有使用者的流程都一樣,都是三步。

讀取Feed流:

不需要第一步,也不需要第三步,只需要第二步即可,將之前的2 + N(N是關注的大V個數) 次網路開銷減少為 1 次網路開銷。讀取延時大幅降級。

個性化和定向廣告

個性化和定向廣告是兩種很強烈的產品需求。個性化可以服務好使用者,增大產品競爭力和使用者粘性,而定向廣告可以為產品增加盈利渠道,而且還可以不招來使用者反感,那麼這兩種方式如何實現呢? 在Feeds流裡面這兩種功能的實現方式差不多,我們以定向廣告為例來說明:

1. 通過使用者特徵分析對使用者分類,比如其中有一類是新生類:今年剛上大學的新生。(具體的使用者特徵分析可以依靠TableStore + MaxCompute,這裡就不說了)。

2. 建立一個廣告賬號:新生廣告

3. 讓這些具有新生特徵的使用者虛擬關注新生廣告賬號。使用者看不到這一層關注關係。

4. 從七月份開始就可以通過新生廣告賬號傳送廣告了。

5. 最終,每個使用者可能會有多個特徵,那麼就可能虛擬關注多個廣告賬號。

上面是定向廣告的一種比較簡單的實現方式,其他方式就不再贅述了。

收益

上面我們詳細說了使用TableStore作為儲存和推送系統的架構,接下來我們看看新架構能給我們帶來多大收益。

只使用1種系統,架構、實現簡單。不再需要訪問多個系統,架構,開發,測試,運維都能節省大力人力時間。

TableStore 主鍵自增列功能效能極優。由於架構的不同,不僅不需要表鎖,行鎖也不需要,所以效能要遠遠好於關係型資料庫。

可以儲存所有的Feed。一是系統可以支援儲存所有Feed,二是價格便宜,存的起。

無須將Feed ID和內容分開儲存。價格便宜,也就不需要再分開儲存ID和內容了。

全託管服務,無運維操作,更無需分庫分表。

磁碟型(SSD、Hybrid)資料庫,成本低。

可靠性10個9,資料更可靠,更不易丟失。

大V和普通使用者的切分閾值更高,讀取大V的次數更少,整體延時更低。

一個設計缺陷

如果使用大V/普通使用者的切分方式,大V使用拉模式,普通使用者使用推模式,那麼這種架構就會存在一種很大的風險。

比如某個大V突然發了一個很有話題性的Feed,那麼就有可能導致整個Feed產品中的所有使用者都沒法讀取新內容了,原因是這樣的:

大V傳送Feed訊息。

大V,使用拉模式。

大V的活躍粉絲(使用者群A)開始通過拉模式(架構圖中讀取的步驟3,簡稱讀3)讀取大V的新Feed。

Feed內容太有話題性了,快速傳播。

未登入的大V粉絲(使用者群B)開始登陸產品,登陸進去後自動重新整理,再次通過讀3步驟讀取大V的Feed內容。

非粉絲(使用者群C)去大V的個人頁Timeline裡面去圍觀,再次需要讀取大V個人的Timeline,同讀3.

結果就是,平時正常流量只有使用者群A,結果現在卻是使用者群A + 使用者群B+ 使用者群C,流量增加了好幾倍,甚至幾十倍,導致讀3路徑的服務模組被打到server busy或者機器資源被打滿,導致讀取大V的讀3路徑無法返回請求,如果Feed產品中的使用者都有關注大V,那麼基本上所有使用者都會卡死在讀取大V的讀3路徑上,然後就沒法重新整理了。

所以這裡設計的時候就需要重點關心下面兩點:

單個模組的不可用,不應該阻止整個關鍵的讀Feed流路徑,如果大V的無法讀取,但是普通使用者的要能返回,等服務恢復後,再補齊大V的內容即可。

當模組無法承受這麼大流量的時候,模組不應該完全不可服務,而應該能繼續提供最大的服務能力,超過的拒絕掉。

那麼如何優化呢?

不使用大V/普通使用者的優化方式,使用活躍使用者/非活躍使用者的優化方式。這樣的話,就能把使用者群A和部分使用者群B分流到其他更分散的多個路徑上去。而且,就算讀3路徑不可用,仍然對活躍使用者無任何影響。

完全使用推模式就可以徹底解決這個問題,但是會帶來儲存量增大,大V微博傳送總時間增大,從發給第一個粉絲到發給最後一個粉絲可能要幾分鐘時間(一億粉絲,100萬行每秒,需要100秒),還要為最大併發預留好資源,如果使用表格儲存,因為是雲服務,則不需要考慮預留最大額度資源的問題。

實踐

接下來我們來實現一個訊息廣場的功能。很多App中都有動態或訊息廣場的功能,在訊息廣場中一般有兩個Tab,一個是關注人,一個是廣場,我們這裡重點來看關注人。

要實現的功能如下:

使用者之間可以相互關注

使用者可以釋出新訊息

使用者可以檢視自己釋出的訊息列表

使用者可以檢視自己關注的人的訊息

採取前面的方案:

使用TableStore作為儲存和推送系統

採用Timeline的顯示方式,希望使用者可以認真看每條Feed

採用推模式

角色

接著,我們看看角色和每個角色需要的功能:

傳送者

傳送狀態:add_activity()

接收者

關注:follow()

讀取Feed流:get_activity()

Feed訊息中至少需要包括下面內容:

訊息:

傳送人:actor

型別:verb,比如圖片,視訊,文字

文字文字:message

架構圖

如何打造千萬級Feed流系統

釋出新訊息

介面:add_activity()

實現:

get_range介面呼叫關注列表,返回粉絲列表。

batch_write_row介面將feed內容和ID批量寫入個人頁表(發件箱)和所有粉絲的關注頁表(收件箱),如果量太大,可以多次寫入。或者呼叫非同步batch_write_row介面,目前C++ SDK和JAVA SDK提供非同步介面。

關注

介面:follow()

實現:

put_row介面直接寫入一行資料(關注人,粉絲)到關注列表和粉絲列表(粉絲,關注人)即可。

獲取Feed流訊息

介面:get_activity()

實現:

從客戶端獲取上次讀取到的最新訊息的ID:last_id

使用get_range介面讀取最新的訊息,起始位置是last_id,結束位置是MAX。

如果是讀取個人頁的內容,訪問個人頁表即可。如果是讀取關注頁的內容,訪問關注頁表即可。

計劃

上面展示瞭如何使用表格儲存TableStore的API來實現。這個雖然只用到幾個介面,但是仍然需要學習表格儲存的API和特性,還是有點費時間。

為了更加易用性,我們接下來會提供Feeds流完整解決方案,提供一個LIB,介面直接是add_activity(),follow()和get_activity()類似的介面,使用上會更加簡單和快捷。

擴充套件

前面講述的都是Timeline型別的Feed流型別,但是還有一種Feed流型別比較常見,那就是新聞推薦,圖片分享網站常用的Rank型別。

我們再來回顧下Rank型別擅長的領域:

潛在Feed內容非常多,使用者無法全部看完,也不需要全部看完,那麼需要為使用者選出她最想看的內容,典型的就是圖片分享網站,新聞推薦網站等。

我們先來看一種架構圖:

如何打造千萬級Feed流系統

這種Rank方式比較輕量級,適用於推拉結合的場景。

寫流程基本一樣

讀流程裡面會先讀取所有的Feed內容,這個和Timeline也一樣,Timeline裡面的話,這裡會直接返回給使用者,但是Rank型別需要在一個排序模組裡面,按照某個屬性值排序,然後將所有結果存入一個timeline cache中,並返回分數最高的N個結果,下次讀取的時候再返回[N+1, 2N]的結果。

再來看另外一種:

如何打造千萬級Feed流系統

這種比較重量級,適用於純推模式。

寫流程也和Timeline一樣。

每個使用者有兩個收件箱:

一個是關注頁Timeline,儲存原始的Feed內容,使用者無法直接檢視這個收件箱。

一個是rank timeline,儲存為使用者精選的Feed內容,使用者直接檢視這個收件箱。

寫流程結束後還有一個資料處理的流程。個性化排序系統從原始Feed收件箱中獲取到新的Feed 內容,按照使用者的特徵,Feed的特徵計算出一個分數,每個Feed在不同使用者的Timeline中可能分數不一樣的,計算完成後再排序然後寫入最終的rank timeline。

這種方式可以真正為每個使用者做到“千人千面”。

上述兩種方式是實現Rank的比較簡單,常用的方式。

最後

從上面的內容來看,表格儲存(TableStore)在儲存方面可以支援10PB級,推送方面可以支撐每秒千萬的TPS/QPS,在Feed流系統中可以發揮很大的價值。

目前,已經有不少著名公司在使用表格儲存(TableStore)來構建他們自己的Feed流系統,最終為系統,產品,公司都帶來了不少收益。

相關文章