好久沒有寫文章了,這篇介紹一個(gè)工作中遇到的功能和相關(guān)設(shè)計(jì)佑稠,其中涉及到的幾個(gè)點(diǎn)還是值得深入考慮下,簡單做個(gè)記錄孽江。
業(yè)務(wù)場(chǎng)景
實(shí)際是一個(gè)數(shù)據(jù)統(tǒng)計(jì)的需求讶坯,比如我們?cè)谑褂梦⒉┑臅r(shí)候,會(huì)記錄有多少人評(píng)論岗屏,發(fā)布多少評(píng)論辆琅,收到多少評(píng)論等交互信息。與之類似这刷,這個(gè)需求詳細(xì)描述的話有如下5個(gè)指標(biāo)要提供婉烟。
1、用戶發(fā)布的內(nèi)容數(shù)暇屋;
2似袁、用戶內(nèi)容得到的分享數(shù)
3、用戶分享的內(nèi)容數(shù);
4昙衅、用戶給他人的評(píng)論數(shù)扬霜;
5、用戶內(nèi)容獲得的評(píng)論數(shù)而涉;
概要設(shè)計(jì)
問題一
用戶發(fā)布的內(nèi)容數(shù)
首先著瓶,第一個(gè)用戶發(fā)布的內(nèi)容數(shù),這個(gè)其實(shí)只要在用戶發(fā)布的時(shí)候做記錄就可以了啼县。這個(gè)是一種基礎(chǔ)的方案材原,另外有一種場(chǎng)景是,這個(gè)發(fā)布的內(nèi)容需要審核季眷。內(nèi)容只記錄有效內(nèi)容余蟹,這個(gè)場(chǎng)景下,有三種解決方法:1)如果有消息組件子刮,在完成審核之后推送消息來統(tǒng)計(jì)威酒。2)沒有消息組件或者不完善可以用借口回調(diào)做統(tǒng)計(jì)。3)比較笨拙的方法话告,固定時(shí)間后主動(dòng)調(diào)用接口獲得統(tǒng)計(jì)數(shù)據(jù)兼搏。但是會(huì)有問題,審核如果是人工的沙郭,往往不會(huì)是固定周期完成佛呻,因此不推薦。操作其實(shí)就是分享之后給authorId 對(duì)應(yīng)的pub_count+1病线。
問題二
用戶內(nèi)容獲得的分享數(shù)
這里倆問題吓著,計(jì)數(shù)的是內(nèi)容還是分享的人次,是否需要去重送挑。這里我們看下绑莺,首先有三個(gè)關(guān)鍵參數(shù),內(nèi)容ID惕耕,分享者纺裁,內(nèi)容作者,即contentId
,sharedBy
,authorId
司澎。用戶內(nèi)容獲得的分享數(shù)欺缘,假設(shè)去重,就用 sharedBy + contentId 判斷是否已經(jīng)分享挤安,否則設(shè)置標(biāo)簽并給對(duì)應(yīng)的authorId的recv_shared_count + 1谚殊。當(dāng)然這里如果是記錄分享人次,則用authorId + sharedBy去重蛤铜,效果就是只要用戶A分享過B的內(nèi)容嫩絮,就算一人次計(jì)數(shù)丛肢,且以后再分享都不算。
問題三
用戶分享的內(nèi)容數(shù)
這個(gè)比較簡單剿干,用sharedBy + contentId做去重蜂怎,然后按結(jié)果給對(duì)應(yīng)的sharedBy的shared_count+1
問題四
用戶給他人的評(píng)論數(shù)
這個(gè)是比較復(fù)雜的一個(gè)功能,有很多的情況置尔。首先派敷,評(píng)論一般是在一個(gè)內(nèi)容下的,回復(fù)內(nèi)容算作一級(jí)評(píng)論撰洗,當(dāng)然還有回復(fù)評(píng)論,會(huì)有多級(jí)的評(píng)論回復(fù)腐芍。如果是統(tǒng)計(jì)人次差导,還有個(gè)場(chǎng)景就是A發(fā)內(nèi)容,B評(píng)論A猪勇,C評(píng)論B的評(píng)論设褐,這種情況到底算給誰的評(píng)論,這里我們默認(rèn)也算作給A的評(píng)論泣刹,因?yàn)槎际窃贏的內(nèi)容下助析。還有一種比較特殊就是,在別人的內(nèi)容下自己回復(fù)自己的評(píng)論是不是要計(jì)數(shù)椅您,雖然這個(gè)情況比較少外冀,其實(shí)也可以加但可能會(huì)有hash key 放大的風(fēng)險(xiǎn),因?yàn)橛衷黾恿艘粋€(gè)維度的統(tǒng)計(jì)掀泳。
這個(gè)還是內(nèi)容的評(píng)論數(shù)雪隧,不是用戶評(píng)論了多少人,還是以內(nèi)容來判斷的员舵。首先脑沿,發(fā)布評(píng)論之后,有幾個(gè)參數(shù):內(nèi)容id,評(píng)論者马僻,內(nèi)容作者庄拇,即contentId
,commenter
,authorId
,首先用authorId和commenter過濾自己給自己的評(píng)論韭邓。其次給對(duì)應(yīng)的commenter的comment_count + 1
問題五
用戶內(nèi)容獲得評(píng)論數(shù)
這個(gè)還是以內(nèi)容計(jì)數(shù)的措近,在評(píng)論的時(shí)候會(huì)有三個(gè)參數(shù),評(píng)論者仍秤,內(nèi)容作者熄诡,內(nèi)容id,即commenter
,authorId
,contentId
诗力,首先過濾自己給自己內(nèi)容評(píng)論(他人內(nèi)容下自己回復(fù)自己評(píng)論不過濾)凰浮,最后給對(duì)應(yīng)的authorId的recv_comment_count+1我抠。
技術(shù)選型和設(shè)計(jì)
具體要使用哪種技術(shù),其實(shí)是和業(yè)務(wù)緊密相關(guān)的袜茧。首先我們可以看到類似exist和incr的操作菜拓,直觀的是使用Redis,但Redis涉及到集群維護(hù)以及持久化的問題笛厦,如果有成熟的環(huán)境可以直接來用就方便了纳鼎。持久化除了依賴Redis當(dāng)然也可以自己維護(hù),比如用任務(wù)刷到數(shù)據(jù)庫等等裳凸。其次可以考慮MySQL持久化贱鄙,如唯一鍵等特性,當(dāng)然也可以自己維護(hù)邏輯關(guān)系姨谷。其他比如Pegasus等也可以使用逗宁。
聰明的同學(xué)已經(jīng)看到給別人評(píng)論和收到評(píng)論,以及分享別人內(nèi)容和獲得分享是有關(guān)聯(lián)的梦湘。的確設(shè)計(jì)的時(shí)候這兩種情況是在一起考慮的瞎颗。以下是整體的設(shè)計(jì)方案和偽代碼。
1捌议、結(jié)構(gòu)
pub_count; //發(fā)布內(nèi)容數(shù)
shared_count;//分享內(nèi)容數(shù)
comment_count;//發(fā)布評(píng)論數(shù)
recv_comment_count;//內(nèi)容獲得評(píng)論數(shù)
recv_shared_count;//內(nèi)容獲得分享數(shù)
}
2哼拔、業(yè)務(wù)偽代碼
incrPubCount(authorId){
incr(authorId+pub_count);
}
incrSharedCount(sharedBy,authorId,contentId){
if(exist(sharedBy+contentId) || sharedBy == authorId){
return;
}else{
set(sharedBy+contentId);
incr(sharedBy+shared_count);
incr(authorId+recv_shared_count);
}
}
//具體按人次還是按內(nèi)容依據(jù)情況修改。
incrCommentCount(commenter,authorId,contentId){
if(authorId == commenter){
return;
}else{
incr(commenter+comment_count);
incr(authorId+recv_comment_count);
}
}
總結(jié)
以上就是回顧的所有內(nèi)容瓣颅,某些方面還是有待完善倦逐,比如數(shù)據(jù)量非常大的時(shí)候的存儲(chǔ)選型;某些異常的時(shí)候狀態(tài)可能不一致的問題弄捕,如:A分享B僻孝,A分享計(jì)數(shù)增加,但B獲得分享計(jì)數(shù)增加失敗的情況守谓。這種問題其實(shí)非常典型穿铆,類似銀行轉(zhuǎn)賬的,只是這個(gè)是兩邊都增加斋荞。也因?yàn)闃I(yè)務(wù)不需要這么嚴(yán)謹(jǐn)荞雏,而且主要是每個(gè)具體操作比較簡單,可以看做是原子的平酿,依賴服務(wù)失敗幾率比較小凤优,失敗后再重試或者回滾成功的可能也比較小,因此沒有再做更復(fù)雜的容錯(cuò)方案蜈彼。感興趣的朋友可以再深入了解下一致性相關(guān)內(nèi)容筑辨。
還有一個(gè)是這個(gè)需求統(tǒng)計(jì)相關(guān),可以用異步流程實(shí)現(xiàn)幸逆,如spring的async注解棍辕,以后有時(shí)間單獨(dú)開篇文章介紹下暮现。
以上,感謝閱讀楚昭。