迎關(guān)注我的頭條號:Wooola,10 年 Java 軟件開發(fā)及架構(gòu)設(shè)計經(jīng)驗,專注于 Java、Go 語言、微服務(wù)架構(gòu),致力于每天分享原創(chuàng)文章、快樂編碼和開源技術(shù)。
隨著唯品會業(yè)務(wù)的快速發(fā)展,訂單量的不斷增長,原有的訂單存儲架構(gòu)已經(jīng)不能滿足公司的發(fā)展了,特別是在大促高峰期,原訂單庫已經(jīng)成為搶購瓶頸,已經(jīng)嚴重制約公司的發(fā)展。
唯品會舊訂單庫包含幾十張訂單相關(guān)表,舊訂單庫是典型的一主多從架構(gòu);主庫容量已接近服務(wù)器物理空間上限,同時也已經(jīng)達到MySQL的處理上限,很快將無法再處理新增訂單。
舊訂單庫面臨的問題有:
1、超大容量問題
- 訂單相關(guān)表都已經(jīng)是超大表,最大表的數(shù)據(jù)量已經(jīng)是幾十億,數(shù)據(jù)庫處理能力已經(jīng)到了極限;
- 單庫包含多個超大表,占用的硬盤空間已經(jīng)接近了服務(wù)器的硬盤極限,很快將無空間可用;
2、性能問題
單一服務(wù)器處理能力是有限的,單一訂單庫的TPS也有上限,不管如何優(yōu)化,總會有達到上限,這限制了單位時間的訂單處理能力,這個問題在大促時更加明顯,如果不重構(gòu),訂單達到一定量以后,就無法再繼續(xù)增長,嚴重影響到用戶體驗。
3、升級擴展問題
- 單一主庫無法靈活的進行升級和擴展,無法滿足公司快速發(fā)展要求;
- 所有的訂單數(shù)據(jù)都放在同一庫里面,存在單點故障的風(fēng)險;
綜上所述,容量、性能問題是急需解決的問題,擴展是為了將來3~5年內(nèi)能夠很好的滿足唯品會快速發(fā)展的需要,而不需要每隔幾個月花費人力物力去考慮擴容等問題。
解決方法思考
1、解決容量問題
我們可以考慮到最直接的方式是增加大容量硬盤,或者對IO有更高要求,還可以考慮增加SSD硬盤來解決容量的問題。此方法無法解決單表數(shù)據(jù)量問題。
可以對數(shù)據(jù)表歷史數(shù)據(jù)進行歸檔,但也需要頻繁進行歸檔操作,而且不能解決性能問題。
2、解決性能問題
提高數(shù)據(jù)庫服務(wù)器的配置,這個可以提升一定數(shù)量的QPS和TPS,但仍然不能解決單服務(wù)器連接數(shù)、IO讀寫存在上限的問題,此方法仍然存在單點故障的問題。
拆分方法探討
常見的數(shù)據(jù)庫拆分方式有三種:垂直拆分、水平拆分、垂直水平拆分。
1、垂直拆分
垂直拆庫是根據(jù)數(shù)據(jù)庫里面的數(shù)據(jù)表的相關(guān)性進行拆分,比如:一個數(shù)據(jù)庫里面既存在用戶數(shù)據(jù),又存在訂單數(shù)據(jù),那么垂直拆分可以把用戶數(shù)據(jù)放到用戶庫、把訂單數(shù)據(jù)放到訂單庫。如下圖:
垂直拆表是對數(shù)據(jù)表進行垂直拆分的一種方式,常見的是把一個多字段的大表按常用字段和非常用字段進行拆分,每個表里面的數(shù)據(jù)記錄數(shù)一般情況下是相同的,只是字段不一樣,使用主鍵關(guān)聯(lián),如下圖:
2、水平拆分
水平拆分是把單表按某個規(guī)則把數(shù)據(jù)分散到多個表的拆分方式,比如:把單表1億數(shù)據(jù)按某個規(guī)則拆分,分別存儲到10個相同結(jié)果的表,每個表的數(shù)據(jù)是1千萬,拆分出來的表,可以分別放至到不同數(shù)據(jù)庫中,即同時進行水平拆庫操作,如下圖:
水平拆分可以降低單表數(shù)據(jù)量,讓每個單表的數(shù)據(jù)量保持在一定范圍內(nèi),從而提升單表讀寫性能。但水平拆分后,同一業(yè)務(wù)數(shù)據(jù)分布在不同的表或庫中,可能需要把單表事務(wù)改成跨表事務(wù),需要轉(zhuǎn)變數(shù)據(jù)統(tǒng)計方式等。
3、垂直水平拆分
垂直水平拆分,是綜合了垂直和水平拆分方式的一種混合方式,垂直拆分把不同類型的數(shù)據(jù)存儲到不同庫中,再結(jié)合水平拆分,使單表數(shù)據(jù)量保持在合理范圍內(nèi),提升總TPS,提升性能,如下圖:
垂直拆分策略
原訂單庫把所有訂單相關(guān)的數(shù)據(jù)(訂單銷售、訂單售后、訂單任務(wù)處理等數(shù)據(jù))都放在同一數(shù)據(jù)庫中,不符合電商系統(tǒng)分層設(shè)計,對于訂單銷售數(shù)據(jù),性能第一,需要能夠在大促高峰承受每分鐘幾萬到幾十萬訂單的壓力;而售后數(shù)據(jù),是在訂單生成以后,用于訂單物流、訂單客服等,性能壓力不明顯,只要保證數(shù)據(jù)的及時性即可;所以根據(jù)這種情況,把原訂單庫進行垂直拆分,拆分成訂單售后數(shù)據(jù)、訂單銷售數(shù)據(jù)、其他數(shù)據(jù)等,如下圖:
水平拆分策略
垂直拆分從業(yè)務(wù)上把訂單下單數(shù)據(jù)與下單后處理數(shù)據(jù)分開,但對于訂單銷售數(shù)據(jù),由于數(shù)據(jù)量仍然巨大,最大的訂單銷售相關(guān)表達到幾十億的數(shù)據(jù)量,如果遇到大型促銷(如:店慶128、419、618、雙十一等等),數(shù)據(jù)庫TPS達到上限,單銷售庫單訂單表仍然無法滿足需求,還需要進一步進行拆分,在這里使用水平拆分策略。
訂單分表是首先考慮的,分表的目標是保證每個數(shù)據(jù)表的數(shù)量保持在1000~5000萬左右,在這個量級下,數(shù)據(jù)表的大小與性能是最理想的。
如果幾十個分表都放到一個訂單庫里面,運行于單組服務(wù)器上,則受限于單組服務(wù)器的處理能力,數(shù)據(jù)庫的TPS有限,所以需要考慮分庫,把分表放到分庫里面,減輕單庫的壓力,增加總的訂單TPS。
1、用戶編號HASH切分
使用用戶編號哈希取模,根據(jù)數(shù)據(jù)量評估,把單庫拆分成n個庫,n個庫分別存放到m組服務(wù)器中,如下圖:
每組服務(wù)器容納4個庫,如果將來單服務(wù)器達到性能、容量等瓶頸,可以直接把數(shù)據(jù)庫水平擴展為2倍服務(wù)器集群,還可以繼續(xù)擴展為4倍服務(wù)器集群。水平擴展可以支撐公司在未來3~5年的快速訂單增長。
使用用戶編號進行 sharding,可以使得創(chuàng)建訂單的處理更簡單,不需要進行跨庫的事務(wù)處理,提高下單的性能與成功率。
2、訂單號索引表
根據(jù)用戶編號進行哈希分庫分表,可以滿足創(chuàng)建訂單和通過用戶編號維度進行查詢操作的需求,但是根據(jù)統(tǒng)計,按訂單號進行查詢的占比達到80%以上,所以需要解決通過訂單號進行訂單的CURD等操作,所以需要建立訂單號索引表。
訂單號索引表是用于用戶編號與訂單號的對應(yīng)關(guān)系表,根據(jù)訂單號進行哈希取模,放到分庫里面。根據(jù)訂單號進行查詢時,先查出訂單號對應(yīng)的用戶編號,再根據(jù)用戶編號取模查詢?nèi)?yīng)的庫查詢訂單數(shù)據(jù)。
訂單號與用戶編號的關(guān)系在創(chuàng)建訂單后是不會更改的,為了進一步提高性能,引入緩存,把訂單號與用戶編號的關(guān)系存放到緩存里面,減少查表操作,提升性能,索引不命中時再去查表,并把查詢結(jié)果更新到緩存中。
3、分布式數(shù)據(jù)庫集群
訂單水平分庫分表以后,通過用戶編號,訂單號的查詢可以通過上面的方法快速定位到訂單數(shù)據(jù),但對于其他條件的查詢、統(tǒng)計操作,無法簡單做到,所以引入分布式數(shù)據(jù)庫中間件。
下圖是基本構(gòu)架:
總結(jié)與思考
技術(shù)架構(gòu)與業(yè)務(wù)場景息息相關(guān),不能脫離實際的業(yè)務(wù)場景、歷史架構(gòu)、團隊能力、數(shù)據(jù)體量等等去做架構(gòu)重構(gòu),對于一家快速發(fā)展的電子商務(wù)公司,訂單系統(tǒng)是核心,訂單庫是核心的核心,訂單庫的重構(gòu)就像汽車在高速公路上跑著的過程中更換輪胎。
本文是對唯品會訂單庫重構(gòu)——采用分庫分表策略對原訂單庫表進行拆分的粗略總結(jié),在訂單庫重構(gòu)過程中遇到的問題遠遠超過這些,比如:歷史數(shù)據(jù)的遷移、各外圍系統(tǒng)的對接等,但這些在公司強大的技術(shù)團隊面前,最終都順利的解決,新舊訂單庫順利的切換,給公司快速的業(yè)務(wù)發(fā)展提供堅實的保障。
來源 極客時間 | 葉明開、王鑫
如有侵權(quán)請聯(lián)系刪除
1.《水平分表后如何查詢 水平分表后如何查詢數(shù)據(jù)?》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《水平分表后如何查詢 水平分表后如何查詢數(shù)據(jù)?》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/keji/3217626.html