訂單表多維分庫分表解決方案

一刻剥、背景

訂單分庫分表不同于其他業(yè)務(wù)表分庫分表,訂單表的讀寫場景復(fù)雜滩字,一般有買家維度造虏、賣家維度御吞、訂單號維度3個主要維度。多讀寫維度情況下無論采取哪種維度做分庫分表漓藕,對另外兩種維度的查詢性能來說陶珠,基本都是災(zāi)難。而在電商項目中撵术,每個訂單從創(chuàng)建到終態(tài)往往都會經(jīng)歷上百個業(yè)務(wù)環(huán)節(jié)背率,任何一個環(huán)節(jié)出問題就會導(dǎo)致整單數(shù)據(jù)異常话瞧。所以交易系統(tǒng)可能不是技術(shù)難度最深的系統(tǒng)嫩与,但一定是業(yè)務(wù)復(fù)雜度最高、穩(wěn)定性要求最高的系統(tǒng)

二交排、訂單單表面臨的問題

訂單單表數(shù)據(jù)量大了之后一般會面臨以下問題:

  • 單表過大划滋,SQL RT過高
  • 數(shù)據(jù)庫實例負載過高
  • 單庫實例磁盤空間有限

以上都是比較嚴重的問題,如果不予以解決埃篓,將會嚴重影響機器性能处坪、限制業(yè)務(wù)發(fā)展

應(yīng)對以上問題一般常用的優(yōu)化思路如下:

  • 優(yōu)化SQL
  • 優(yōu)化索引
  • 優(yōu)化業(yè)務(wù)
  • 讀寫分離
  • 復(fù)雜查詢借助ES

僅通過以上優(yōu)化方式,數(shù)據(jù)量幾千萬后架专,業(yè)務(wù)高峰期還是頂不住同窘,壓測也壓不上去,這個時候就不得不采取分庫分表措施了部脚。

三想邦、拆分類型介紹

3.1 垂直(縱向)拆分

根據(jù)業(yè)務(wù)特性,與拆分微服務(wù)的做法相似委刘,將關(guān)聯(lián)度低或數(shù)據(jù)量巨大的不同表存儲在不同的數(shù)據(jù)庫丧没,或者將不經(jīng)常用或字段長度較大的字段拆分到擴展表中。

垂直(縱向)拆分

垂直拆分的優(yōu)點:

  • 降低業(yè)務(wù)表之前的耦合度锡移,層次分明
  • 一定程度上提升數(shù)據(jù)庫資源的性能瓶頸

垂直拆分的缺點:

  • 單表數(shù)據(jù)量過大的問題無法解決
  • 拆分過程對歷史業(yè)務(wù)改造較大

3.2 水平(橫向)拆分

將大表按照某個字段采取不同的路由函數(shù)分散到多個數(shù)據(jù)庫或多個表中呕童,表字段完全一致,每個表中只包含一部分數(shù)據(jù)淆珊,所有表加起來等于全量數(shù)據(jù)夺饲。

水平(橫向)拆分

水平拆分的優(yōu)點:

  • 有效解決單表數(shù)據(jù)量過大的問題,提升系統(tǒng)穩(wěn)定性和負載能力
  • 業(yè)務(wù)層面改造較小

水平拆分的缺點:

  • 所有業(yè)務(wù)SQL安全起見必須帶上分表鍵施符,如果不帶分表鍵查詢會掃全表钞支,性能極低
  • 需要自行解決全局唯一ID問題
  • 跨表查詢性能較差,只能通過接口聚合方式解決操刀,提升了開發(fā)的復(fù)雜度

四烁挟、常用分片算法

4.1、按時間維度(年/月/日)

比如按年/日分表骨坑,同一天的數(shù)據(jù)都能落在同一張分表撼嗓,后續(xù)訂單的查詢條件都必須帶上時間屬性

按時間維度拆分適用場景:

  • 業(yè)務(wù)跟時間關(guān)聯(lián)度高
  • 同一時間段內(nèi)業(yè)務(wù)數(shù)據(jù)量分布比較均勻
  • 適用于報表柬采、統(tǒng)計系統(tǒng)相關(guān)的業(yè)務(wù)

可行性分析:

按時間分庫分表比較難做,由于訂單業(yè)務(wù)邏輯繁多且警,不可能所有業(yè)務(wù)都有時間作為劃分粉捻,即使帶上時間屬性,業(yè)務(wù)查詢時數(shù)據(jù)庫壓力分布也是在很小范圍內(nèi)斑芜,并不能減輕實例負載肩刃,所以并不適合訂單分庫分表的場景。時間可以作為后續(xù)做冷熱分離的條件杏头。

4.2盈包、HASH

HASH函數(shù)的算法是簡單取模,若分庫和分表使用不同拆分鍵進行HASH時醇王,則根據(jù)分庫鍵的鍵值直接按分庫數(shù)取模呢燥,如果鍵值是字符串,則字符串會先被換算成哈希值再進行路由計算寓娩。若分庫和分表都使用同一個拆分鍵進行HASH時叛氨,則根據(jù)拆分鍵的鍵值按總的分表數(shù)取模。

以t_user表為例棘伴,拆分成8個庫寞埠,每個庫8張表:


HASH適用場景:

  • 一個分表鍵夠用
  • 適合于需要按用戶ID或訂單ID進行分庫分表的場景
  • 適合于拆分鍵是數(shù)字、字符串類型的場景

可行性分析:

采用HASH函數(shù)進行分庫分表焊夸,考慮到訂單會有按買家仁连、按賣家、按訂單號3種主要查詢場景淳地,就需要分別以買家ID怖糊、賣家ID、訂單號3個維度去做3個不同的分庫分表颇象。這種分庫分表方式可行伍伤。但是數(shù)據(jù)就會有3份,存儲是需要考慮先按哪個維度遣钳、再按哪個維度扰魂、最后按什么維度,所以數(shù)據(jù)存儲流程拉長了蕴茴,出異常的可能性變大劝评,對業(yè)務(wù)不太友好

4.3、RANGE_HASH

選取兩個拆分鍵倦淀,兩個拆分鍵的后N位需確保一致蒋畜,根據(jù)任一拆分鍵后N位計算哈希值,然后再按分庫數(shù)取模撞叽,完成路由計算姻成。此路由方式需要自行實現(xiàn)分片算法

以t_order表為例插龄,拆分成8個庫,每個庫8張表:


RANGE_HASH適用場景:

  • 兩個拆分鍵有關(guān)聯(lián)
  • 查詢時有其中一個拆分鍵值的場景

可行性分析:

如果采取RANGE_HASH函數(shù)作為分庫分表科展,則最優(yōu)方案是以訂單號和買家id的后N位做分庫分表均牢,后續(xù)按訂單號維度、買家id維度查詢都能滿足才睹,賣家維度無法查詢徘跪。但是前提是訂單號后幾位和買家id要有關(guān)聯(lián),涉及到訂單號改造的過程琅攘。

五垮庐、拆分工具

ShardingSphere

在拆分工具選擇上,這里借助ShardingSphere官網(wǎng)乎澄,ShardingSphere是一套開源的分布式數(shù)據(jù)庫解決方案組成的生態(tài)圈突硝,它們能提供數(shù)據(jù)分片测摔、分布式事務(wù)置济、分布式治理等功能。

如果對ShardingSphere原理锋八、使用感興趣浙于,大家可以去ShardingSphere官網(wǎng)進一步學(xué)習(xí)

六、訂單分庫分表

6.1挟纱、訂單表主要服務(wù)的讀寫場景

  • 根據(jù)買家id查詢
  • 根據(jù)賣家id查詢
  • 各個業(yè)務(wù)環(huán)節(jié)羞酗、下游應(yīng)用中大量使用的根據(jù)訂單號讀寫

6.2、訂單表適用的分表方式

通過對訂單表讀寫場景紊服、不同分表函數(shù)檀轨、改造成本的分析,訂單表采用水平拆分適用的分表方式如下:

  • 用HASH函數(shù)欺嗤,就需要以買家参萄、賣家、訂單號3個維度拆分成3張邏輯表煎饼,讀寫時根據(jù)場景判斷走哪個表讹挎,數(shù)據(jù)存儲鏈路較長
  • 用RANGE_HASH函數(shù),以訂單號和買家id的后N位做分庫分表吆玖,能滿足訂單號和買家id兩個維度的查詢筒溃,賣家id維度無法查詢

6.3、最終采取方案

綜上沾乘,因為訂單一般都是由買家發(fā)起生成的怜奖,所以我們認為優(yōu)先處理買家數(shù)據(jù)和訂單號數(shù)據(jù)比較合理,所以我們先采用RANGE_HASH拆分算法按買家id后N位翅阵、訂單號后N位維度做分庫分表歪玲,作為買家表邏輯表尽爆。再用HASH拆分函數(shù)按商家id冗余一份數(shù)據(jù),作為賣家表邏輯表

  • 買家?guī)於辽鳌①I家表:下單填充買家表數(shù)據(jù)漱贱,用于以訂單號、以買家id查詢
  • 賣家?guī)熵参①u家表:異步冗余一份買家表數(shù)據(jù)到賣家表幅狮,用于根據(jù)賣家id查數(shù)據(jù)
訂單買賣家表

6.4、訂單號生成

訂單號生成規(guī)則需要根據(jù)買家表分表特性訂單號后N位等于買家Id后N位做設(shè)計

比如用戶id為12345678株灸,則用戶在下單時生成的單號為:xxxxxxxxx345678崇摄,單號前幾位可以根據(jù)公司自己規(guī)則設(shè)定,但是要注意不能重復(fù)

6.5慌烧、分表數(shù)的確定

一般單表數(shù)據(jù)量控制在100W到5000W之間比較合理逐抑,可以根據(jù)預(yù)估未來2-3年數(shù)據(jù)的增長預(yù)期計算出合適的分表數(shù)

6.6、歷史訂單處理

歷史訂單沒有按照訂單號生成規(guī)則來生成屹蚊,但是歷史訂單也會有買家id厕氨,所以拆分函數(shù)配置時,特意將買家id后N位作為前置條件汹粤,歷史訂單會以買家id后N位作為分表鍵落庫命斧。

給歷史訂單建一個索引表,只保留訂單號和買家id關(guān)系

CREATE TABLE `order_history_index` (
`orderId` bigint(20) unsigned NOT NULL COMMENT '訂單ID',
`buyerUserId` bigint(20) unsigned NOT NULL COMMENT '買家的userId'
PRIMARY KEY (`orderId`)
) 

歷史訂單根據(jù)訂單號查詢時先過索引表取到買家id嘱兼,再查買家表取到具體數(shù)據(jù)国葬。

注意:

  • 還可以在訂單號里面添加了賣家id末2位、買家id末2位芹壕。
  • 而分庫汇四、分表的規(guī)則可以設(shè)計成,買家?guī)焓前凑召u家id末尾2位數(shù)分踢涌,賣家?guī)焓前凑召u家id末尾兩位分通孽。
  • 所以,只要從訂單號里面拿到了這些數(shù)字信息斯嚎,就知道在哪個庫利虫,哪個表了。

這種辦法堡僻,與微信的紅包訂單號是類似的糠惫,末尾三位數(shù)包含了庫信息、表信息钉疫。

  • 如果是按照用戶id的后4位數(shù)取模分散訂單數(shù)據(jù)硼讽。那么訂單號的生成,可以在后面加上用戶id的后4位數(shù)牲阁。
  • 那么固阁,雖然是按照用戶id來對訂單表分庫分表的壤躲。其實可以直接根據(jù)訂單號,就知道這個訂單在哪個庫哪個表了备燃。
  • 如果是B2B2C系統(tǒng)碉克,涉及到賣家和買家。那么可以把賣家和買家的id后面4位都加進去并齐。不過是不是訂單號有些偏長漏麦。

七、總結(jié)

按照上述方式對訂單分庫分表后况褪,業(yè)務(wù)里常用的查訂單表sql撕贞,通過編碼層面區(qū)分,路由到各個庫的買家表测垛、賣家表里捏膨,有效解決單表數(shù)據(jù)量過大的問題,提升系統(tǒng)穩(wěn)定性和負載能力食侮。

當(dāng)然肯定還有個別復(fù)雜查詢和分表鍵沾不上邊的号涯,這些業(yè)務(wù)場景對實時性要求不高的,可以走ES或者離線庫去查詢

參考:
https://maimai.cn/article/detail?fid=1639183809&efid=I5KVAmjkHZ_UPeF8wcR6gQ

https://www.cnblogs.com/wangtao_20/p/7115962.html

https://www.likecs.com/show-737990.html

https://my.oschina.net/vivotech/blog/5286769

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疙描,一起剝皮案震驚了整個濱河市诚隙,隨后出現(xiàn)的幾起案子讶隐,更是在濱河造成了極大的恐慌起胰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巫延,死亡現(xiàn)場離奇詭異效五,居然都是意外死亡,警方通過查閱死者的電腦和手機炉峰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門畏妖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疼阔,你說我怎么就攤上這事戒劫。” “怎么了婆廊?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵迅细,是天一觀的道長。 經(jīng)常有香客問我淘邻,道長茵典,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任宾舅,我火速辦了婚禮统阿,結(jié)果婚禮上彩倚,老公的妹妹穿的比我還像新娘。我一直安慰自己扶平,他們只是感情好帆离,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著结澄,像睡著了一般盯质。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上概而,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天呼巷,我揣著相機與錄音,去河邊找鬼赎瑰。 笑死王悍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的餐曼。 我是一名探鬼主播压储,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼源譬!你這毒婦竟也來了集惋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤踩娘,失蹤者是張志新(化名)和其女友劉穎刮刑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體养渴,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡雷绢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了理卑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翘紊。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖藐唠,靈堂內(nèi)的尸體忽然破棺而出帆疟,到底是詐尸還是另有隱情,我是刑警寧澤宇立,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布踪宠,位于F島的核電站,受9級特大地震影響泄伪,放射性物質(zhì)發(fā)生泄漏殴蓬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望染厅。 院中可真熱鬧痘绎,春花似錦、人聲如沸肖粮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩馆。三九已至行施,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間魂那,已是汗流浹背蛾号。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涯雅,地道東北人鲜结。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像活逆,于是被迫代替她去往敵國和親精刷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容