Pinterest的Feed架構與算法

jopen 9年前發布 | 18K 次閱讀 算法


Pinterest首頁的Feed消息流,最早是按照用戶的關注對象的Pin(類似微博)聚合后按時間進行排序(自然序,類似朋友圈),后來版本 的feed系統放棄了自然序,而是根據一定規則及算法來設計,內部稱之為Smart feed,其算法及架構根據其公開資料整理如下,值得業界做信息流產品的技術架構師參考。

Pinterest每個用戶的首頁feed都是個性化內容。Pinterest系統大約1/3流量都指向feed頁面,因此它是整個系統最關鍵的頁面之一。當工程師開發新版Smart Feed時,如何達到99.99%可用性也是衡量項目是否成功的指標之一。

Pinterest smart feed的主要算法及規則如下

  • 不同來發表來源的Pin按照不同的頻次聚合。
  • 將Pin按照算法及權重有選擇的去除(或延遲加載),質量較低的發表來源不必每次顯示全部,系統可以有選擇的決定哪些立即出現,哪些延遲顯示。Pin的質量都是從當前接收用戶的角度來衡量。
  • Pin排序的邏輯是最好的優先,而不是最新的優先。一些發表來源的Pin可能最新的優先,但另外一些發表來源的可能新的Pin優先級低。

Pinterest Feed如圖所示主要由以下幾部分構成,最左邊是數據來源,最右邊是用戶看到的Pinterest瀑布流。中間的三個服務介紹如下。

Pinterest的Feed架構與算法

Feed worker

Feed worker職責:接收新的pin并根據接收的用戶的不同賦予pin權重并保存。同一個Pin,不同的接收用戶有不同的權重打分。

新的pin主要有三個來源:關注用戶,相關內容,關注關系的感興趣內容。Worker會給每個來源的pin打分之后插入到一個pool里面,每個Pool是針對單個用戶的優先隊列(Priority Queue,即優先級高的內容先出)。

由于Feed Worker按照接收用戶的維度存儲,因此所有的pin進入worker時候已經按照關注關系進行分發(即行內通常說的Feed推模式)。

Feed content generator

Feed content generator負責返回用戶上次訪問后新的pin。Content Generator可以返回前n條或者全部新的pin,用戶獲取過(即瀏覽過)的pin會從pool中刪除。Content Generator可以將多個發表源的pin按照一定規則重新排列,但是不能改變原來的Priority Queue返回的優先順序。即隊列中高優先級的會被優先取出。

Smart feed service

物化視圖用于保存用戶上次feed列表的快照。此服務不需要對feed的重新排序,它將上次返回給用戶的pin按照當時的順序完整保存,由于它屬 于用戶已閱讀過的歷史列表,讀寫較少,因此它可以提供更好的可用性。另外由于可以限制歷史列表的長度,存儲空間可控,因此可以更低成本來增加從庫來提高訪 問的可用性。

Feed依賴content generator來提供新的Pin,如果content generator不可用,服務可以優雅的降級,用戶仍然可以獲取歷史的列表,返回物化存儲的結果。

Pinterest通過以上3個不同的服務,實現了對feed返回內容靈活的控制,每個服務都有自己明確的職責,達到了每個用戶都具備個性化返回內容的目標。

Feed存儲

Pinterest的feed存儲需要解決以下幾個需求:

  • 寫入新發表的feed,由于Pinterest采用的是推模式,這個場景需要面臨需要高的寫入QPS,但用戶能容忍一定的寫入延遲。
  • 獲取首頁的物化feed列表,相對與寫入的QPS要小很多,但是用戶對請求的延遲容忍度低。
  • 刪除feed。

可以采用簡單的設計方法,比如將所有的feed寫入到一個存儲,可以簡單實現訪問、更新及刪除功能。在Pinterest當前的訪問規模有上百T 的數據以及每秒百萬訪問操作。經過綜合評估,選擇使用HBase來實現了上述需求,Pinterest業務場景需要提供非常高的讀寫及更新操 作,HBase同時提供較高的讀寫及更新訪問性能。

用戶發表一個新的Pin時,將Pin分發給他所有的粉絲,他的粉絲可能被shard到所有的HBase region上,因此一個分發操作可能要訪問到多個region,并鎖定每個region的WAL日志,然后進行更新再解鎖。每次的 write/delete/update操作鎖定WAL非常低效,而且很快成為系統的瓶頸。更好的方法是將HBase的操作批量進行,并且可以加大 HBase的吞吐能力,但另外一方面增加了訪問的時延latency,如果是面向用戶請求的操作,訪問時延增大是不能接受的。

為了滿足不同的需求,Pinterest設計使用了雙HBase集群的方法,將數據在不同的階段寫入到不同的HBase集群的方法,請參考圖示。

Pinterest的Feed架構與算法

Zen是一個在HBase基礎上提供圖(Graph)存儲的服務。

SmartFeed Worker將用戶發表的內容分發后通過Zen保存在HBase中,異步處理任務通過PinLater服務來調用。

SmartFeed ContentGenerator負責返回最新的Pin,并進行評分及排序。

當用戶刷新請求自己首頁的feed時,SmartFeed服務從Content Generator和物化存儲的HBase歸并數據返回給用戶,如果生成服務請求超時,則系統仍然可以返回物化存儲的數據給用戶。在后 臺,SmartFeed將物化存儲的數據從左邊的存儲刪除。

在實際的場景中,物化存儲HBase的數據遠遠要比發表池的數據要少,這樣請求的速度會非常快。

Feed的高可用

使用上述設計后,系統的可用性相當于物化存儲HBase的可用性。HBase集群目前存在GC卡頓的風險,還有單點故障region遷移等問題,因此使用單一的HBase集群,可用性很難保證99.99%以上。

為了解決這個問題,在另外一個EC2可用區啟用一個備用集群,任何寫入到主集群的數據將會在數百毫秒內同步到另外一個集群上。當主集群不可用時,可以從備用集群返回用戶請求的數據。通過上述設計,整個系統的可用性達到99.99%以上(不包括寫)。

Pinterest的Feed架構與算法

參考資料

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!