原文出處:http://weibo.com/p/1001643880172431480781
作者:唐揚(yáng),@唐揚(yáng)TY
未讀提醒功能在各種社交平臺(tái)服務(wù)中較為常見(jiàn),在微博中這些功能由Unread服務(wù)來(lái)提供??此坪?jiǎn)單的功能,當(dāng)請(qǐng)求量級(jí)達(dá)到一定規(guī)模后,成本、性能、穩(wěn)定性的平衡將是架構(gòu)設(shè)計(jì)的重點(diǎn)。
大綱
在以timeline為核心的微博業(yè)務(wù)中, 未讀數(shù)場(chǎng)景出現(xiàn)的頻率較高,它可以是這樣的…
也可以是這樣的…
通過(guò)分析和比較這些未讀場(chǎng)景,我們抽象了unread服務(wù)中設(shè)計(jì)到的三種主要操作:
1.?incr:增加未讀數(shù)
2.?reset:未讀數(shù)清零
3.?get:獲取未讀數(shù)
我們發(fā)現(xiàn)unread服務(wù)中g(shù)et操作是典型的無(wú)觸發(fā)操作,即不需要用戶執(zhí)行任何操作都會(huì)對(duì)服務(wù)器造成請(qǐng)求。正是這個(gè)特點(diǎn)給unread服務(wù)帶來(lái)如下問(wèn)題:
1.?高并發(fā):高峰期單一業(yè)務(wù)的qps達(dá)到10萬(wàn)+
2.?性能要求高:接口4個(gè)9的響應(yīng)時(shí)間在10ms
為了解決上述問(wèn)題,unread架構(gòu)針對(duì)不同的業(yè)務(wù)場(chǎng)景設(shè)計(jì)了不同的方案,保證了服務(wù)的高性能、高可用和可擴(kuò)展。本文主要針對(duì)三種典型的未讀數(shù)場(chǎng)景介紹微博平臺(tái)是如何設(shè)計(jì)解決方案的。
在這種場(chǎng)景下,用戶的某一個(gè)操作只會(huì)影響一個(gè)用戶的未讀數(shù)字。典型的場(chǎng)景有:@未讀提醒、評(píng)論未讀提醒、贊評(píng)論提醒等等。
針對(duì)這種場(chǎng)景,我們采用最簡(jiǎn)單的解決方案:為每一個(gè)用戶存儲(chǔ)一份未讀數(shù)字,如下圖
在設(shè)計(jì)的實(shí)現(xiàn)中,由于存儲(chǔ)容量可控,我們采用redis存儲(chǔ)未讀數(shù)。相比于通常使用的mysql+mc的存儲(chǔ)解決方案,redis有以下的優(yōu)勢(shì):
1.?存儲(chǔ)一體化,避免了緩存和持久化存儲(chǔ)之間一致性的問(wèn)題
2.?快速恢復(fù)
這個(gè)設(shè)計(jì)方案主要基于如下的考慮:
1.?簡(jiǎn)單直觀
2.?性能能夠達(dá)到SLA,每次操作只需要訪問(wèn)一次資源
打點(diǎn)主要指微博官方客戶端中的一些弱提醒功能,見(jiàn)下圖中的紅點(diǎn)
而全量打點(diǎn)指對(duì)全量用戶都增加未讀提醒紅點(diǎn)??紤]到目前微博的用戶量,如果采用第一種場(chǎng)景的方案,打點(diǎn)過(guò)程會(huì)存在很大的延遲。因此我們采用了基于tag的解決方案。
1.?存儲(chǔ)公共的時(shí)間戳global
2.?每一個(gè)用戶存儲(chǔ)一個(gè)時(shí)間戳
3.?打點(diǎn)時(shí),更新global時(shí)間戳為當(dāng)前時(shí)間
4.?消點(diǎn)時(shí),更新用戶的時(shí)間戳為global時(shí)間戳
5.?如果用戶時(shí)間戳小于global時(shí)間戳,則有點(diǎn);否則沒(méi)有點(diǎn)
這個(gè)方案適用于用戶間存在共享存儲(chǔ),且共享存儲(chǔ)有限的場(chǎng)景。在這種場(chǎng)景下,我們?yōu)槊恳粋€(gè)用戶存儲(chǔ)一個(gè)tag用來(lái)記錄用戶在共享存儲(chǔ)中的已讀位置,這樣就可以通過(guò)比較這個(gè)已讀位置獲得用戶的未讀數(shù)。
在實(shí)際的應(yīng)用過(guò)程中,我們通常會(huì)使用本地緩存來(lái)解決訪問(wèn)共享存儲(chǔ)的極端峰值。這種基于已讀位置的解決方案雖然能很好的解決全量打點(diǎn)的問(wèn)題,但是面對(duì)訪問(wèn)量最大的微博未讀數(shù)場(chǎng)景卻是無(wú)能為力,原因有二:
1.?用戶的feed是無(wú)限的,不存在共享存儲(chǔ),全部存儲(chǔ)下來(lái)的成本很高
2.?在高并發(fā)下獲取未讀數(shù)操作性能衰減嚴(yán)重
我們采用了下面這種方案來(lái)解決微博未讀數(shù)問(wèn)題。
眾所周知,微博未讀數(shù)就是微博主feed未讀數(shù),當(dāng)我關(guān)注的人發(fā)表一條微博,我的微博未讀數(shù)提醒就會(huì)加一。
對(duì)于微博微博數(shù)場(chǎng)景,我們采用了基于snapshot的解決方案,具體如圖所示:
更多建議: