算引擎如何實(shí)現(xiàn)秒級(jí)實(shí)時(shí)關(guān)系傳遞)
1. 先聊清楚實(shí)時(shí)關(guān)系傳遞到底在解決什么問題1.1 社交場(chǎng)景里的一個(gè)真實(shí)例子最近在做一個(gè)“關(guān)系推薦與風(fēng)險(xiǎn)傳導(dǎo)”項(xiàng)目從技術(shù)選型上就是一個(gè)非常典型的 RabbitMQ 大數(shù)據(jù)圖計(jì)算組合。先講一個(gè)運(yùn)營(yíng)同學(xué)一聽就懂的例子系統(tǒng)監(jiān)控到用戶小明關(guān)注了Ruby幾秒后Ruby又點(diǎn)贊了Kevin發(fā)布的一條帖子。從圖視角看小明、Ruby、帖子、Kevin之間天然形成一條路徑小明—FOLLOW→Ruby—LIKE→帖子—AUTHOR→Kevin。業(yè)務(wù)上想實(shí)時(shí)給小明推送“你關(guān)注的人Ruby點(diǎn)贊了Kevin的內(nèi)容”這種提醒就是在做實(shí)時(shí)關(guān)系傳遞。這里的關(guān)系不是簡(jiǎn)單的一對(duì)一好友關(guān)系而是圖上節(jié)點(diǎn)通過邊串起來的間接關(guān)系。傳統(tǒng)做法是離線任務(wù)每小時(shí)或每天跑一遍全量圖把新產(chǎn)生的二度人脈或者風(fēng)險(xiǎn)鏈路刷出來但到那會(huì)兒用戶早就離開了當(dāng)時(shí)的互動(dòng)場(chǎng)景運(yùn)營(yíng)想抓住的就是關(guān)系發(fā)生之后那幾十秒的變化窗口。于是需求就變成一條關(guān)系事件發(fā)生后要在秒級(jí)把它追加到全局關(guān)系圖里再沿著新增邊做多跳傳遞計(jì)算。這套邏輯術(shù)語(yǔ)上叫實(shí)時(shí)關(guān)系傳遞實(shí)現(xiàn)上則強(qiáng)依賴消息隊(duì)列和圖計(jì)算引擎的配合。1.2 為什么不能指望定時(shí)批處理真正開始做實(shí)時(shí)后會(huì)發(fā)現(xiàn)數(shù)據(jù)源非常多用戶關(guān)注接口、點(diǎn)贊服務(wù)、交易系統(tǒng)、內(nèi)容舉報(bào)、設(shè)備指紋上報(bào)每個(gè)系統(tǒng)都可能產(chǎn)生節(jié)點(diǎn)與節(jié)點(diǎn)之間的關(guān)系變更。如果讓圖計(jì)算平臺(tái)直接去各業(yè)務(wù)系統(tǒng)拉數(shù)據(jù)第一個(gè)問題是數(shù)據(jù)接口五花八門第二個(gè)問題是高峰期所有系統(tǒng)同時(shí)產(chǎn)生大量關(guān)系變更圖數(shù)據(jù)庫(kù)寫入壓力會(huì)陡增。更嚴(yán)重的是業(yè)務(wù)系統(tǒng)不能因?yàn)閳D計(jì)算模塊掛了就一直阻塞生產(chǎn)流程否則一個(gè)輔助鏈路會(huì)把核心鏈路拖垮。這就是需要一套異步事件管道的原因。業(yè)務(wù)系統(tǒng)只負(fù)責(zé)把“發(fā)生了關(guān)系變更”這個(gè)事實(shí)扔到 RabbitMQ不關(guān)心后面有多少消費(fèi)者、圖計(jì)算模塊是否 ready。RabbitMQ 在這里承擔(dān)的是削峰緩沖、事件分發(fā)和故障隔離讓上游業(yè)務(wù)和圖計(jì)算引擎解耦。你可以把它理解成快遞中轉(zhuǎn)倉(cāng)所有商家把包裹統(tǒng)一送到中轉(zhuǎn)中心末端再按區(qū)域分給快遞員。商家不會(huì)因?yàn)槟硞€(gè)片區(qū)快遞員請(qǐng)假而無法寄件快遞員也不會(huì)因?yàn)樗查g涌進(jìn)大量包裹而被商家直接堵門。1.3 關(guān)系事件在圖中最終是什么形態(tài)要聊實(shí)現(xiàn)得先統(tǒng)一語(yǔ)義。我把圖上每個(gè)實(shí)體都稱為 Entity 節(jié)點(diǎn)比如用戶、帖子、設(shè)備、銀行卡實(shí)體之間通過關(guān)系邊連接比如 FOLLOW、LIKE、AUTHOR、TRANSFER、REGISTER_DEVICE。每當(dāng)業(yè)務(wù)系統(tǒng)產(chǎn)生一條新的關(guān)系邊就對(duì)應(yīng)一個(gè)關(guān)系事件RelationEvent。RabbitMQ 里傳遞的對(duì)象不是“圖計(jì)算結(jié)果”而是這些原始關(guān)系變更消息真正算關(guān)系、做傳遞計(jì)算的活應(yīng)該放在消費(fèi)端和圖引擎那邊。這么拆開之后分工非常清楚RabbitMQ 管消息可靠到達(dá)大數(shù)據(jù)圖計(jì)算管節(jié)點(diǎn)和邊的增量維護(hù)與路徑查詢。兩者結(jié)合實(shí)時(shí)關(guān)系傳遞才