網(wǎng)易云音樂工程師,親自揭曉評(píng)論實(shí)現(xiàn)技術(shù)(二)| 技術(shù)頭條

歡迎大家回到網(wǎng)易云音樂評(píng)論技術(shù)探秘之旅色难,上一篇我們介紹了云音樂評(píng)論的業(yè)務(wù)場(chǎng)景和基礎(chǔ)架構(gòu)泼舱,這一篇將圍繞云音樂評(píng)論的核心功能:評(píng)論發(fā)表、評(píng)論獲取和評(píng)論點(diǎn)贊進(jìn)行剖析探秘莱预。

評(píng)論發(fā)表

數(shù)據(jù)庫表.jpg

首先我們先看上圖柠掂,這是我們把評(píng)論功能抽象出來最核心的數(shù)據(jù)庫表結(jié)構(gòu),為了更好地理解后文依沮,我們先解釋一下字段含義

先看一下右邊評(píng)論表【Comment】:

  • id:評(píng)論記錄主鍵
  • resourceId:評(píng)論所屬的資源
  • contents:評(píng)論內(nèi)容
  • time:評(píng)論時(shí)間
  • likedCount:評(píng)論被點(diǎn)贊次數(shù)(這里會(huì)有行鎖競(jìng)爭(zhēng)的問題需要處理)
  • status:數(shù)據(jù)狀態(tài)
  • userId:評(píng)論用戶ID
  • version:版本號(hào)涯贞,用樂觀鎖控制數(shù)據(jù)并發(fā)操作

接下來我們看評(píng)論與資源關(guān)聯(lián)表【CommentResource】,對(duì)資源不太理解的同學(xué)可以翻閱上篇危喉。

  • id:評(píng)論與資源關(guān)聯(lián)表的主鍵宋渔,這里沒有使用自增ID,而是使用資源類型和資源ID組合辜限,這樣在處理業(yè)務(wù)邏輯時(shí)就可以根據(jù)主鍵ID按照規(guī)則拆解出資源ID從而可以方便的取到資源信息
  • resourceInfo:資源基本信息
  • resourceType:資源類型皇拣,如歌單、歌曲薄嫡、動(dòng)態(tài)氧急、電臺(tái)等
  • CommentCount:記錄資源評(píng)論數(shù)量,類似上表的likedCount都是計(jì)數(shù)字段毫深,同樣有行鎖競(jìng)爭(zhēng)的問題需要處理

評(píng)論發(fā)表流程

介紹完評(píng)論數(shù)據(jù)模型之后吩坝,我們開始進(jìn)入評(píng)論發(fā)表流程,整體流程圖如下:

發(fā)表評(píng)論流程圖.jpg

從上圖可以看到從客戶端發(fā)起評(píng)論到后臺(tái)服務(wù)會(huì)先經(jīng)過網(wǎng)關(guān)哑蔫,上一篇我們也提到了網(wǎng)關(guān)的重要性钉寝,它為后臺(tái)服務(wù)提供了流控、鑒權(quán)等全局能力闸迷。接下來就進(jìn)入應(yīng)用服務(wù)嵌纲,應(yīng)用服務(wù)首先會(huì)進(jìn)行前置的邏輯判斷,包含三部分分別是:一是反作弊判斷腥沽,主要是安全性方面的判斷逮走;二是資源合法性判斷,比如資源已經(jīng)不存在了今阳,或者設(shè)置不允許評(píng)論等言沐;最后是評(píng)論鑒權(quán)邓嘹,有可能資源作者拉黑了某些用戶酣栈,那么這些在黑名單的用戶就不能對(duì)該資源進(jìn)行評(píng)論了险胰。

經(jīng)過上述前置校驗(yàn)通過后,可以看到這里進(jìn)行了異步化的處理矿筝,將評(píng)論放到異步消息隊(duì)列成功時(shí)即返回客戶端評(píng)論成功起便,再由消息消費(fèi)者異步進(jìn)行持久化處理。

對(duì)于評(píng)論來說窖维,其內(nèi)容合法性是至關(guān)重要的榆综,這個(gè)大家都懂,因此在進(jìn)行真正持久化處理之前需要進(jìn)行反垃圾處理铸史,將不合適的內(nèi)容優(yōu)(he)化(xie)一下鼻疮,對(duì)于反垃圾如何實(shí)現(xiàn)這個(gè)就比較復(fù)雜了,一般都是有專門的部門和系統(tǒng)提供中臺(tái)化平臺(tái)琳轿,常見的做法是構(gòu)建內(nèi)容中心判沟、策略引擎、舉報(bào)懲罰中心崭篡、數(shù)據(jù)中心和引入人工標(biāo)注挪哄,這個(gè)都可以單獨(dú)再寫一篇了,這里暫不贅述琉闪。接下來進(jìn)行真正的持久化迹炼,添加評(píng)論并更新評(píng)論計(jì)數(shù),到此評(píng)論本身的處理就結(jié)束了颠毙,然后將該事件寫到消息隊(duì)列斯入,通知其他關(guān)聯(lián)業(yè)務(wù)處理。

接下來重點(diǎn)說一下上述流程在前置校驗(yàn)和后置持久化中間進(jìn)行異步化處理蛀蜜,主要有以下兩個(gè)好處:

  • 熱門資源可能會(huì)在短時(shí)間產(chǎn)生大量評(píng)論刻两,如果不進(jìn)行異步化對(duì)突發(fā)流量削峰會(huì)導(dǎo)致在短時(shí)間內(nèi)有大量評(píng)論更新同一資源的評(píng)論計(jì)數(shù),即更新CommentResource表的CommentCount字段涵防,會(huì)存在行鎖競(jìng)爭(zhēng)問題
  • 評(píng)論本身從請(qǐng)求發(fā)出到數(shù)據(jù)落地所需要處理的邏輯相對(duì)評(píng)論讀取要復(fù)雜很多闹伪,通過異步消息隊(duì)列將流程解耦可以快速響應(yīng)用戶,提升用戶體驗(yàn)壮池。

當(dāng)然引入異步化也增加了系統(tǒng)復(fù)雜度偏瓤,需要正確使用,否則會(huì)引起其他問題椰憋。那么異步化需要關(guān)注的點(diǎn)有哪些呢厅克?

  • 消息有序性:從評(píng)論這個(gè)業(yè)務(wù)場(chǎng)景來看,對(duì)消息有序性沒有那么高的要求橙依,消息不需要邏輯有序证舟,或者說即使消息亂序了硕旗,用戶感知并不明顯,而且消息體已包含評(píng)論發(fā)表時(shí)間女责,可以確保評(píng)論顯示的時(shí)間與用戶發(fā)表時(shí)間一致漆枚。
  • 消息冪等性:不同消息中間件提供的機(jī)制有所不同,有的是保證最多消費(fèi)一次抵知,這可能會(huì)導(dǎo)致消息丟失墙基;有的是最少消費(fèi)一次,這可能導(dǎo)致重復(fù)消費(fèi)刷喜;對(duì)于這個(gè)場(chǎng)景來說残制,肯定是要優(yōu)先保證消息不丟失,即允許消息存在重復(fù)掖疮,消息重復(fù)引來另一個(gè)問題就是要實(shí)現(xiàn)消息冪等初茶,否則后果可想而知。這里可以在消息異步化之前生成評(píng)論主鍵作為消息體的一部分浊闪,通過成熟的數(shù)據(jù)庫唯一性約束保證消息唯一恼布,相對(duì)來說是比較容易也是成本較低的實(shí)現(xiàn)方式。
  • 消息延遲:異步化的另一個(gè)共性問題就是消息可能會(huì)延遲规揪,在這個(gè)場(chǎng)景中我們看到在消息進(jìn)入隊(duì)列之前已經(jīng)返回客戶端成功桥氏,此時(shí)客戶端可以將當(dāng)前用戶評(píng)論顯示在評(píng)論列表上,但是其他人刷新列表時(shí)不一定能同時(shí)看到猛铅,需要等到數(shù)據(jù)持久化之后字支,正常情況下客戶感知不明顯,但在消息堆積比較嚴(yán)重的情況下會(huì)存在一定時(shí)間差奸忽。

評(píng)論反垃圾

反垃圾流程圖.jpg

對(duì)于所有互聯(lián)網(wǎng)UCG相關(guān)的場(chǎng)景都避免不了反垃圾處理堕伪,對(duì)于反垃圾處理在實(shí)現(xiàn)上有以下要求:
首先要做到數(shù)據(jù)可恢復(fù),因?yàn)橛行?shù)據(jù)有可能一開始會(huì)被系統(tǒng)認(rèn)為有問題栗菜,后續(xù)又經(jīng)過審核把“有問題”的給恢復(fù)回來欠雌,因此要求數(shù)據(jù)資產(chǎn)可恢復(fù),不能做物理刪除疙筹,實(shí)際上不僅僅評(píng)論數(shù)據(jù)富俄,從公司數(shù)據(jù)資產(chǎn)角度來說對(duì)于所有的數(shù)據(jù)都不建議物理刪除。另外而咆,如上文所述反垃圾服務(wù)一般是獨(dú)立于業(yè)務(wù)系統(tǒng)存在的霍比,跨系統(tǒng)協(xié)作不可避免會(huì)存在請(qǐng)求或響應(yīng)沒收到的情況,這樣會(huì)導(dǎo)致整個(gè)鏈路不完整暴备,因此需要有類似對(duì)賬機(jī)制悠瞬,確保請(qǐng)求被接收,響應(yīng)被處理,即ACK機(jī)制浅妆,所以這個(gè)地方要求反垃圾記錄做持久化處理望迎,做到可追溯。

評(píng)論點(diǎn)贊

評(píng)論點(diǎn)贊功能很好理解凌外,場(chǎng)景比較簡(jiǎn)單辩尊,喜歡可以點(diǎn)贊,點(diǎn)了贊的也可以取消趴乡。但它與評(píng)論計(jì)數(shù)有個(gè)類似的問題对省,熱門資源的熱門評(píng)論有可能會(huì)有很多人同時(shí)點(diǎn)贊從而產(chǎn)生計(jì)數(shù)行鎖競(jìng)爭(zhēng),這里我們同樣采用異步的方式進(jìn)行削峰晾捏,但這里與評(píng)論有個(gè)不同點(diǎn)是這里異步化要重點(diǎn)解決的是消息有序性,因?yàn)橥粋€(gè)用戶如果先點(diǎn)贊后取消哀托,但后臺(tái)接收到的消息卻是先取消后點(diǎn)贊惦辛,這樣就會(huì)導(dǎo)致最終的結(jié)果跟實(shí)際操作不符,顯然這里消息有序性比消息不重復(fù)更重要仓手。

那如何保證消息嚴(yán)格有序呢胖齐?消息有序既要求消息有序生產(chǎn),也要求消息被有序消費(fèi)嗽冒。

kafka(1).jpg

如上圖呀伙,我們都知道使用kafka中間件,同一個(gè)partition可以保證消息有序添坊,因此我們可以按照用戶維護(hù)剿另,讓同一個(gè)用戶的點(diǎn)贊和取消點(diǎn)贊操作都寫到同一個(gè)partition,這可以解決生產(chǎn)端消息有序贬蛙;然后在消費(fèi)端雨女,我們使用單線程消費(fèi)同一個(gè)partition,這樣可以保證消費(fèi)端有序消費(fèi)阳准;但是單線程消費(fèi)有可能會(huì)帶來性能問題導(dǎo)致消息積壓氛堕,因此我們需要考慮擴(kuò)展更多的partition使消息更分散,這樣消費(fèi)的線程也同樣得到相應(yīng)的擴(kuò)展野蝇。

評(píng)論讀取

前面我們了解到評(píng)論讀取的并發(fā)是非常高的讼稚,因此首先我們要考慮該場(chǎng)景下要保護(hù)的核心資源:數(shù)據(jù)庫。為了保護(hù)數(shù)據(jù)庫同時(shí)為了提供滿足業(yè)務(wù)要求的性能绕沈,我們進(jìn)行了多級(jí)緩存的設(shè)計(jì)锐想,具體如下圖:

評(píng)論讀取.jpg

從下往上看我們可以看到在數(shù)據(jù)庫之上有Memcached緩存,這是跟數(shù)據(jù)庫表一一對(duì)應(yīng)的七冲,我們可以理解為DAO層緩存痛倚;再往上是數(shù)據(jù)組裝服務(wù),處理評(píng)論相關(guān)聯(lián)的數(shù)據(jù)組裝澜躺;接著是使用Redis實(shí)現(xiàn)的業(yè)務(wù)層緩存蝉稳,這里存放的就是經(jīng)過業(yè)務(wù)組裝的數(shù)據(jù)抒蚜;最上層就是應(yīng)用服務(wù)了,這一層我們也使用了本地緩存耘戚,它的特點(diǎn)是快嗡髓,但容量小,因此只能放少量熱門的數(shù)據(jù)收津,但這部分最熱門數(shù)據(jù)的緩存可以緩解Redis熱點(diǎn)問題饿这,避免最熱門數(shù)據(jù)都打到同一個(gè)Redis節(jié)點(diǎn),但本地緩存有一個(gè)問題撞秋,就是緩存難以同時(shí)清除长捧,不同于分布式緩存,使用一個(gè)命令就可以把緩存清掉吻贿,本地緩存在每個(gè)服務(wù)器上面都存了一份串结,這個(gè)要同時(shí)清理還是比較困難的。

另一個(gè)需要注意的是冷熱數(shù)據(jù)的處理舅列,因?yàn)閿?shù)據(jù)庫和內(nèi)存緩存的容量級(jí)別存在較大差異肌割,我們不可能把所有的數(shù)據(jù)都緩存起來,因此緩存一般存的都是相對(duì)較熱的數(shù)據(jù)帐要,冷數(shù)據(jù)則從數(shù)據(jù)庫直接加載把敞。

接下來我們重點(diǎn)看一下業(yè)務(wù)層緩存的設(shè)計(jì),這里相對(duì)比較復(fù)雜榨惠。上面提到了這里緩存的是業(yè)務(wù)組裝之后的數(shù)據(jù)奋早,除了評(píng)論數(shù)據(jù)本身,還會(huì)讀取其他模塊比如用戶數(shù)據(jù)冒冬,但其他模塊的數(shù)據(jù)更新又不會(huì)通知到評(píng)論模塊伸蚯,所以怎么更新這一層緩存呢?這里我們采用的策略不是去訂閱其他服務(wù)的變更來同步更新緩存简烤,而是采用短時(shí)間緩存自動(dòng)失效后重新拉取數(shù)據(jù)的方式剂邮。從下圖可以看到短時(shí)間緩存過了2秒之后就需要重新調(diào)用數(shù)據(jù)組裝服務(wù),這2秒鐘對(duì)前端體驗(yàn)來說基本無損横侦,但緩存失效之后會(huì)造成大量請(qǐng)求去調(diào)用組裝服務(wù)挥萌,為了避免對(duì)下層服務(wù)造成太大壓力這里加了一層分布式鎖,即某個(gè)緩存失效了之后枉侧,在大量請(qǐng)求該緩存數(shù)據(jù)的線程中引瀑,只有一個(gè)線程可以調(diào)用數(shù)據(jù)組裝服務(wù),其他的請(qǐng)求轉(zhuǎn)到長(zhǎng)時(shí)間緩存(24小時(shí))榨馁,當(dāng)數(shù)據(jù)組裝完成后會(huì)同時(shí)更新短時(shí)間緩存和長(zhǎng)時(shí)間緩存憨栽,這樣長(zhǎng)短緩存結(jié)合的設(shè)計(jì)既保護(hù)了核心資源,也不犧牲服務(wù)性能,同時(shí)可以解決數(shù)據(jù)組裝問題屑柔,可以說是一個(gè)比較巧妙的設(shè)計(jì)屡萤。

redis.jpg

以上就是云音樂評(píng)論的核心功能評(píng)論發(fā)表、評(píng)論獲取和評(píng)論點(diǎn)贊的實(shí)現(xiàn)思路掸宛,包含了基礎(chǔ)的邏輯架構(gòu)死陆,處理流程,以及關(guān)鍵功能點(diǎn)實(shí)現(xiàn)技巧唧瘾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末措译,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子饰序,更是在濱河造成了極大的恐慌领虹,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菌羽,死亡現(xiàn)場(chǎng)離奇詭異掠械,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)注祖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來均唉,“玉大人是晨,你說我怎么就攤上這事√蚣” “怎么了罩缴?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)层扶。 經(jīng)常有香客問我箫章,道長(zhǎng),這世上最難降的妖魔是什么镜会? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任檬寂,我火速辦了婚禮,結(jié)果婚禮上戳表,老公的妹妹穿的比我還像新娘桶至。我一直安慰自己,他們只是感情好匾旭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布镣屹。 她就那樣靜靜地躺著,像睡著了一般价涝。 火紅的嫁衣襯著肌膚如雪女蜈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音伪窖,去河邊找鬼逸寓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惰许,可吹牛的內(nèi)容都是我干的席覆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼汹买,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼佩伤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晦毙,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤生巡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后见妒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孤荣,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年须揣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盐股。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耻卡,死狀恐怖疯汁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卵酪,我是刑警寧澤幌蚊,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站溃卡,受9級(jí)特大地震影響溢豆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘸羡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一漩仙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧最铁,春花似錦讯赏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雀哨,卻和暖如春磕谅,著一層夾襖步出監(jiān)牢的瞬間私爷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工膊夹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衬浑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓放刨,卻偏偏與公主長(zhǎng)得像工秩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子进统,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355