大規(guī)模業(yè)務(wù)數(shù)據(jù)延遲落地,以及實時IM消息通知



遇到的問題:

目前流行的直播行業(yè)中悯森,產(chǎn)品會鼓勵用戶多與主播互動宋舷,而互動火熱的體現(xiàn),則是通過上圖最右方的人氣值體現(xiàn)瓢姻。

目前常規(guī)的互動為聊天祝蝠,送禮,點贊幻碱,關(guān)注绎狭,宋星星,分享褥傍。其中聊天儡嘶,送禮,點贊恍风,都是頻率較高的互動蹦狂。

系統(tǒng)要根據(jù)這些互動計算圖右側(cè)的人氣值,并返回給用戶邻耕,而且人氣值需要持久處理鸥咖。

筆者所遇到的問題是,實時計算互動兄世,并存儲時啼辣,能否降低寫庫的次數(shù),以及推送IM的次數(shù)御滩。

如果當(dāng)前房間十分火熱鸥拧,

聊天tps500 ?送禮tps300 點贊tps500 我不希望我每秒會為了更新人氣,更新1000多次削解,并且IM推送上行1000多次富弦,IM下行是給房間里的

每一個人推送,那么次數(shù)更是不可設(shè)想氛驮。

如何減輕庫的寫壓力腕柜,以及IM服務(wù)的壓力,是這次要解決的問題矫废。

總體圖:



上圖是該業(yè)務(wù)的總體結(jié)構(gòu)圖盏缤,每個業(yè)務(wù)有自己的業(yè)務(wù)消息總線,如發(fā)言蓖扑,點贊等唉铜,消息中間件采用kafka,比如我現(xiàn)在是需要接受消息更新人氣律杠,用戶經(jīng)驗等潭流,所以我定義了一個新的消費組community-esb竞惋,消費組收到各業(yè)務(wù)線的消息后,通過調(diào)用人氣服務(wù)灰嫉,以及經(jīng)驗服務(wù)來更新主播的人氣值拆宛,互動發(fā)生源用戶的經(jīng)驗值。消息body基本都是這樣的熬甫,比如聊天:

{userId:<userId>,targetUserId<targetUserId>,roomId<roomId>,message<message>}

消費者會根據(jù)消息體內(nèi)的詳細(xì)內(nèi)容進(jìn)行加人氣處理胰挑,比如送禮會看禮物個數(shù)蔓罚,點贊會看點贊次數(shù)等椿肩,這里不再贅述。

上述規(guī)劃圖中豺谈,這個部分是要解決的問題

起初想到的三種解決方式:

A,

//增加人氣值郑象,用戶進(jìn)入房間獲取,或推送都從這里獲取

Long total=Increase(AnchorPopularKey,value);

//獲取鎖

String timeStamp = getAnchorLockKey(anchor)? 1

如果鎖存在茬末,并且未失效厂榛,則直接返回

If(value!=null && System.currentTime-value<15s){Return;}

//這里有并發(fā)問題

//鎖不存在,則設(shè)置鎖丽惭,并更新db 推送IM

setAnchorLockKey(anchor,random(3,12)s)

Insert DB total

sendIM total

A方式的大致思路為:緩存中存儲主播的總?cè)藲庵祷髂蹋瑯I(yè)務(wù)需要讀取時也從這里讀取,人氣服務(wù)計算好需要增加的人氣值時责掏,

直接調(diào)用redis increase操作柜砾,那么什么時候進(jìn)行落地呢?設(shè)置另外一個ttl key换衬,失效時間為3~10秒痰驱,當(dāng)key失效時,則進(jìn)行落地操作瞳浦,

以及推送IM操作担映,如果希望前端更新快,則時間可設(shè)置短一些叫潦。

優(yōu)點:這種方式網(wǎng)絡(luò)開銷相對較少蝇完,策略驗證是否需要落地只用了一次網(wǎng)絡(luò)IO

缺點:

? ? ? ? 1,因為redis存的是人氣總值矗蕊,而需要保證redis里的總值與數(shù)據(jù)庫總值完全相同較難短蜕。而且最后落地時,是將redis的總值

? ? ? ? ? ? ? 直接做覆蓋操作拔妥,很有可能總值之前是100忿危,覆蓋后變98

? ? ? ? ?2,最后的落地操作没龙,以及推送IM操作铺厨,存在并發(fā)問題缎玫,因為為了達(dá)到較大吞吐量,增加消費消息效率解滓,

? ? ? ? ? ? ? ?消費組的進(jìn)程數(shù)與kafka設(shè)置的patition數(shù)量相同赃磨,當(dāng)多個進(jìn)程同時消費時,可能會同時進(jìn)行落地操作洼裤,

? ? ? ? ? ? ? ?以及推送IM操作邻辉,比較浪費。

B腮鞍,

//增加人氣值值骇,//增加人氣值,用戶進(jìn)入房間獲取移国,或推送都從這里獲取

Long total=Increase(AnchorPopularKey,value);

//獲取鎖

Boolean set = setIfAbsent(anchorLock2(anchor),System.currentTime);? 1

If(set){

//獲取到了鎖吱瘩,入庫,推IM

Insert DB total;

sendIM total;

重新設(shè)置鎖(3~12秒)失效

setExpire(anchorLock2(anchor),random(3,12)s);

}else{

//獲取鎖的設(shè)置時間

timeStamp = get(anchorLock2(anchor));? 2

//如果鎖設(shè)置時間已過15秒迹缀,說明鎖已經(jīng)失效使碾,之前設(shè)置失效失敗,刪除鎖

if(System.currentTime-timeStamp>15s){

delete(anchorLock2);

}

}

方式B算是方式A的改進(jìn)祝懂,為了解決并發(fā)數(shù)據(jù)落地的問題票摇,不過這種方式,增加了一個分布式鎖砚蓬,多了一次網(wǎng)絡(luò)IO消耗矢门。


C,

TASK 60秒一次怜械。颅和。÷圃剩或10秒一次

for(Room room:ShowingRoomList){

//獲取緩存中的人氣值

Popular p = popularService.get(room);

//上次推送至今峡扩,房間人氣值有變化,給予推送更新

if(redis.get(room)!=p.getPopular()){

insertDb;

sendIm

redis.set(room)

}

}


C方式與A B方式完全不同障本,C是通過另起一個進(jìn)程跑task教届,然后異步將人氣值落地,以及推送IM驾霜,但是

還是需要消費者做redis.increase操作案训,只是消費者不再負(fù)責(zé)數(shù)據(jù)落地,以及推送了粪糙。

結(jié)論:

1强霎,起初設(shè)置一個緩存總?cè)藲庵凳菫榱隧槺憧棺x壓力,不過上述幾種方式經(jīng)過反復(fù)推演蓉冈,首先難以解決的問題就是城舞,如果你在緩存中存儲一個總值轩触,那么你用數(shù)據(jù)庫覆蓋緩存可以,如果用緩存覆蓋數(shù)據(jù)庫家夺,將十分危險脱柱,而且難以保證準(zhǔn)確性。

2拉馋,A,B方式均存在很多不必要的網(wǎng)絡(luò)開銷或數(shù)據(jù)庫開銷榨为,需要在兩者之間做均衡。C方式另起進(jìn)程煌茴,使得業(yè)務(wù)不聚合随闺,消費組不能自己

完成任務(wù),需要依賴另一個進(jìn)程景馁。而且板壮,單進(jìn)程存在單點問題逗鸣。不過C方式相對來講合住,更可控些,因為單進(jìn)程撒璧,所以不存在過多的數(shù)據(jù)庫開銷透葛,以及網(wǎng)絡(luò)開銷。

最后決定卿樱,棄用緩存存人氣總值的方式僚害,通過增量更新人氣總值。

設(shè)計圖如下:



代碼如下:


這種方式的思路是繁调,將一分鐘時間分為30個時間片萨蚕,線程將根據(jù)當(dāng)前系統(tǒng)時間,將人氣值累加存儲到當(dāng)前時間片內(nèi)蹄胰,

落地時則是存儲上一個時間片的累加值岳遥,并且為增量更新。這樣可控制一個房間內(nèi)的落地以及推送IM頻率裕寨,最多為30次浩蓉。

通過redis的原子操作,選取leader宾袜,來進(jìn)行落地捻艳,推送,失效操作庆猫,防止并發(fā)問題认轨。同時,當(dāng)房間內(nèi)互動頻率不高時月培,

則實時落地推送嘁字,增強用戶體驗昨稼。

當(dāng)然,我們現(xiàn)在的業(yè)務(wù)量還不大~服務(wù)上線后監(jiān)控圖如下:

由圖可見拳锚,互動產(chǎn)生累加人氣操作tps在晚上比較高假栓,可以達(dá)到90左右,而那時霍掺,實時落地的tps為2.5匾荆。也就是說房間內(nèi)就算互動再頻繁,

右上角的人氣變化大約是2秒一變杆烁。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牙丽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兔魂,更是在濱河造成了極大的恐慌烤芦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件析校,死亡現(xiàn)場離奇詭異构罗,居然都是意外死亡,警方通過查閱死者的電腦和手機智玻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門遂唧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吊奢,你說我怎么就攤上這事盖彭。” “怎么了页滚?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵召边,是天一觀的道長。 經(jīng)常有香客問我裹驰,道長隧熙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任邦马,我火速辦了婚禮贱鼻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滋将。我一直安慰自己邻悬,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布随闽。 她就那樣靜靜地躺著父丰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛾扇,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天攘烛,我揣著相機與錄音,去河邊找鬼镀首。 笑死坟漱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的更哄。 我是一名探鬼主播芋齿,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼成翩!你這毒婦竟也來了觅捆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤麻敌,失蹤者是張志新(化名)和其女友劉穎栅炒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體术羔,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡赢赊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了聂示。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片域携。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鱼喉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情趋观,我是刑警寧澤扛禽,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站皱坛,受9級特大地震影響编曼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剩辟,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一掐场、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贩猎,春花似錦熊户、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至艇棕,卻和暖如春蝌戒,著一層夾襖步出監(jiān)牢的瞬間串塑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工北苟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桩匪,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓友鼻,卻偏偏與公主長得像吸祟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桃移,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,318評論 25 707
  • 這一趟要去的是越南版的“大上何葚埃”胡志明,以前沒去過借杰,坦白地說过吻,此行主要是去看美女的,當(dāng)然還有那么一點小小的目的.....
    吉娃文創(chuàng)閱讀 287評論 0 0
  • 百度云盤新增了文件夾屬性蔗衡,實際上是對用戶做了什么假定纤虽? 11月份百度云盤進(jìn)行了改版升級,本次升級新增文件夾屬性绞惦,圖...
    臨岸觀潮雨閱讀 1,351評論 0 51
  • 今天是考研的第一天逼纸,但我沒有走進(jìn)考場,我不知道怎么面對你們济蝉,卻有好多話想對你們說 這段日子的糟糕杰刽,你們應(yīng)該隱約感覺...
    景昕閱讀 244評論 0 0
  • “ 世事如書,我偏爰你這一句,愿做個逗號,呆在你腳邊。但你有自己的朗讀者,而我只是個擺渡人王滤『厣” (一)你還是你,一...
    豆四吧閱讀 232評論 0 1