订单中心,1亿数据架构,这次服了
訂單中心,是互聯(lián)網(wǎng)業(yè)務(wù)中,一個典型的“多key”業(yè)務(wù),即:用戶ID,商家ID,訂單ID等多個key上都有業(yè)務(wù)查詢需求。
隨著數(shù)據(jù)量的逐步增大,并發(fā)量的逐步增大,訂單中心這種“多key”業(yè)務(wù),架構(gòu)應(yīng)該如何設(shè)計,有哪些因素需要考慮,是本文將要系統(tǒng)性討論的問題。
什么是“多key”類業(yè)務(wù)?
所謂的“多key”,是指一條元數(shù)據(jù)中,有多個屬性上存在前臺在線查詢需求。
訂單中心是什么業(yè)務(wù),有什么典型業(yè)務(wù)需求?
訂單中心是一個非常常見的“多key”業(yè)務(wù),主要提供訂單的查詢與修改的服務(wù),其核心元數(shù)據(jù)為:
Order(oid, buyer_uid, seller_uid, time, money, detail…);
其中:
(1)oid為訂單ID,主鍵;
(2)buyer_uid為買家uid;
(3)seller_uid為賣家uid;
(4)time, money, detail, …等為訂單屬性;
數(shù)據(jù)庫設(shè)計上,一般來說在業(yè)務(wù)初期,單庫,配合查詢字段上的索引,就能滿足元數(shù)據(jù)存儲與查詢需求。
(1)order-center:訂單中心服務(wù),對調(diào)用者提供友好的RPC接口;
(2)order-db:對訂單進(jìn)行數(shù)據(jù)存儲,并在訂單,買家,賣家等字段建立索引;
隨著訂單量的越來越大,數(shù)據(jù)庫需要進(jìn)行水平切分,由于存在多個key上的查詢需求,用哪個字段進(jìn)行切分呢?
(1)如果用oid來切分,buyer_uid和seller_uid上的查詢則需要遍歷多庫;
(2)如果用buyer_uid或seller_uid來切分,其他屬性上的查詢則需要遍歷多庫;
總之,很難有一個萬全之策,在展開技術(shù)方案之前,先一起梳理梳理查詢需求。
任何脫離業(yè)務(wù)需求的架構(gòu)設(shè)計,都是耍流氓。
訂單中心,典型業(yè)務(wù)查詢需求有哪些?
第一類,前臺訪問,最典型的有三類需求:
(1)訂單實體查詢:通過oid查詢訂單實體,90%流量屬于這類需求;
(2)用戶訂單列表查詢:通過buyer_uid分頁查詢用戶歷史訂單列表,9%流量屬于這類需求;
(3)商家訂單列表查詢:通過seller_uid分頁查詢商家歷史訂單列表,1%流量屬于這類需求;
前臺訪問的特點是什么呢?
吞吐量大,服務(wù)要求高可用,用戶對訂單的訪問一致性要求高,商家對訂單的訪問一致性要求相對較低,可以接受一定時間的延時。
第二類,后臺訪問,根據(jù)產(chǎn)品、運營需求,訪問模式各異:
(1)按照時間,價格,商品,詳情來進(jìn)行查詢;
后臺訪問的特點是什么呢?
運營側(cè)的查詢基本上是批量分頁的查詢,由于是內(nèi)部系統(tǒng),訪問量很低,對可用性的要求不高,對一致性的要求也沒這么嚴(yán)格,允許秒級甚至十秒級別的查詢延時。
?
這兩類不同的業(yè)務(wù)需求,應(yīng)該使用什么樣的架構(gòu)方案來解決呢?
要點一:前臺與后臺分離的架構(gòu)設(shè)計。
如果前臺業(yè)務(wù)和后臺業(yè)務(wù)共用一批服務(wù)和一個數(shù)據(jù)庫,有可能導(dǎo)致,由于后臺的“少數(shù)幾個請求”的“批量查詢”的“低效”訪問,導(dǎo)致數(shù)據(jù)庫的cpu偶爾瞬時100%,影響前臺正常用戶的訪問(例如,訂單查詢超時)。
前臺與后臺訪問的查詢需求不同,對系統(tǒng)的要求也不一樣,故應(yīng)該兩者解耦,實施“前臺與后臺分離”的架構(gòu)設(shè)計。
前臺業(yè)務(wù)架構(gòu)不變,站點訪問,服務(wù)分層,數(shù)據(jù)庫水平切分。
后臺業(yè)務(wù)需求則抽取獨立的web/service/db來支持,解除系統(tǒng)之間的耦合,對于“業(yè)務(wù)復(fù)雜”“并發(fā)量低”“無需高可用”“能接受一定延時”的后臺業(yè)務(wù):
(1)可以去掉service層,在運營后臺web層通過dao直接訪問數(shù)據(jù)層;
(2)可以不需要反向代理,不需要集群冗余;
(3)可以通過MQ或者線下異步同步數(shù)據(jù),犧牲一些數(shù)據(jù)的實時性;
(4)可以使用更契合大量數(shù)據(jù)允許接受更高延時的“索引外置”或者“HIVE”的設(shè)計方案;
?
關(guān)于前臺與后臺分離的架構(gòu)設(shè)計,在《用戶中心,1億數(shù)據(jù)架構(gòu),這次服了》一文中有更為細(xì)致的分析,便不再展開。
解決完了后臺業(yè)務(wù)的訪問需求,那前臺的oid,buyer_uid,seller_uid如何來進(jìn)行數(shù)據(jù)庫水平切分呢?
要點二:多個維度的查詢較為復(fù)雜,對于復(fù)雜系統(tǒng)設(shè)計,應(yīng)該逐個擊破。
假設(shè)沒有seller_uid,應(yīng)該如何擊破oid和buyer_uid的查詢需求?
訂單中心,假設(shè)只有oid和buyer_uid上的查詢需求,就蛻化為一個“1對多”的業(yè)務(wù)場景,對于“1對多”的業(yè)務(wù),水平切分應(yīng)該使用“基因法”。
要點三:基因法,是解決“1對多”業(yè)務(wù),數(shù)據(jù)庫水平切分的常見方案。
什么是分庫基因?
通過buyer_uid分庫,假設(shè)分為16個庫,采用buyer_uid%16的方式來進(jìn)行數(shù)據(jù)庫路由,所謂的模16,其本質(zhì)是buyer_uid的最后4個bit決定這行數(shù)據(jù)落在哪個庫上,這4個bit,就是分庫基因。
什么是基因法分庫?
在訂單數(shù)據(jù)oid生成時,oid末端加入分庫基因,讓同一個buyer_uid下的所有訂單都含有相同基因,落在同一個分庫上。
如上圖所示,buyer_uid=666的用戶下了一個訂單:
(1)使用buyer_uid%16分庫,決定這行數(shù)據(jù)要插入到哪個庫中;
(2)分庫基因是buyer_uid的最后4個bit,即1010;
(3)在生成訂單標(biāo)識oid時,先使用一種分布式ID生成算法生成前60bit(上圖中綠色部分);
(4)將分庫基因加入到oid的最后4個bit(上圖中粉色部分),拼裝成最終64bit的訂單oid(上圖中藍(lán)色部分);
?
通過這種方法保證,同一個用戶下的所有訂單oid,都落在同一個庫上,oid的最后4個bit都相同,于是:
(1)通過buyer_uid%16能夠定位到庫;
(2)通過oid%16也能定位到庫;
關(guān)于“一對多”業(yè)務(wù),以及“基因法”,在《帖子中心,1億數(shù)據(jù)架構(gòu),這次服了》一文中有更為細(xì)致的分析,便不再展開。
假設(shè)沒有oid,應(yīng)該如何擊破buyer_uid和seller_uid的查詢需求?
訂單中心,假設(shè)只有buyer_uid和seller_uid上的查詢需求,就蛻化為一個“多對多”的業(yè)務(wù)場景,對于“多對多”的業(yè)務(wù),水平切分應(yīng)該使用“數(shù)據(jù)冗余法”。
如上圖所示:
(1)當(dāng)有訂單生成時,通過buyer_uid分庫,oid中融入分庫基因,寫入DB-buyer庫;
(2)通過線下異步的方式,通過binlog+canal,將數(shù)據(jù)冗余到DB-seller庫中;
(3)buyer庫通過buyer_uid分庫,seller庫通過seller_uid分庫,前者滿足oid和buyer_uid的查詢需求,后者滿足seller_uid的查詢需求;
?
數(shù)據(jù)冗余的方法有很多種:
(1)服務(wù)同步雙寫;
(2)服務(wù)異步雙寫;
(3)線下異步雙寫(上圖所示,是線下異步雙寫);
?
要點四:數(shù)據(jù)冗余,是解決“多對多”業(yè)務(wù),數(shù)據(jù)庫水平切分的常見方案。
?
不管哪種方案,因為兩步操作不能保證原子性,總有出現(xiàn)數(shù)據(jù)不一致的可能,高吞吐分布式事務(wù)是業(yè)內(nèi)尚未解決的難題,此時的架構(gòu)方向,是最終一致性,并不是完全保證數(shù)據(jù)的一致,而是盡早的發(fā)現(xiàn)不一致,并修復(fù)不一致。
?
要點五:最終一致性,是高吞吐互聯(lián)網(wǎng)業(yè)務(wù)一致性的常用實踐。
?
保證冗余數(shù)據(jù)最終一致的常見方案有三種:
(1)冗余數(shù)據(jù)全量定時掃描;
(2)冗余數(shù)據(jù)增量日志掃描;
(3)冗余數(shù)據(jù)線上消息實時檢測;
?
關(guān)于“多對多”業(yè)務(wù),數(shù)據(jù)冗余多種方案,數(shù)據(jù)冗余保證最終一致性多種方案,在《好友中心,1億數(shù)據(jù)架構(gòu),這次服了》一文中有更為細(xì)致的分析,便不再展開。
那如果oid/buyer_uid/seller_uid同時存在呢?
綜合上面的解決方案即可:
(1)如果沒有seller_uid,“多key”業(yè)務(wù)會蛻化為“1對多”業(yè)務(wù),此時應(yīng)該使用“基因法”分庫:使用buyer_uid分庫,在oid中加入分庫基因;
(2)如果沒有oid,“多key”業(yè)務(wù)會蛻化為“多對多”業(yè)務(wù),此時應(yīng)該使用“數(shù)據(jù)冗余法”分庫:使用buyer_uid和seller_uid來分別分庫,冗余數(shù)據(jù),滿足不同屬性上的查詢需求;
(3)如果oid/buyer_uid/seller_uid同時存在,可以使用上述兩種方案的綜合方案,來解決“多key”業(yè)務(wù)的數(shù)據(jù)庫水平切分難題;
?
要點總結(jié)
一:前后臺差異化需求,可使用前臺與后臺分離的架構(gòu)設(shè)計;
二:對于復(fù)雜系統(tǒng)設(shè)計,應(yīng)該逐個擊破;
三:基因法,是解決“1對多”業(yè)務(wù),數(shù)據(jù)庫水平切分的常見方案;
四:數(shù)據(jù)冗余,是解決“多對多”業(yè)務(wù),數(shù)據(jù)庫水平切分的常見方案;
五:最終一致性,是高吞吐互聯(lián)網(wǎng)業(yè)務(wù)一致性的常用實踐。
?
相關(guān)文章:
《用戶中心,1億數(shù)據(jù)架構(gòu),這次服了》
《帖子中心,1億數(shù)據(jù)架構(gòu),這次服了》
《好友中心,1億數(shù)據(jù)架構(gòu),這次服了》
任何脫離業(yè)務(wù)的架構(gòu)設(shè)計都是耍流氓,共勉。
?
文章來源:https://mp.weixin.qq.com/s/AVGc7JskhKxG0iPQBX5J1w
總結(jié)
以上是生活随笔為你收集整理的订单中心,1亿数据架构,这次服了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于美国哥伦比亚大学以华人命名教席的资料
- 下一篇: ios 加载大量图片崩溃_加载高清大图崩