0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于Erlang語言的視頻相似推薦系統(tǒng)

WpOh_rgznai100 ? 來源:lq ? 2019-07-18 10:27 ? 次閱讀

【導語】:作者在上一篇文章《基于內容的推薦算法》中介紹了基于內容的推薦算法的實現(xiàn)原理。在本篇文章中作者會介紹一個具體的基于內容的推薦算法的實現(xiàn)案例。該案例是作者在2015年基于Erlang語言開發(fā)的相似視頻推薦系統(tǒng),從開發(fā)完成就一直在公司多個產品線中使用,該算法目前已經使用了四年。

本文會從視頻相似推薦系統(tǒng)簡介、算法原理及實現(xiàn)細節(jié)、問題與難點、為什么用Erlang語言開發(fā)、系統(tǒng)架構與工程實現(xiàn)、核心亮點、未來優(yōu)化方向、個人收獲與感悟等8個方面來講解。

通過學習本文讀者可以深入了解基于向量空間模型的相似推薦算法原理及實現(xiàn)細節(jié)、對Erlang語言特性也會有基本的了解、同時對實現(xiàn)一個簡單高效的Master/Slaver架構的分布式計算框架的原理和工程細節(jié)有基本的概念。

視頻相似推薦系統(tǒng)簡介

作者所在公司從事智能電視/智能機頂盒上的視頻業(yè)務(主要產品是電視貓),由于智能電視上主要依賴遙控器操作,所以操控不是很方便,產品對推薦系統(tǒng)的依賴會更大。而相似推薦就是為每個視頻關聯(lián)一組相似(或者有一定關聯(lián)關系)的視頻。

具體產品形態(tài)見下圖1和圖2:

圖1:電視貓電影詳情頁的相似影片

圖2:電視貓奇趣短視頻的關聯(lián)推薦

我們的產品包括長視頻(電影、電視劇、動漫、少兒、紀錄片、綜藝6種)和短視頻(資訊、奇趣、游戲、體育、戲曲、音樂6種)兩大類,我們需要為每類視頻類型的節(jié)目關聯(lián)一組相似推薦(在同一類別中做推薦,電影的相關推薦只能是電影、體育的關聯(lián)推薦是體育等)。

具體怎么計算相似呢?我們是基于視頻的metadata信息來計算兩個視頻之間的相似度,利用相似度從高到低來排序,獲取某個視頻最相似的topN作為關聯(lián)或者相似推薦。

這里提一下,雖然長視頻和短視頻采用同一套算法體系,但是由于視頻類型不一樣,前端的產品形態(tài)是不一樣的。由于短視頻單片時長較短,一般幾分鐘就播完了,所以短視頻的關聯(lián)推薦采用的是信息流的方式,播放原視頻,它關聯(lián)的視頻會作為信息流播放,這樣整體用戶體驗會好很多(這就是上面圖1和圖2雖然都是相似推薦但是產品形態(tài)不一樣的原因)。

相信通過上面的介紹,大家對視頻相似推薦的產品形態(tài)比較清楚了。在下面一節(jié),我們來講解具體的算法實現(xiàn)細節(jié)。

算法原理及具體實現(xiàn)細節(jié)

視頻行業(yè)一般是具備結構化信息的,一般視頻公司會有CMS(Content Management System,內容管理系統(tǒng)),該系統(tǒng)一般會包含媒資庫,媒資庫中針對每個節(jié)目會有標題、演職員、導演、標簽、評分、地域等維度數(shù)據(jù),這類數(shù)據(jù)一般存放在關系型數(shù)據(jù)庫(如MySQL)中。

這類數(shù)據(jù),我們可以將一個字段(也是一個特征)作為向量的一個維度,這時用向量表示視頻,每個維度的值不一定是數(shù)值,但是形式還是向量化的形式,即所謂的向量空間模型(Vector Space Model,簡稱VSM)。這時我們可以通過如下的方式計算兩個視頻之間的相似度。

假設兩個視頻的向量表示分別為:

?? ??

?? ? ?

這時這兩個視頻的相似度可以采用如下公式計算:

其中代表的是向量的兩個分量?之間的相似度??梢圆捎肑acard相似度等各種方法計算兩個分量之間的相似度。上面公式中還可以針對不同的分量采用不同的權重策略,見下面公式,其中?是第t個分量(特征)的權重,具體權重的數(shù)值可以根據(jù)對業(yè)務的理解來人工設置,或者利用機器學習算法來訓練學習得到。

有了上面的計算公式,我們就知道該怎么計算兩個視頻的相似度了。但是上面公式中未解決的問題是,對于某一個具體的維度,我們該怎么計算相似度呢?

上式中的?、???分別代表兩個節(jié)目第 i 個維度的值,可以是數(shù)值、字符串等。下面我們列舉一下針對不同的分量怎么計算分量之間的相似度。

年代

假設兩個視頻???的年代分別是???和???,計算在年代這個維度的相似度可以采用如下分段函數(shù)表示:

其中(1)、(2)是剔除掉無效的??值,(3)是給出的當???在0到2020年之間的一個計算公式,??值越大,最終的相似度越大。這里相似度與??無關(所以嚴格來說,不叫做相似度,而是貢獻度,下面類似,不再說明,直接用貢獻度來描述)在其他條件相同的情況下,越是近期拍攝的視頻權重越大。

標題

假設兩個視頻?, ??和??分別是這兩個視頻的標題,首先我們可以通過分詞或者關鍵詞提取算法將 ???和??提取關鍵詞得到對應的關鍵詞,假設如下:

?? ? ?

?? ? ?

其中?分別是?提取關鍵詞后的集合,那么我們可以用如下Jacard相似度來計算??之間的相似度:

?? ? ?

這里涉及到很多NLP方面的技術和領域知識。首先我們需要有視頻行業(yè)相關語料,才能夠保證分詞準確,另外標題可能是雜亂無章的,比如很多電影標題中包含粵語版、國語版、新傳、第三季等對相似度價值不大的詞或者詞組,這些都需要借助規(guī)則或者NLP技術做預處理,才能得到較好的關鍵詞提取效果,最終才會有較好的相似度計算效果。

標簽

對于標簽,可以采用跟上面標題一樣的計算方法,因為標題提取關鍵詞后的每個關鍵詞可以看成是一個標簽。這里不再細說怎么計算了。

地域

假設兩個視頻??, ??和??分別是這兩個視頻的出品地,我們可以用如下公式來計算這兩個視頻在地域維度的相似度。

這個公式可以考慮得更復雜一點,將地區(qū)按照語言、地域等分成幾類,比如北美、東歐、東南亞等,當兩個視頻的地域完全一樣時相似度為1,當兩個視頻在同一個地區(qū)分類內,相似度為0.5(或者其他大于0小于1的值,根據(jù)業(yè)務經驗開發(fā)人員自己定義),否則為0,這樣會更加精確合理。

豆瓣評分

假設兩個視頻?,??和??分別是這兩個視頻的豆瓣評分(豆瓣評分是0到10之間),下面公式給出視頻?? 在豆瓣評分這個維度的貢獻度,評分越高,貢獻度越大。

是否獲獎

假設兩個視頻?,?? 和??分別是這兩個視頻所獲的獎項,那么可以簡單用下面公式來計算視頻?? 在獲獎這個維度上的貢獻,當然計算公式可以更加復雜,對不同獎項區(qū)別對待,級別更高的獎項可以給出更高的貢獻度。

導演與演員

通常情況下,視頻一般只有一個導演,導演的相似度可以類似地域一樣的方法計算。而演職員可以采用跟標簽類似的方法計算相似度。

上面給出了幾個內容維度怎么計算兩個視頻在該維度的相似度(或者貢獻度),我們在實際項目中用到的維度比這個更多,但是計算原理類似,這里不再一一列舉。另外,具體的計算和處理邏輯也會更復雜,比如對于標簽相似度,標簽之間是有相似關系的,比如驚悚和恐怖,它們是相似的。上面方法沒有考慮到標簽之間的這種相似關系而是將他們看成不同的標簽,計算相似性多少有點簡單。

實際上,我們項目中用到了數(shù)學中等價類的思想,將很相似的標簽看成是同一類的,在同一類的標簽之間是有相似度的,這樣如果一個電影的標簽是恐怖,另外一個電影的標簽是驚悚,按照上面的計算方法相似度是0,而按照我們等價類的思路,相似度是大于0的。同時,對于某些類別的視頻我們加了很多規(guī)則性的東西,更好地適應不同類別內容的相似計算。像這類提升效果的處理還有很多,這里不再細說。

問題與難點

該項目最早(2012年底)是采用Java來開發(fā)的,寫一個單機程序,當時視頻量還比較少,也沒有這么多視頻類別,基本可以支撐,當后面加入越來越多的視頻類別,每類視頻數(shù)量也越來越多時,單機計算的性能就出現(xiàn)瓶頸了。

當時采用的應對方案是將視頻按照類別分成幾組,每一組采用一個Java線程計算,雖然某種程度上可以做到并行計算,但是每個視頻類型的數(shù)量及增長速度是不一樣的,人工按照類型拆開分布不夠均勻,問題比較多。

回顧老的設計面臨的問題,我們來總結一下,基于該算法的相似視頻推薦主要難點有如下幾個:

數(shù)據(jù)量大,增速快

前面講到我們長短視頻加起來大概有12個類別,類別多,總量有幾百萬條視頻。對于短視頻來說,特別是資訊、體育等,每天都有大量(萬級)新增的節(jié)目。

第一次全量計算所有節(jié)目的相似度時,由于需要計算的節(jié)目太多,必須采用分布式計算,否則計算太慢,單機可能要花幾個月時間才能完全算完。

需要實時計算

在我們的APP上,短視頻一般按照時間排列,新的短視頻放在最前面,用戶更容易看到。所以對于新增的視頻節(jié)目,我們需要實時計算出相似的視頻,否則只能用默認推薦頂替相似推薦,效果肯定不會太好。

計算與某個視頻最相似的視頻需要遍歷所有視頻

我們一般只關聯(lián)推薦同一大類的視頻,但是各個類別數(shù)量是極不均衡的,電影1-2萬部,資訊大概有上百萬。在我們?yōu)槟硞€資訊計算與它最相似的N個資訊時,我們需要遍歷所有其他的資訊才能找到與它最相似的N個,怎么設計這個遍歷過程對計算時間有很大影響。

更新已經計算的視頻的相似度

對于新入庫的視頻A,我們需要計算它的關聯(lián)推薦,同時,對于某個已經計算好的視頻B,如果新加入的視頻A與B的相似度高于B原來計算好的topN相似的某個視頻的相似度,這時需要更新B的相似度列表,將A添加進去,同時刪除原來B的相似列表中相似度最低的視頻。每個新視頻的加入都可能影響很多已經計算過相似度的視頻,怎么在短時間內快捷地查找出這類需要更新相似度列表的視頻也是一個挑戰(zhàn)。

上面我們對相似視頻推薦的算法原理及難點做了比較細致的講解。為了實現(xiàn)這些算法和克服難點,我們基于Erlang語言完美地解決了這些問題,在講怎么利用Erlang語言來從工程上實現(xiàn)上面的算法之前,我們先簡單對Erlang語言做一個初略的介紹,方便讀者更好地理解后續(xù)算法的架構和工程實現(xiàn)原理。

為什么要用Erlang語言開發(fā)

Erlang語言簡介

Erlang是一種通用的面向并發(fā)的編程語言,它由瑞典電信設備制造商愛立信所轄的CS-Lab開發(fā),目的是創(chuàng)造一種可以應對大規(guī)模并發(fā)事件的編程語言和運行環(huán)境。Erlang問世于1987年,經過十年的發(fā)展,于1998年發(fā)布開源版本。Erlang是運行于虛擬機的解釋性語言。在編程范型上,Erlang屬于多重范型編程語言,涵蓋函數(shù)式、并發(fā)式及分布式。

Erlang是一個結構化、動態(tài)類型編程語言,內建并行計算支持。最初是由愛立信專門為通信應用設計的,比如控制交換機或者變換協(xié)議等,因此非常適合于構建分布式、實時并行計算系統(tǒng)。使用Erlang編寫出的應用程序運行時通常由成千上萬個輕量級進程組成,并通過消息傳遞相互通訊。進程間上下文切換對于Erlang來說非常簡單,比起C程序的線程切換要高效得多。

Erlang語言的特性

Erlang語言雖然開發(fā)于上世紀80年代,但是很多思想是非常超前的,在當前云計算時代具有非常實用的價值,算是在多如牛毛的編程語言大軍中獨樹一幟。這些特性也是我選擇利用Erlang語言開發(fā)相似視頻推薦系統(tǒng)的主要原因之一。

下面我們列舉一些Erlang語言的主要特性:

(1) 函數(shù)式編程及部分語法特性

Erlang是一個函數(shù)式編程語言,即可以將函數(shù)作為參數(shù)傳入別的的函數(shù),并且可以作為函數(shù)的返回值。

Erlang語法也比較特殊,通過遞歸來實現(xiàn)迭代邏輯,沒有其他語言的while和for循環(huán)結構。Erlang的變量跟數(shù)學中類似,只能單次賦值,不可重復賦不同值。Erlang的模式匹配能力也非常強大。Erlang內置了很多數(shù)據(jù)類型及操作函數(shù),輔助更好地進行函數(shù)式編程。

(2) 并發(fā)模型

Erlang是一個高并發(fā)語言,天生支持高并發(fā),Erlang基于Actor的并發(fā)編程模型,進程間通信通過消息傳遞進行,高效自然可靠。Erlang語言將并發(fā)模式作為自己的核心特性,非常方便構建分布式處理邏輯,從一開始設計之初就充分利用多核處理器性能,非常適合在現(xiàn)代服務器上構建分布式應用。

(3) 跨平臺

Erlang語言與java類似,采用虛擬機來解釋執(zhí)行代碼,Erlang的beam虛擬機負責對代碼進行解釋執(zhí)行,因此具備跨平臺特性,一次編譯到處運行。

(3) 錯誤處理

Erlang是一個高容錯的編程框架,它對錯誤處理有兩個設計哲學:讓另外一個程序來解決錯誤,如果出錯就讓程序崩潰并重新啟動。第一個設計哲學將錯誤”外包“給另外一個專門的程序監(jiān)控和處理,這樣原來的程序將核心放到處理邏輯上,這個監(jiān)控程序可以放在另外一臺機器上,如果原來程序所在機器掛了,監(jiān)控程序也可以發(fā)現(xiàn)問題。

基于第二個設計哲學,既然處理邏輯和處理錯誤的程序分離了,如果處理邏輯的程序掛了(一般也是遇到偶發(fā)的情況或者傳入非法參數(shù)等原因掛掉),處理錯誤的程序就可以讓它重新啟動,這樣系統(tǒng)又可以正常運行了。這個哲學跟我們熟知的重啟可以解決90%以上問題不謀而合。

(4) OTP框架

OTP 是包裝在Erlang中的一組庫程序。OTP構成Erlang的行為機制(behaviors),用于編寫服務器、有限狀態(tài)機、事件管理器。不僅如此,OTP的應用行為(the application behavior)允許程序員把寫好的Erlang代碼打包成一個單獨的應用程序;監(jiān)測行為(the supervisor behavior )允許程序員創(chuàng)建樹狀結構的進程依賴鏈,使得某個進程死后,它的監(jiān)控進程(父進程)會重新啟動它而復活。

OTP提供大量通用的庫程序,可以輕松創(chuàng)建具有高度容錯、熱機換碼等功能的高質量高效的程序。你可以通過OTP獲得如下好處:

a 通用服務器、有限狀態(tài)機、事件管理器;

b 標準化應用程序結構;

c 代碼熱機更換;

d 監(jiān)測樹行為機制,讓你的進程永不”罷工“。

OTP是在Erlang之上構建系統(tǒng)平臺的標準方式。大型Erlang項目,如ejabberd, CouchDB等,都是基于OTP開發(fā)的。我們的視頻推薦系統(tǒng)也大量利用OTP的各種行為機制,這樣只需要實現(xiàn)核心的接口,進程間的調用、監(jiān)控這些能力行為機制很容易幫我們做到。

(5) 內嵌的Mnesia數(shù)據(jù)庫

Mnesia是內嵌入Erlang的一款容錯的、分布式可拓展的交易型數(shù)據(jù)庫,數(shù)據(jù)按照表來組織,類似于關系型數(shù)據(jù)庫,數(shù)據(jù)可以選擇存在內存或者磁盤中,并且有一套自己的非常方便的查詢語言,可以對數(shù)據(jù)進行方便快捷的讀寫查詢等操作。

為什么選擇Erlang語言來開發(fā)相似視頻推薦系統(tǒng)

有了上面對Erlang語言的簡單介紹,我們在這里簡單介紹一下該項目采用Erlang語言來開發(fā)的主要原因:

(1) Erlang語言有比較牛的互聯(lián)網(wǎng)應用

大家耳熟能詳?shù)幕ヂ?lián)網(wǎng)軟件,如CouchBase、CouchDB(apache基金會上的一款文檔型數(shù)據(jù)庫,類似MongoDB),RabbitMQ(消息隊列中間件),還有基于XMPP協(xié)議的IM開源軟件ejabberd等非常流行的軟件都是基于Erlang語言開發(fā)的,它們在工業(yè)界有大量應用案例。

另外大家可能知道whatsApp背后只有50多位工程師支撐近5億的月活用戶規(guī)模,在2014年被Facebook以190億美元收購。而該公司背后用到的編程語言正是Erlang。當時,作者看到這個消息時是非常震驚的,對Erlang語言越發(fā)佩服了。

(2) Erlang語言的幾個特性非常適合該項目

前面對Erlang語言的特性做了簡單描述,這些特性是構建相似視頻推薦系統(tǒng)的核心基礎,我們在這里重點講一下對我們開發(fā)該系統(tǒng)非常重要的一些特性。

Erlang屏蔽了跨服務器交互的細節(jié),內嵌了跨服務器訪問的rpc及網(wǎng)絡交換函數(shù),跨服務器交互跟與本地交互基本一樣,所以非常適合開發(fā)分布式程序,能夠快速擴展。

Erlang自帶非常多的數(shù)據(jù)處理函數(shù),方便對Set、List、Map、字符串等結構的各類操作。Erlang包含ETS、DETS等key-value的分布式數(shù)據(jù)結構以及嵌入式數(shù)據(jù)庫Mnesia,非常方便對數(shù)據(jù)進行讀寫等操作。

Erlang的OTP框架和錯誤處理機制也是非常的強大,適合開發(fā)穩(wěn)定高效的應用程序。

正是Erlang有這些成功的軟件產品、優(yōu)秀的應用案例及非常有意思的特性,讓作者對Erlang崇拜不已,躍躍欲試,最終決定采用Erlang來開發(fā)相似視頻推薦系統(tǒng)。對Erlang語言有興趣的讀者可以看參考文獻2,Erlang的作者寫的一本全面介紹Erlang編程的書,非常值得一讀。

系統(tǒng)架構與工程實現(xiàn)

前面對相似視頻的算法實現(xiàn)細節(jié)及Erlang的特性做了完整的介紹,在本節(jié)我們就來詳細講解怎么基于Erlang的一些特性從工程上實現(xiàn)一個高效的分布式的Master/Slaver架構的相似視頻推薦系統(tǒng)。

首先我們給出相似視頻推薦的架構圖(見下面圖3),再針對每個模塊詳細說明實現(xiàn)的細節(jié)。

圖3:基于Erlang語言的相似視頻推薦架構圖

另外,整個項目的工程目錄如下圖,這里簡單解釋一下:

conf是配置文件相關目錄,doc是文檔相關目錄,ebin是編譯文件目錄,log是日志目錄,Mnesia.helios@Platform-recommended-couchbase11是Mnesia數(shù)據(jù)存儲目錄,out是輸出相關目錄,RelevanceRecommend.* 、similarity_computing.app是工程啟動及配置相關文件,src是源碼。

圖4:基于Erlang語言的相似視頻推薦工程目錄結構

相似視頻推薦采用主流的Master/Slaver架構,主要包括Master、Slaver、Riak Cluster、Cowboy server 4個核心部分,其中Master、Slaver是整個相似視頻推薦算法的核心。Master主要負責任務的分配、跟Slaver保持聯(lián)系、并且從MySQL中將metadata同步到Mnesia中,而Slaver主要負責相似度計算,計算完后將推薦結果插入Riak集群中。我們在下面分別介紹這4個模塊的核心功能和實現(xiàn)細節(jié)。

Master節(jié)點模塊與功能

Master節(jié)點主要負責任務分派,數(shù)據(jù)同步,處理節(jié)點加入及退出等異常情況。Master包含4個主要組件,如上圖,各個組件的功能如下:

(1) data sync模塊

該模塊負責將需要計算相似性的視頻從MySQL(媒資庫)同步到Slaver的Mnesia集群中,Slaver計算時直接從本地Mnesia讀取數(shù)據(jù)來進行相似計算。由于需要參與計算的字段是較少的(媒資庫字段很多,我們只選擇同步對計算相似度有價值的字段),這里我們采用Mnesia的內存存儲,將所有數(shù)據(jù)存在內存中,方便計算程序更快地從Mnesia讀取需要參與計算的視頻metadata,提升計算速度。

該模塊不光可以具備批量讀取MySQL所有數(shù)據(jù)的能力(項目第一次跑的時候需要全量計算),同時還需要實時監(jiān)控媒資庫的變化,如有新視頻加入,馬上(在秒級內)將新視頻同步到Mnesia中。

(2) add node模塊

當加入新節(jié)點時,通過重啟Master節(jié)點,Master節(jié)點與新節(jié)點建立聯(lián)系,識別出新節(jié)點,并把新節(jié)點加入計算集群,同時將Mnesia上的數(shù)據(jù)均勻分配到所有節(jié)點(包括新加入的節(jié)點)、給新節(jié)點分派計算任務(如果當前還有未計算過視頻相似度的視頻的話)。

(3) heartbeat模塊

Master節(jié)點定期(幾秒鐘)向所有Slaver節(jié)點發(fā)送心跳信號,通過該信號探測Slaver是否活著,如果一段時間后Slaver無任何響應,Master會認為該Slaver掛掉了,這時會將該掛掉的Slaver從計算列表中刪除,后續(xù)新的計算任務不再分配給該Slaver。

(4) Task allocation模塊

Slaver節(jié)點上啟動多個(一般可以設置為該服務器核數(shù)的1-2倍,如4核機器,可以啟動4-8個進程進行計算,有效利用多核計算能力)進程進行計算,等待Master節(jié)點來分配任務。Master節(jié)點定期跟Slaver節(jié)點通訊,輪詢各個Slaver節(jié)點,了解Slaver節(jié)點是否空閑,如有空閑并且現(xiàn)在還有未完成的計算任務,那么Master將新的計算任務分配給該slaver進行計算。

(5) similarity update模塊

如果新加入的視頻A比視頻B相似列表中相似度最低的視頻相似度更大,這時我們就需要更新視頻B的相似列表,將A添加進去,同時將B原來相似列表中相似度最低的剔除掉(見下面圖5)。

圖5:如果新視頻相似度大于某個視頻的相似列表,需要更新相似列表

那么怎么更新老視頻的相似推薦列表呢?一般來說,我們可以采用如下的方法,該方法也非常簡單,容易理解。

在Master節(jié)點維護一張視頻id和它的相似列表最小相似度的表(見下表,表中的視頻都是已經計算完相似推薦的視頻)。新加入的視頻A計算完相似視頻后(在計算topN相似度時,保存A跟每個其他視頻的相似度),將A視頻與每個其他視頻的相似度與下表比對,假設A與id_1的相似度大于s_1,那么就需要更新id_1的相似推薦列表了。

視頻id 推薦列表最小的相似度
id_1 s_1
id_2 s_2
...... ......
id_k s_k

實際上可以做很多簡化,比如我們可以先求出上表中第二列的最小值(見下面公式),我們只保留A與其他視頻相似度大于?的視頻,其他視頻直接丟棄(其實很多視頻可以丟棄,畢竟很多視頻跟A是沒有任何相似度的),而不會影響更新計算邏輯,這些相似度大于??的視頻才是可能需要更新推薦列表的視頻。

? ? ??

Master節(jié)點除了上面5個核心模塊外,還維護兩個關鍵的數(shù)據(jù)結構:

A :living_nodes:記錄集群目前可用的Slaver節(jié)點,如有有節(jié)點加入或者掛掉會更新該數(shù)據(jù)。

B:need_computing_id: 記錄哪些視頻還沒有計算相關視頻推薦列表,針對這些視頻在任務分配模塊中分派給Slaver節(jié)點計算,分配出去后將該視頻從待計算列表中刪除,避免重復計算。如果有新視頻加入,新視頻的id會寫入該列表。

Slaver:主要負責計算任務

Slaver節(jié)點只有一個核心模塊,即計算模塊,負責根據(jù)Master節(jié)點指派的任務進行相似計算。當Master將某個視頻的計算任務分配到Slaver時,Slaver從Mnesia讀取這個視頻的metadata信息,并計算該視頻與該視頻所在group(如電影組)的所有其他視頻的相似度,將相似度最大的TopN存到Riak集群中。

這里我們對核心的計算過程進行更詳細的講解,讓大家知道我們是怎么解決TopN最相似視頻的計算問題的。在下面圖6中每個Slaver節(jié)點中有4個worker(工作進程,負責進行相似計算),每個worker維護一個最大堆(最大堆中保留的元素個數(shù)就是我們需要計算的TopN的相似視頻數(shù)),最大堆負責保留最相似的N個視頻及相似度。

當Master將某個視頻A分配給worker1時,worker1先從Mnesia集群中將所有與A在同一類別(如電影)中的所有視頻取出來,循環(huán)計算與A的相似度,計算完一個就丟給最大堆,當所有的視頻與A的相似度都計算完后,這些相似視頻都丟給了worker1維護的最大堆,根據(jù)最大堆的性質,最終最大堆中留下的視頻(及相似度)就是與A最相似的N個相似視頻了。

圖6:Slaver中進行相似計算過程與邏輯

上面的最大堆是基于Erlang的ETS數(shù)據(jù)結構及相關操作構建的,它非常高效,也是我們整個計算引擎的核心子模塊,可以自動對丟入的{(videoid(視頻Id),similarity_score(相似度))}結構進行排序,保留最相似的N個。上面提到worker中包含的計算部分,即是基于我們在第二部分中的公式進行計算的。當某個視頻最相似的TopN計算完成后,worker會將推薦列表插入Riak集群,供前端接口調用。

這里面也是有很多可優(yōu)化點的,比如對于新聞或者體育等時效性很強的視頻,我們可以只從Mnesia中選取一段時間內(比如過去1天)的視頻來計算相似度,這樣就不需要計算相似度時跟Mnesia中同一組中的所有其他視頻計算相似度,這樣大大節(jié)省了計算時間。再比如,如果計算相似度中標簽的權重最大,我們計算視頻A與其他視頻相似度時,如果A與其他視頻的標簽相似度為0(或者很小),我們就沒必要計算它的其他維度的相似度了,直接將該視頻丟棄計算下一個。這些優(yōu)化點還很多,這里不一一描述。

Riak集群:負責最終相似推薦結果的存儲

Riak是基于Erlang語言開發(fā)的一個分布式的key-value存儲系統(tǒng),可以非常容易地水平擴展,非常適合大規(guī)模的數(shù)據(jù)存儲,是整個相似視頻推薦系統(tǒng)的最終計算結果的存儲模塊,所有視頻的相似推薦列表都存在Riak集群中。Slaver的worker計算完一個視頻的相似度后會直接插入Riak。

相應請求模塊:基于客戶端用戶請求,給出推薦結果

當用戶在客戶端訪問某個視頻的詳情頁時,客戶端向服務端發(fā)送請求,請求響應模塊根據(jù)用戶請求從Riak集群中將該節(jié)目的相似列表取出來,并將其他需要的信息(如標題、演職員、海報圖等在前端展示需要用到的節(jié)目metadata信息,這些信息我們存在Redis集群中)填充完整后返回給用戶。

請求響應模塊是基于Cowboy (一款基于Erlang開發(fā)的高性能輕量級接口服務器)來開發(fā)的。從前面的介紹中可以知道,Cowboy除了從Riak中獲取推薦列表外,還需要從Redis中獲取節(jié)目的metadata信息做填充。

核心亮點

到此為止,我們基本講完了相似視頻推薦的核心算法原理與基于Erlang實現(xiàn)的工程架構,該系統(tǒng)是作者在15年開發(fā)的,一直在作者公司的兩個產品中使用到現(xiàn)在,其中一個產品目前還是用的該算法(另外一個產品基于Spark平臺做了重構,整體效果更好),該算法在服務公司業(yè)務的4年中,雖然視頻種類和數(shù)量有了非常大的增長,但是系統(tǒng)一直比較穩(wěn)定,也能夠很好地應對視頻量的增長,并且效果還不錯,這得益于Erlang良好的容錯機制及該系統(tǒng)較好的分布式擴展能力。

在這里我們回顧一下該系統(tǒng)的亮點,也讓我們可以更好地理解它的價值。

分布式可拓展能力

該系統(tǒng)采用Master/Slaver架構,可以通過水平地增加服務器來拓展該系統(tǒng)的計算能力,同時當全量計算完后,后面就是增量計算了,增量計算相對沒有那么大的計算量,不需要這么多計算資源,我們可以縮減部分服務器節(jié)省開支。

可以實時對新增加的視頻做計算

Master的Data sync模塊近實時監(jiān)控媒資庫MySQL,如果有新視頻加入,馬上將該視頻同步到Mnesia中,并分派給Slaver進行計算,在分鐘級內新視頻就可以完成計算,這樣基本可以有效避免新入庫視頻的相似推薦冷啟動問題。

系統(tǒng)很穩(wěn)定

該系統(tǒng)一般很少出問題,這得益于Erlang的OTP框架,我們的Master和Slaver服務都是基于OTP框架來實現(xiàn)的,每個進程都有一個supervisor進程,當進程掛掉后,supervisor會重啟該進程,避免了因為偶爾的故障或者異常數(shù)據(jù)導致的系統(tǒng)崩潰,最終讓我們的系統(tǒng)非常穩(wěn)定。

分將計算過程解耦合,抽象為最大堆來維護topN最相似的視頻列表

將計算相似性計算抽象為一個計算模塊,每個worker通過維護一個最大堆,可以非常有效地解決最相似的topN計算問題。同時,針對新聞、體育等時效性強的視頻類型,我們還可以只取最近一段時間內的視頻來計算相似度,進一步減少計算量。

充分利用多核能力

每個Slaver可以啟動多個worker進行計算,充分利用現(xiàn)代服務器多核的能力,大大加速了計算過程。

除了上述優(yōu)點外,我們通過配置文件來定義各種參數(shù)(比如一個Slaver可以啟動多少個worker),可以方便地對參數(shù)進行調整,系統(tǒng)啟動時會首先解析這些參數(shù)。我們也可以一鍵啟動Master節(jié)點和所有的Slaver節(jié)點,整個配置和啟動過程跟Spark比較類似。該系統(tǒng)可以看成基于Erlang語言開發(fā)的具備特定功能的類Spark的小型分布式計算平臺。

未來優(yōu)化方向

雖然該系統(tǒng)有很多優(yōu)點,但由于個人能力及精力有限,并且對Erlang的了解還沒有達到爐火純青的階段,該系統(tǒng)還有非常多的地方是可以做優(yōu)化的。下面對可能的優(yōu)化點進行說明,作為后面努力的方向。

算法本身的優(yōu)化

該系統(tǒng)基于視頻內容的簡單向量空間模型來計算相似度,雖然算法原理簡單,但是由于視頻的metadata比較雜亂,相似性效果受到數(shù)據(jù)質量好壞的嚴重影響。同時,向量空間模型是一個比較簡單的模型,無法獲得更復雜的特征表示。可行的優(yōu)化點是,我們可以基于metadata數(shù)據(jù)或者用戶行為數(shù)據(jù)做嵌入,為每個視頻構建一個稠密的特征向量表示,該系統(tǒng)可以通過稠密向量的相似度來計算視頻的相似性。其他各類計算視頻相似度的方法都是可以使用的。

目前我們的計算相似度算法和整個系統(tǒng)還是耦合比較緊密的,通過優(yōu)化是可以將計算相似性做成可插拔的組件的,這樣就可以方便更換計算引擎。

另外,我們的向量空間模型各個維度的權重是根據(jù)人工經驗自定義的,比較主觀,其實是可以

利用用戶點擊反饋機制自動化學習最優(yōu)參數(shù)的,這樣可能效果會更好。

調度策略的優(yōu)化

當前該框架的調度策略還非常粗暴,對于每個需要計算相似推薦的視頻,直接從所有Slaver中先過濾出有空余資源的worker,將任務分配給第一個空閑的worker。針對每個視頻都要從頭過濾一遍,效率很低。

更好的方式是每個Slaver節(jié)點維護一個待計算相似度的固定長度的視頻隊列,當隊列中待計算的視頻都計算完了相似度,Slaver主動向Master申請待計算的視頻。這樣將主動權放到Slaver上,減少原來分配方案中毫無意義的輪詢,同時也減輕了Master節(jié)點的壓力。

部署方式的優(yōu)化

目前的系統(tǒng)雖然部署非常容易,只要在每臺服務器上安裝Erlang,將該項目編譯好,將編譯后的工程代碼分發(fā)到每臺服務器上統(tǒng)一的目錄下,修改每臺服務器上的配置文件(實際上所有Slaver上配置是一樣的,跟Master上略有不同)就可以啟動了。

更好的方式可以利用docker將工程構建在容器之上,利用mesos或者kubernetes等來管理工程運行,可以更好地做到集群監(jiān)控和資源彈性伸縮。

錯誤監(jiān)控與問題排查的優(yōu)化

目前該項目運行過程中會打少量的日志記錄,但對于各個模塊中可能存在的錯誤信息并未捕獲并記錄下來,對于問題的發(fā)現(xiàn)和排查不是很友好。雖然Erlang很穩(wěn)定,但是偶爾出一些問題是在所難免的,這一塊的優(yōu)化也是未來可行的方向之一。

數(shù)據(jù)同步的優(yōu)化

目前是由Master節(jié)點的data sync模塊直接監(jiān)控MySQL(媒資庫),從中將數(shù)據(jù)同步到Mnesia集群的。這一塊是可以直接采用消息隊列(如RabbitMQ)解耦的,data sync只需要監(jiān)控消息隊列中某個topic是否有新節(jié)目進來,有新的話就同步到Mnesia中,這比直接監(jiān)控MySQL高效得多。

后面作者會考慮基于上面幾點優(yōu)化思路對該項目進行優(yōu)化,同時對代碼結構進行調整,讓代碼看起來更加優(yōu)雅,如果有機會的話是希望可以將該項目開源的。

個人收獲與感悟

到此為止,關于利用Erlang語言開發(fā)分布式視頻相似推薦系統(tǒng)的介紹就講完了。在最后作者簡單說下自己做這個項目后的收獲和感悟。

作者在2015年花了近半年時間,算是一邊學習Erlang語言(在這之前看過Erlang,但是看得不太懂)一邊開發(fā)了該項目。該項目一共5000行左右代碼,雖然不是很多,但是對于像Erlang這類簡潔的語言來說,也不算少(如果用Java實現(xiàn),估計要幾萬行,還很難實現(xiàn)分布式計算)。在整個開發(fā)過程中,最大的收獲有如下3點:

新學習了一門比較有意思的函數(shù)式編程語言,對Erlang的特性有了比較深入的了解;

對于分布式計算有了更深刻的認識,這個項目相當于獨立實現(xiàn)了一個小型的分布式計算引擎,對于深刻認識Spark、Hadoop的原理是非常有幫助的;

獨立完成了一個較大的工程,并且實現(xiàn)了一個基于內容的相似視頻推薦系統(tǒng)。

做完該項目對個人來說確實是非常有幫助的。但是從整個團隊來說,這樣做未必是好事,利用一個很小眾的語言來開發(fā)一整套系統(tǒng),為以后埋下了很大的隱患,如果人員離職,很難招聘到Erlang的開發(fā)人員,新人很難獨立維護這套系統(tǒng),風險極大。作為團隊管理者,應該避免這種情況發(fā)生,最好還是利用主流的技術棧,避免留下無窮后患。

當時作者管理經驗還不足、對技術的理解還不夠深入,所以自告奮勇的親自開發(fā)了該系統(tǒng)。經過這幾年的積累和成長,對技術和管理有了更深的感悟。如果作為一名技術管理者,讓我再一次選擇,我可能不會用Erlang來開發(fā)該系統(tǒng),而會采用Spark流式計算引擎來開發(fā)。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 視頻
    +關注

    關注

    6

    文章

    1929

    瀏覽量

    72774
  • 算法
    +關注

    關注

    23

    文章

    4587

    瀏覽量

    92505
  • erlang
    +關注

    關注

    0

    文章

    16

    瀏覽量

    5734

原文標題:基于Erlang語言的視頻相似推薦系統(tǒng) | 深度

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    CPLD系統(tǒng)設計及VHDL語言視頻教程

    各位好,請問哪里有免費下載的 CPLD系統(tǒng)設計及VHDL語言視頻教程?是天祥的。淘寶里有好多賣的,可是要淘寶帳戶和錢呀?
    發(fā)表于 07-20 10:29

    系統(tǒng)的學習下C語言,求推薦教材和視頻!

    系統(tǒng)的學習下C語言,求推薦教材和視頻
    發(fā)表于 10-22 11:44

    適用于Java的嵌入式腳本語言是什么

    /fakescript-java簡介fakescript是一款輕量級的嵌入式腳本語言,使用Java語言編寫,語法吸取自lua、golang、erlang,基于jflex、cup生成語法樹,編譯成字節(jié)碼解釋執(zhí)行。 C/C++...
    發(fā)表于 12-23 08:17

    基于語義相似度的主觀題閱卷系統(tǒng)模型設計

    主觀題閱卷系統(tǒng)是一個值得研究的問題。常見的主觀題評分是比對學生答案和參考答案的相似程度得出分數(shù)的。自然語言處理里面的分詞技術可以將文字切分為詞的組合,然后通
    發(fā)表于 01-07 16:25 ?10次下載

    分布式的Erlang程序:陷阱和對策

    為了在Erlang運行時系統(tǒng)基礎上開發(fā)更可靠的分布式系統(tǒng)和算法,我們研究了Erlang編程語言中分布式的部分。使用
    發(fā)表于 04-18 22:37 ?23次下載

    優(yōu)化相似度計算在推薦系統(tǒng)中的應用

    推薦系統(tǒng)技術發(fā)展至今,產生了許多經典的推薦算法。為了進一步地提高推薦系統(tǒng)的推薦準確度和用戶滿意度,文章對相似度計算方法進行了研究,分析了不同物品的相似權重這個因素對
    發(fā)表于 01-04 14:55 ?0次下載

    erlang如何自定義_ERLANG環(huán)境搭建

    本文詳細介紹了erlang 如何自定義 behaviour以及ERLANG環(huán)境搭建。要定義一個behaviour,首先你要創(chuàng)建一個模塊,它必須導出 behaviour_info/1 這個函數(shù)(注意必須帶u),函數(shù)的定義如下文
    發(fā)表于 02-23 08:42 ?1505次閱讀
    <b class='flag-5'>erlang</b>如何自定義_<b class='flag-5'>ERLANG</b>環(huán)境搭建

    Erlang到底好在哪里_Erlang的優(yōu)勢與缺陷

    Erlang是一個平臺,她提供了一套完整的高性能、高可靠網(wǎng)絡服務開發(fā)所需要的基礎設施,并提供了原語給開發(fā)人員使用,她降低了開發(fā)類似系統(tǒng)的難度與門檻.有一個說法,Erlang讓一個中高級程序員,用一半
    的頭像 發(fā)表于 02-23 09:09 ?1.2w次閱讀

    Erlang是什么_erlang適合做什么_olang與erlang的比較

    本文詳細介紹了Erlang是什么,erlang適合做什么以及olang與erlang的關系比較。Erlang編程語言最初目的是進行大型電信交
    發(fā)表于 02-23 09:23 ?2.4w次閱讀
    <b class='flag-5'>Erlang</b>是什么_<b class='flag-5'>erlang</b>適合做什么_olang與<b class='flag-5'>erlang</b>的比較

    Erlang與java的內存架構比較_erlang與java構建的節(jié)點通訊

    Erlang是一門函數(shù)語言,通過異步消息傳遞來處理并發(fā),使用語義拷貝傳遞消息。即使Erlang分布在多個虛擬機上,運行在多臺機器上,對程序員來說也是透明的。在某種意義上Erlang和j
    發(fā)表于 02-23 10:18 ?2118次閱讀

    erlang編程語言特點詳細解析

    Erlang虛擬機。Erlang并發(fā)進程不同于操作系統(tǒng)進程,是非常輕量的,Erlang內置的分布式特性,異常方便, Erlang編程
    發(fā)表于 02-23 10:55 ?2879次閱讀

    Go和Python,Erlang語言對比分析和Go編程示例概述

    本文對Go和Python、Erlang做了一些有趣的分析對比,相信大家能從中感受到Go語言的強大和與眾不同。
    的頭像 發(fā)表于 07-21 09:52 ?7684次閱讀
    Go和Python,<b class='flag-5'>Erlang</b>的<b class='flag-5'>語言</b>對比分析和Go編程示例概述

    關于Erlang語言的功能及特性

    Erlang是運作于虛擬機的解釋型語言,在程序設計范型上,Erlang屬于多重范型編程語言,涵蓋函數(shù)式、并行及分布式。循序運行的Erlang
    發(fā)表于 09-29 10:56 ?3601次閱讀

    Erlang之父Joe Armstrong于4月20日去世,享年68歲

    Armstrong發(fā)明的Erlang在全球范圍內是個小眾語言,根據(jù)TIOBE發(fā)布的最新語言排行榜,Erlang排名第47位,市場份額占有僅為0.177%。它不是像Java、C++是面向
    的頭像 發(fā)表于 04-23 14:57 ?4718次閱讀

    Erlang代碼支持愛立信網(wǎng)絡解決方案的大部分移動語音和網(wǎng)絡通信

    大約20年前,一種名叫Erlang的編程語言在愛立信Computer Science Lab誕生——它的設計者,Mike Williams、Joe Armstrong和Robert Virding,為了滿足通信大規(guī)模并行活動所需的運行環(huán)境,發(fā)明了這種
    的頭像 發(fā)表于 12-09 17:10 ?1891次閱讀