類淘寶千億量級(jí)超大規(guī)模電商系統(tǒng)后端數(shù)據(jù)庫設(shè)計(jì)實(shí)踐
時(shí)間:2023-06-02 04:42:01 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-06-02 04:42:01 來源:網(wǎng)站運(yùn)營
類淘寶千億量級(jí)超大規(guī)模電商系統(tǒng)后端數(shù)據(jù)庫設(shè)計(jì)實(shí)踐:
問題背景 電商網(wǎng)站如
http://jd.com,
http://tmall.com等,訂單數(shù)據(jù)一直在膨脹,每年產(chǎn)生個(gè)一兩千億那都是正常,要知道人家阿里11.11那天,平均每一秒鐘就產(chǎn)生15.7w筆訂單,這么算下來當(dāng)天大概產(chǎn)生了15.7*10000*86400=13,564,800,000,嗯,135.65億。問題:像這樣超大規(guī)模訂單的數(shù)據(jù)存儲(chǔ),如果事先沒有設(shè)計(jì)好可擴(kuò)展的數(shù)據(jù)架構(gòu)方案和容災(zāi)方案,不久的將來肯定會(huì)抵達(dá)性能瓶頸值,成為限制業(yè)務(wù)發(fā)展的首要技術(shù)難題。
分庫分表的維度選擇 通常來說分庫分表都是通過訂單id經(jīng)過簡單hash算法得到一個(gè)數(shù)字hash,然后采用hash值的后五位mod|1024(32*32=1024),先對(duì)庫表進(jìn)行分組編號(hào)1-1024,進(jìn)而得到這個(gè)訂單id應(yīng)該路由到那個(gè)編號(hào)的表中。當(dāng)然咯,這里最好保持hash數(shù)值的后五位數(shù)能夠以最大的隨機(jī)性命中這1024張表中的任何一張,但出現(xiàn)了新的問題:這樣分庫分表還是
無法解決若干個(gè)數(shù)據(jù)庫的若干個(gè)表讀寫IO很高的問題。
面臨的幾個(gè)問題 分庫分表訂單id如何高效生成?snowflake算法嗎?不建議。分庫分表的最終目的是為了服務(wù)用戶,同時(shí)便于開發(fā)運(yùn)維以及銷售運(yùn)營等系統(tǒng)的設(shè)計(jì),所以我們應(yīng)該以用戶為主線,從user_id出發(fā),所有與此用戶(包含客戶和商家)相關(guān)的訂單,產(chǎn)品,禮品,評(píng)論,簽到等一系列表都應(yīng)該按照既定的原則存放在同一份庫表里面,方便進(jìn)行相關(guān)信息的整合查詢,現(xiàn)在回到訂單id如何生成的問題,先讓新的訂單表根據(jù)用戶信息路由到指定的庫表(例如db89_table19)中,讓數(shù)據(jù)庫幫我們生成一個(gè)表訂單的自增id(100089),于是我們得到了訂單的guid(db89_table19_order100089),當(dāng)然我們寫數(shù)據(jù)接口的時(shí)候肯定不能直接傳這個(gè)guid,這個(gè)屬于安全意識(shí)問題,因此我們使用不可逆加密算法生成對(duì)應(yīng)的訂單enctrypted_id(111sakhkhsa121hksajj1687971),并放入訂單的全局ht_order的guid_kv(guid=>enctrypted_order_id)映射關(guān)系中。接著,引出了新的問題:某些用戶表的容量已經(jīng)達(dá)到了系統(tǒng)高性能實(shí)踐所允許的閾值(假設(shè)每臺(tái)機(jī)器的單表閾值是同一個(gè)常量值K),這時(shí)應(yīng)該把新注冊(cè)的用戶數(shù)據(jù)放在哪個(gè)庫對(duì)應(yīng)的哪張表呢?解決辦法是這樣的,通過monitor服務(wù)器的來存放這些字段信息ht_load_balance(db_index,table_index,day_[read/write]_[peak|valley],month_[read/write]_[peak|valley],year_[read/write]_[peak|valley],total_count),這張表用于記錄指定庫指定表的負(fù)載統(tǒng)計(jì)情況,它統(tǒng)計(jì)的最小維度是day(天),接著需要把db和table的負(fù)載情況按照指定的算法進(jìn)行排序(load_balance_weight_rank),然后把排序得到的權(quán)重結(jié)果緩存起來得到(load_balance_weight_rank_cache),并把排序結(jié)果更新到系統(tǒng)共用緩存區(qū)(同步計(jì)劃的執(zhí)行時(shí)間根據(jù)以往經(jīng)驗(yàn)固定在凌晨3-5點(diǎn)之間執(zhí)行)。
緊接著我們就可以通過這個(gè)緩存權(quán)重結(jié)果來設(shè)計(jì)新數(shù)據(jù)的庫表路由選擇算法,算法的設(shè)計(jì)應(yīng)該盡量保證每一個(gè)數(shù)據(jù)庫,乃至每一個(gè)數(shù)據(jù)庫中的每一張表的的Read/Write的IO是均衡的,關(guān)于這個(gè)算法的選擇思路,請(qǐng)小伙伴們自己發(fā)揮想象力,在此就不打算深究了。現(xiàn)在假設(shè)新注冊(cè)一個(gè)用戶,通過上面的負(fù)載均衡算法路由到了db100,table1000,然后我們把新用戶的數(shù)據(jù)插入到表中得到一個(gè)自增id,接著問題來了,我們?cè)趺粗肋@個(gè)用戶的uid放在那張表呢?這個(gè)簡單,使用hashtable來存放ht_user(guid=>enctrypted_user_id),我們看到這是最簡單的kv store方式存儲(chǔ)的,google的基于GFS的分布式bigtable來存放,這些個(gè)速度都快得沒話說!于是我們把新的order_guid,product_guid,gift_guid,comment_guid都放到它們的guid_kv中,以便進(jìn)行路由查詢,但運(yùn)營和銷售又提出了新的問題。
1)運(yùn)營想搞一個(gè)促銷活動(dòng),打算向最近三個(gè)月購買總額超過2000元的客戶推送一條促銷的短信消息。好解決,分布式作業(yè),通過制定的查詢條件找到滿足條件的用戶手機(jī)號(hào)碼,接著發(fā)送短信。
2)運(yùn)營想知道銷售的主要來源區(qū)域便于加強(qiáng)運(yùn)營分析能力,當(dāng)然這個(gè)也簡單。
3)公司新推出了100款重點(diǎn)促銷的商品(分布在不同的庫表中),想知道這幾款商品的實(shí)時(shí)銷售量,點(diǎn)擊量,這個(gè)貌似也不難。
4)接下來,難點(diǎn)來了,銷售想知道商家的銷售額排行的前100w名,該怎么辦?這就有點(diǎn)難辦了!猿哥的解決思路還是創(chuàng)建一個(gè)(guid=>sale_amount)kv-store,用來存儲(chǔ)實(shí)時(shí)變更的銷售額信息,離線計(jì)算。
其它諸如大數(shù)據(jù)分析,離線任務(wù)(客戶端推送,短信群發(fā)等)都可以通過類似的思路解決。
系統(tǒng)可擴(kuò)展性通過上面的ht_load_balance負(fù)載均衡算法,我們知道了新來的用戶數(shù)據(jù)應(yīng)該放到那個(gè)數(shù)據(jù)庫,當(dāng)指定庫的指定表達(dá)到最佳性能數(shù)值時(shí)(假設(shè)total_count=500w條記錄,這個(gè)數(shù)值的選擇可以通過一些壓測(cè)模擬和生產(chǎn)統(tǒng)計(jì)手段分析得到)時(shí),我們添加一個(gè)新的數(shù)據(jù)庫服務(wù)器,并把數(shù)據(jù)庫初始化的庫表信息同步到ht_load_balance記錄中,那么新的用戶數(shù)據(jù)總是會(huì)命中新的數(shù)據(jù)庫服務(wù)器,并在一定的時(shí)候達(dá)到平衡,當(dāng)這個(gè)數(shù)據(jù)量快要達(dá)到臨界值的時(shí)候,系統(tǒng)管理員,快速響應(yīng),再次部署新的服務(wù)器,從而保證服務(wù)器的擴(kuò)展性。
系統(tǒng)的高可用性由于極小的故障概率可能會(huì)出現(xiàn)的原因,通常每一臺(tái)數(shù)據(jù)庫服務(wù)器都會(huì)有一到多臺(tái)地域彼此隔離的冷熱雙備服務(wù)器待命,就算其中一臺(tái)出現(xiàn)故障,服務(wù)器節(jié)點(diǎn)故障偵測(cè)到異常,會(huì)馬上進(jìn)行切換。
本文還有幾個(gè)主題- 舊數(shù)據(jù)遷移原則,例如騰訊qq超過一定的年限未使用便開始凍結(jié),甚至釋放重用,而這些數(shù)據(jù)都會(huì)被遷移到舊數(shù)據(jù)服務(wù)器中存底。
- LRU算法,讓最活躍的用戶享受最快速的服務(wù)。
- 。。。
當(dāng)然還有一些細(xì)節(jié)上的問題,限于篇幅和精力,本文就不在深究了,有興趣的小伙伴可以自己發(fā)散思維,盡情思考,爭(zhēng)取把這個(gè)世界架構(gòu)的妙不可言。
參考文章列表:
大眾點(diǎn)評(píng)訂單系統(tǒng)分庫分表實(shí)踐:http://tech.meituan.com/dianping_order_db_sharding.html
google bigtable:
http://baike.baidu.com/item/BigTable
關(guān)于bigtable的論文:
http://dblab.xmu.edu.cn/post/google-bigtable/
關(guān)鍵詞:系統(tǒng),數(shù)據(jù),實(shí)踐,設(shè)計(jì),規(guī)模