日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spotify如何使用Cassandra实现个性化推荐

發布時間:2024/8/23 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spotify如何使用Cassandra实现个性化推荐 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Spotify我們有超過6000萬的活躍用戶,他們可以訪問超過3000萬首歌曲的龐大曲庫。用戶可以關注成千上萬的藝術家和上百個好友,并創建自己的音樂圖表。在我們的廣告平臺上,用戶還可以通過體驗各種音樂宣傳活動(專輯發行,藝人推廣)發現新的和現有的內容。這些選項增加了用戶的自主權和參與度。目前,用戶在平臺上已創建了超過15億播放列表,并且,僅去年一年就播放了超過70億小時的音樂。

但有時豐富的選擇也讓我們的用戶感到些許困惑。如何從超過10億個播放列表中找到適合鍛煉時聽的播放列表?如何發現與自己品味契合的新專輯?通過在平臺上提供個性化的用戶體驗,我們幫助用戶發現和體驗相關內容。

個性化的用戶體驗包括在不同的場景中學習用戶的喜好和厭惡。一個喜歡金屬類音樂的人在給孩子播放睡前音樂時,可能不想收到金屬類型專輯的公告。這時,給他們推薦一張兒童音樂專輯可能更為貼切。但是這個經驗對另一個不介意在任何情況下接受金屬類型專輯推薦的金屬類型聽眾可能毫無意義。這兩個用戶有相似的聽音樂習慣,但可能有不同偏好。根據他們在不同場景下的偏好,提供在Spotify上的個性化體驗,可以讓他們更加投入。

基于以上對產品的理解,我們著手建立了一個個性化系統,它可以分析實時和歷史數據,分別了解用戶的場景和行為。隨著時間的推移和規模的擴大,我們基于一套靈活的架構建立了自己的個性化技術棧,并且確信我們使用了正確的工具來解決問題。

整體架構

在我們的系統中,使用Kafka收集日志,使用Storm做實時事件處理,使用Crunch在Hadoop上運行批量map-reduce任務,使用Cassandra存儲用戶畫像(user profile)屬性和關于播放列表、藝人等實體的元數據。

下圖中,日志由Kafka producer發出后,運行在不同的服務上,并且把不同類型的事件(例如歌曲完成、廣告展示的投遞)發送到Kafka broker。系統中有兩組Kafka consumer,分別訂閱不同的topic,消費事件:

  • Hadoop Consumer將事件寫入HDFS。之后HDFS上的原始日志會在Crunch中進行處理,去除重復事件,過濾掉不需要的字段,并將記錄轉化為Avro格式。
  • 運行于Storm topology中的Spouts Consumer對事件流做實時計算。
  • 系統中也有其他的Crunch pipeline接收和生成不同實體的元數據(類型、節奏等)。這些記錄存儲在HDFS中,并使用Crunch導出到Cassandra,以便在Storm pipeline中進行實時查找。我們將存儲實體元數據的Cassandra集群稱為實體元數據存儲(EMS)。

    Storm pipeline處理來自Kafka的原始日志事件,過濾掉不需要的事件,用從EMS獲取的元數據裝飾實體,按用戶分組,并通過某種聚合和派生的算法組合來確定用戶級屬性。合并后的這些用戶屬性描述了用戶畫像,它們存儲在Cassandra集群中,我們稱之為用戶畫像存儲(UPS)。

    為何Cassandra適合?

    由于UPS是我們個性化系統的核心,在本文中,我們將詳細說明為什么選擇Cassandra作為存儲。當我們開始為UPS購買不同的存儲解決方案時,我們希望有一個解決方案可以:

    • 水平擴展
    • 支持復制—最好跨站點
    • 低延遲。可以為此犧牲一致性,因為我們不執行事務
    • 能夠支持Crunch的批量數據寫入和Storm的流數據寫入
    • 能為實體元數據的不同用例建模不同的數據模式,因為我們不想為EMS開發另一個解決方案,這會增加我們的運營成本。

    我們考慮了在Spotify常用到的各種解決方案,如Memcached、Sparkey和Cassandra。只有Cassandra符合所有這些要求。

    水平擴展

    Cassandra隨著集群中節點數量的增加而擴展的能力得到了高度的宣傳,并且有很好的文檔支持,因此我們相信它對于我們的場景來說是一個很好的選擇。我們的項目從相對較小的數據量開始,但現在已經從幾GB增長到100 GB以上(譯者注:原文如此,可能是筆誤?歡迎有了解內情的讀者釋疑)。在這一過程中,我們很容易通過增加集群中的節點數量來擴展存儲容量;例如,我們最近將集群的規模增加了一倍,并觀察到延遲(中位數和99分位)幾乎減少了一半。

    此外,Cassandra的復制和可用性特性也提供了巨大的幫助。雖然我們不幸遇到了一些由于GC或硬件問題導致節點崩潰的情況,但是我們訪問Cassandra集群的服務幾乎沒有受到影響,因為所有數據都在其他節點上可用,而且客戶端驅動程序足夠智能,可以透明地進行failover。

    跨節點復制

    Spotify在全球近60個國家提供服務。我們的后端服務運行在北美的兩個數據中心和歐洲的兩個數據中心。為了確保在任何一個數據中心發生故障時,我們的個性化系統仍能為用戶提供服務,我們必須能夠在至少兩個數據中心存儲數據。

    我們目前在個性化集群中使用NetworkReplicationStrategy在歐盟數據中心和北美數據中心之間復制數據。這允許用戶訪問離自己最近的Spotify數據中心中的數據,并提供如上所述的冗余功能。

    雖然我們還沒有發生任何導致整個數據中心中的整個集群宕機的事件,但我們已經執行了從一個數據中心到另一個數據中心的用戶流量遷移測試,Cassandra完美地處理了從一個站點處理來自兩個站點的請求所帶來的流量增長。

    低延遲 可調一致性

    考慮到Spotify的用戶基數,實時計算用戶聽音樂的個性化數據會產生大量數據存儲到數據庫中。除了希望查詢能夠快速讀取這些數據外,存儲數據寫入路徑的低延遲對我們來說也是很重要的。

    由于Cassandra中的寫入會存儲在append-only的結構中,所以寫操作通常非常快。實際上,在我們個性化推薦中使用的Cassandra,寫操作通常比讀操作快一個數量級。

    由于實時計算的個性化數據本質上不是事務性的,并且丟失的數據很容易在幾分鐘內從用戶的聽音樂流中替換為新數據,我們可以調整寫和讀操作的一致性級別,以犧牲一致性,從而降低延遲(在操作成功之前不要等待所有副本響應)。

    Bulkload數據寫入

    在Spotify,我們對Hadoop和HDFS進行了大量投入,幾乎所有關于用戶的見解都來自于在歷史數據上運行作業。

    Cassandra提供了從其他數據源(如HDFS)批量導入數據的方式,可以構建整個SSTable,然后將SSTable通過streaming傳輸到集群中。比起發送數百萬條或更多條INSERT語句,這種方式要簡單得多,速度更快,效率更高。

    針對從HDFS讀取數據并bulkload寫入SSTable,Spotify開源了一個名為hdfs2cass的工具。

    雖然此功能的可用性并不影響我們使用Cassandra進行個性化推薦的決定,但它使我們將HDFS中的數據集成到Cassandra中變得非常簡單和易于維護。

    Cassandra數據模型

    自開始這個項目以來,我們在Cassandra中個性化數據的數據模型經歷了一些演變。

    最初,我們認為我們應該有兩個表——一個用于用戶屬性(鍵值對),一個用于“實體”(如藝術家、曲目、播放列表等)的類似屬性集。前者只包含帶有TTL的短期數據,而后者則是寫入不頻繁的相對靜態的數據。

    將鍵值對存儲為單獨的CQL行而不是試圖為每個“屬性”創建一個CQL列(并且每個用戶有一個CQL行)的動機是允許生成此數據的服務和批處理作業獨立于使用數據的服務。使用這種方法,當數據的生產者需要增加一個新的“屬性”時,消費服務不需要做任何改動,因為這個服務只是查詢給定用戶的所有鍵值對。

    這些表的結構如下:

    CREATE TABLE entitymetadata (entityid text,featurename text,featurevalue text,PRIMARY KEY (entityid, featurekey) )CREATE TABLE userprofilelatest (userid text,featurename text,featurevalue text,PRIMARY KEY (userid, featurename) )

    在最初的原型階段,這種結構工作得很好,但是我們很快遇到了一些問題,這就需要重新考慮關于“實體”的元數據的結構:

  • entitymetadata列的結構意味著我們可以很容易地添加新類型的entitymetadata,但是如果我們嘗試了一種新類型的數據后發現它沒有用,不再需要時,這些featurename沒法刪除。
  • 一些實體元數據類型不能自然地表示為字符串,相反,使用CQL的某個集合類型更容易存儲。例如,在某些情況下,將值表示為list更為自然,因為這個值是有順序的事物列表;或者另一些情況下使用map來存儲實體值的排序。
  • 我們放棄了使用一個表來存儲以(entityid,featurename)為鍵的所有值的做法,改為采用了為每個“featurename”創建一個表的方法,這些值使用適當的CQL類型。例如:

    CREATE TABLE playlisttag (entityid text,featurevalue list<text>,PRIMARY KEY (entityid) )

    用適當的CQL類型而不是全部用字符串表示,意味著我們不再需要對如何將非文本的數據表示為文本(上面提到的第2點)做出任何笨拙的決定,并且我們可以很容易地刪除那些實驗之后決定不再用的表。從操作性的角度來看,這也允許我們檢查每個“特性”的讀寫操作的數量。

    截至2014年底,我們有近12個此類數據的表,并且發現比起把所有數據塊塞進一個表,使用這些表要容易得多。

    在Cassandra中有了DateTieredCompactionStrategy之后(我們自豪地說,這是Spotify同事對Cassandra項目的貢獻),用戶數據表也經歷了類似的演變。

    我們對userprofilelatency表(譯者注:原文如此,猜測可能是userprofilelatest的筆誤)的讀寫延遲不滿意,認為DTCS可能非常適合我們的用例,因為所有這些數據都是面向時間戳的,并且具有較短的ttl,因此我們嘗試將“userprofilelatest”表的STCS改為DTCS以改善延遲。

    在開始進行更改之前,我們使用nodetool記錄了SSTablesPerRead的直方圖,來作為我們更改前的狀態,以便和修改后的效果做比較。當時記錄的一個直方圖如下:

    SSTables per Read1 sstables: 1267332 sstables: 1114143 sstables: 1413854 sstables: 1819745 sstables: 2229216 sstables: 2205817 sstables: 2173148 sstables: 21629610 sstables: 380294

    注意,直方圖相對平坦,這意味著大量的讀取請求都需要訪問多個sstable,而且往下看會發現這些數字實際上也在增加。

    在檢查了直方圖之后,我們知道延遲很可能是由每次讀操作所訪問的sstable絕對數量引起的,減少延遲的關鍵在于減少每次讀取必須檢查的sstable數量。

    最初,啟用DTCS后的結果并不樂觀,但這并不是因為compaction策略本身的任何問題,而是因為我們把短期TTL數據和沒有TTL的用戶長期“靜態”數據混合在一個表里面。

    為了測試如果表中的所有行都有TTL,DTCS是否能夠更好地處理TTL行,我們把這個表分成了兩個表,一個表用于沒有TTL的“靜態”行,一個表用于帶有TTL的行。

    在小心遷移使用這個數據的后端服務(首先將服務更改為同時從新舊表讀取數據,然后在數據遷移到新表完成后僅從新表讀取)后,我們的實驗是成功的:對只有TTL行的表開啟DTCS后生成了SSTablesPerRead直方圖,其中只需訪問1個SSTable的讀操作與訪問2個SSTable的讀操作的比例大約在6:1到12:1之間(取決于主機)。

    下面是這次改動之后nodetool cfhistograms輸出的一個例子:

    SSTables per Read1 sstables: 41785142 sstables: 3025493 sstables: 2547604 sstables: 1976955 sstables: 154961...

    或者如下圖:

    在解決userprofileLatest表延遲問題的過程中,我們學到了一些關于Cassandra的寶貴經驗:

    • DTCS非常適合時間序列,特別是當所有行都有TTL時(SizeTieredCompactionStrategy不適合這種類型的數據)
  • 但是,如果把有TTL的行和沒有TTL的行混在一個表里面,DTCS表現不是很好,因此不要以這種方式混合數據
  • 對于帶有DTCS/TTL數據的表,我們將gc_grace_period設置為0,并有效地禁用讀修復,因為我們不需要它們:TTL比gc grace period要短。
    • nodetool cfhistograms和每次讀取所訪問的SSTables數量可能是了解表延遲背后原因的最佳資源,因此請確保經常測量它,并將其導入圖形系統以觀察隨時間的變化。

    通過對我們的數據模型和Cassandra配置進行一些調整,我們成功地構建了一個健壯的存儲層,用于向多個后端服務提供個性化數據。在對配置進行微調之后,在Cassandra集群的后續運行中我們幾乎沒做過任何其他運維操作。我們在儀表板中展示了一組集群和數據集的指標,并配置了警報,當指標開始朝錯誤方向發展時會觸發。這有助于我們被動地跟蹤集群的健康狀況。除了把集群的大小增加一倍以適應新增的負載之外,我們還沒做過太多的集群維護。而即使是集群倍增這部分也相當簡單和無縫,值得再發一篇文章來解釋所有細節。

    總的來說,我們非常滿意Cassandra作為滿足我們所有個性化推薦需求的解決方案,并相信Cassandra可以隨著我們不斷增長的用戶基數持續擴展,提供個性化體驗。

    感謝PlanetCassandra鼓勵我們在blog上分享Cassandra的經驗。


    原文鏈接
    本文為云棲社區原創內容,未經允許不得轉載。

    總結

    以上是生活随笔為你收集整理的Spotify如何使用Cassandra实现个性化推荐的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲一区二区三区免费观看 | 久久毛片 | 中文字幕丰满孑伦无码专区 | 久久影院午夜理论片无码 | 精品日本一区二区三区 | 国产一区二区三区日韩 | 国产日韩精品视频 | 亚洲综合久 | 日日日日干 | 婷婷五月综合缴情在线视频 | 亚洲片国产一区一级在线观看 | 欧美日韩成人在线视频 | 成人在线免费视频播放 | 国产femdom调教7777 | 国产精品二区一区二区aⅴ 一卡二卡三卡在线观看 | 日韩午夜激情 | 精品乱子伦一区二区三区 | 久久久999精品 | 一级肉体全黄裸片中国 | 日韩成人激情 | 亚洲图片一区二区三区 | 日本高清视频网站 | 成人在线影视 | 视频一区国产精品 | 国产成人aaa | 亚洲淫 | 艳妇乳肉豪妇荡乳av无码福利 | 操丰满女人 | 在线综合网 | 国产白丝精品91爽爽久久 | 温柔女教师在线观看 | 操比网站 | 国产色爽 | 黄色图片小说 | 激情天堂网 | 国产福利片在线观看 | 日本精品一区二区三区四区的功能 | av网址免费在线观看 | 中文字幕亚洲一区 | www.呦呦| 人人插人人搞 | 999久久久免费精品国产 | 一级特黄bbbbb免费观看 | 无码av免费精品一区二区三区 | 成人h视频在线观看 | 蜜桃在线一区 | 日韩高清成人 | 亚洲图片欧美色图 | 乱子伦一区| 性xxxxbbbb | 综合精品视频 | 国产美女视频一区 | 国产绿帽刺激高潮对白 | 性猛交富婆╳xxx乱大交天津 | 欧美最猛黑人xxxx | 99热中文| 91香蕉久久 | 五月天激情社区 | www.伊人 | 久久亚洲一区 | 99色在线视频 | 日韩影院一区二区 | 国产传媒在线 | 男女做爰猛烈刺激 | 大尺度舌吻呻吟声 | a级片国产| 国产一区二区免费在线 | 少妇第一次交换又紧又爽 | 欧美丰满老熟妇xxxxx性 | 色淫湿视频 | 国产极品美女高潮无套嗷嗷叫酒店 | 成年人精品视频 | 四虎影视精品 | 小镇姑娘高清播放视频 | 欧美福利在线视频 | 黑巨茎大战欧美白妞 | 四虎国产在线观看 | 99久久99久久精品免费看蜜桃 | 亚洲精选在线 | 少妇光屁股影院 | 日韩欧美综合在线 | 影音先锋美女 | 国产精品不卡一区 | 白白色视频在线 | 波多野结衣绝顶大高潮 | 激情中文网 | 美女超碰在线 | 亚洲成人无码久久 | 黄色小视频大全 | 欧美黄色短视频 | 99精品欧美一区二区三区 | 国产在线视频第一页 | 国产麻豆乱码精品一区二区三区 | 羞羞影院体验区 | 亚洲中文字幕一区二区 | 一区二区精品久久 | 大桥未久av在线 | 亚洲中文字幕一区二区在线观看 | 国产中文字幕精品 |