楊老板在群里討論了一個系統(tǒng)設(shè)計(jì)題的內(nèi)容。
聊天系統(tǒng)后臺怎么存聊天記錄?
開宇提出declearing
看需求了 什么樣的業(yè)務(wù)模型,以后怎樣scale。比如 支不支持group 支不支持群發(fā)。語音 圖片。
楊老板提出進(jìn)階
比如只是文字,當(dāng)然是大型的,先不說群發(fā)。Nosql 用什么,Cassandra? 存成什么形式,怎么查找。
Beny提出細(xì)節(jié):
先討論問題范圍吧:
1)要存多久?能否刪除?
2)是否有搜索的需要?有無搜索的實(shí)效性需求?對舊信息的搜索需求?
3)群消息還是單獨(dú)的消息居多?當(dāng)然可以共存,但是如果有側(cè)重可以進(jìn)行特殊處理。
4)預(yù)計(jì)用戶量和寫入量是多少?可以估計(jì)peak traffic和存儲量的需求。
等你快速過完problem definiation再開始討論設(shè)計(jì),思路會清晰一點(diǎn)。
特殊消息類型例如圖片、表情、視頻也可以特殊討論。
感覺存儲和搜索是兩個主要需求,要大概估算需要存多少數(shù)據(jù)量。
第一印象是分層存儲,信息和索引都要存下來,老信息加上他們的索引可以寫到file system、較新信息放storage(nosql)、需要快速讀取、推送的新信息放cache。需要考慮multi-Data center的寫入速度和錯誤處理,寫入需要回執(zhí)確認(rèn)成功,為了提高寫入速度可以考慮支持物理層支持同時在disk兩端寫入。
每個人有自己的index,按時刪除過時的部分,搜索應(yīng)該可以支持分頁,先搜新信息,后搜舊信息。
討論的時候可以根據(jù)不同的constrain調(diào)整你的設(shè)計(jì),例如QPS 乘100倍的情況會怎樣,支持圖片、視頻這類大文件的情況如何支持。
楊老板小結(jié)
這是一道很常見的題面試。比如就是Facebook messager, 總流量很大。
圖片,視頻那些無所謂,在聊天記錄里肯定是存鏈接或者id。假設(shè)沒有搜索,沒有刪除,先不考慮群聊。Query就是個返回某個時間段的聊天記錄。
另一個問題:nosql里,data具體怎么存?是table還是簡單的key value pair?
query是什么樣子的?
例如A給B發(fā)了一條信息,給C發(fā)了一條信息,然后收了D一條信息。
你的query結(jié)果是不是:
query(A, begin, end) ->
{
to B: xxxx
to C: xxxx
from D: xxxx
}
應(yīng)該是(uid, timestamp, mid) 比較合適。畢竟有同時發(fā)送、接收的信息。
用這樣的key,可以取字段時間的兩人聊天記錄嗎?
可以的
這并不是幾個字符構(gòu)成的string,對于noSQL來說他們支持這類復(fù)合的key,我記得是實(shí)際上是某個帶有索引功能的 hash,具體實(shí)現(xiàn)就不清楚了。
曉斌接上
只能按prefix搜索。
在后面的key拿不到只能說全表查然后手動filter。如果prefix太接近了 好像某一個node會造成瓶頸。如果prefix太接近了 好像某一個node會造成瓶頸。我一直覺得這個可以搞一個通用的解決方案然后開源一下。
end