一、方案背景
訂單系統存在於各行各業,如電商訂單、銀行流水、運營商話費賬單等,是一個非常廣泛、通用的系統。對於這類系統,在過去十幾年發展中已經形成了經典的做法。但是隨著網際網路的發展,以及各企業對資料的重視,需要儲存和持久化的訂單量越來越大。資料的重視程度與資料規模的膨脹帶來了新的挑戰。
需求場景
某電商平臺A,需要進行持久化所有平臺產生的訂單資料。同時,基於所有的訂單資料,系統又需要向外提供面向多種角色:消費者、店家、平臺三類人群的多元化的查詢服務。消費者可以查詢自己的歷史訂單,商家可以統計熱銷產品,平臺也可以分析使用者行為、平臺交易規模等。主要查詢方式涵蓋訂單的多維度檢索,以及訂單資料的分析、統計等,例如: 面向消費者:【A消費者】*【近1年】*【賣出電腦】訂單查詢; 面向售貨員:【B售貨員】*【近1個月】銷售訂單; ......
技術點
在訂單場景中,技術上通常需要考慮的技術點,主要包含如下幾個方面:
- 查詢能力:需要具備豐富的查詢型別,如多維度、範圍、模糊查詢等,同時具備排序、統計等功能;
- 資料量:儲存海量資料的同時,滿足強一致、高可用、低成本等要求;
- 服務效能:應對高併發請求高併發的同時,保證低延遲;
實現多維、實時查詢功能,是訂單管理解決方案的核心功能,官網控制檯地址:專案樣例
二、方案演進
應對訂單場景,電商通常會採用MySQL傳統方案。藉助關係型資料庫強大的查詢能力,使用者可直接通過SQL語句實現訂單資料的多維度查詢、資料統計等。所謂資料膨脹,分為橫向、縱向兩種,橫向即不斷迭代引入的新欄位維度,縱向即總的儲存資料量。在面對這兩種訂單資料膨脹上,單MySql方案逐漸變得吃力。 SQL + NoSQL的組合方案(以下稱:組合方案)便應運而生,藉助兩個資料庫各自的優勢分別解決不同場景各自的需求。但組合方案同樣也帶來了新的問題,組合方案犧牲空間成本,同時也增加了開發工作量與運維複雜度。在保證資料一致性上產生額外開銷。 下面讓我們看一下如下幾個常規方案:
常規方案
1、MySql分庫分表方案
MySql自身擁有強大的資料查詢、分析功能,基於MyQql建立訂單系統,可以應對訂單資料多維查詢、統計場景。伴隨著訂單資料量的增加,使用者會採取分庫、分表方案應對,通過這種偽分散式方案,解決資料膨脹帶來的問題。但資料一旦達到瓶頸,便需要重新建立更大規模的分庫+資料的全量遷移,麻煩就會不斷出現。資料迭代、膨脹帶來的困擾,是MySql方案難於逾越的。僅僅依靠MySql的傳統訂單方案短板凸顯。 1、資料縱向(資料規模)膨脹:採用分庫分表方案,MySql在部署時需要預估分庫規模,資料量一旦達到上限後,重新部署並做資料全量遷移; 2、資料橫向(欄位維度)膨脹:schema需預定義,迭代新增新欄位變更復雜。而維度到達一定量後影響資料庫效能;
2、MySql+HBase方案
引入雙資料的方案應運而生,通過實時資料、歷史資料分存的方案,可以一定程度解決資料量膨脹問題。該方案將資料歸類成兩部分儲存:實時資料、歷史資料。同時通過資料同步服務,將過期資料同步至歷史資料。 1、實時訂單資料(例如:近3個月的訂單):將實時訂單存入MySql資料庫。實時訂單的總量膨脹的速度得到了限制,同時保證了實時資料的多維查詢、分析能力; 2、歷史訂單資料(例如:3個月以前的訂單):將歷史訂單資料存入HBase,藉助於HBase這一分散式NoSql資料庫,有效應對了訂單資料膨脹困擾。也保證了歷史訂單資料的持久化; 但是,該方案犧牲了歷史訂單資料對使用者、商家、平臺的使用價值,假設了歷史資料的需求頻率極低。但是一旦有需求,便需要全表掃描,查詢速度慢、IO成本很高。而維護資料同步又帶來了資料一致性、同步運維成本飆升等難題;
3、MySql+Elasticsearch方案
組合方案還有MySql+Elasticsearch,該方案同樣是將資料分兩部分儲存,可以一定程度解決訂單索引維度增長問題。使用者自己維護資料同步服務,保證兩部分資料的一致性; 1、全量資料:將全量的訂單資料存入MySql資料庫,訂單ID之外的資料整體存為一個欄位。該全量資料作為持久化儲存,也用於非索引欄位的反查; 2、查詢資料:僅將需要檢索的欄位存入Elasticsearch(基於Lucene分散式索引資料庫),藉助於>Elasticsearch的索引能力,提供可以應付維度膨脹的訂單資料,然後必要時反查MySql獲取訂單完整資訊; 該方案應付了資料維度膨脹帶來的困擾,但是隨著訂單量的不斷膨脹,MySql擴充套件性差的問題再次暴露出來。同時資料同步至Elasticsearch的方案,開發、運維成本很高,方案選擇也存在弊端。
能力分析 | MySql | HBase | Elasticsearch | TableStore |
---|---|---|---|---|
儲存方式 | 行儲存 | 列儲存 | 索引儲存 | 列儲存+索引儲存 |
擴充套件性 | 單機、擴充套件性差 | 水平擴充套件 | 水平擴充套件 | (自動)水平擴充套件 |
一致性 | 強一致性 | 強一致性、時序一致性 | 強一致性、時序一致性 | |
檢索 | 較弱的支援 | 不支援 | 支援 | 支援 |
資料量 | ~ 1T,~億行 | ~10 PB,~萬億行 | ~1 PB,~千億行 | ~10 PB,~萬億行 |
表格儲存(TableStore)方案
如果使用表格儲存(TableStore)研發的多元索引(SearchIndex)方案,則可以完美地解決億量級訂單系統問題。TableStore具有即開即用,按量收費等特點。多元索引隨時建立,是海量電商訂單後設資料管理的優質方案。 TableStore作為阿里雲提供的一款全託管、分散式NoSql型資料儲存服務,具有【海量資料儲存】、【熱點資料自動分片】、【海量資料多維檢索】等功能,天然地解決了訂單資料大爆炸這一挑戰; 同時,SearchIndex功能在保證使用者資料高可用的基礎上,提供了資料多維度搜尋、統計等能力。針對多種場景建立多種索引,實現多種模式的檢索。使用者可以僅在需要的時候建立、開通索引。由TableStore來保證資料同步的一致性,這極大的降低了使用者的方案設計、服務運維、程式碼開發等工作量。
基於表格儲存搭建的訂單系統頁面一覽
樣例內嵌在表格儲存控制檯中,使用者可登入控制檯體驗系統(若為表格儲存的新使用者,需要點選開通服務後體驗,開通免費,訂單資料儲存在公共例項中,體驗不消耗使用者儲存、流量、Cu)。 注:該樣例提供了【億量級】訂單資料。官網控制檯地址:專案樣例
二、搭建準備
若您對於億量級訂單系統的體驗不錯,希望開始自己系統的搭建之旅,只需按照如下步驟便可以著手搭建了:
1、開通表格儲存
通過控制檯開通表格儲存服務,表格儲存即開即用(後付費),採用按量付費方式,已為使用者提供足夠功能測試的免費額度。 表格儲存官網控制檯、免費額度說明。
2、建立例項
通過控制檯建立表格儲存例項,選擇支援多元索引的Region。(當前階段SearchIndex功能尚未商業化,暫時開放北京、上海、深圳、杭州四地,後續逐漸開放)
建立例項後,提交工單申請多元索引功能邀測(商業化後預設開啟,不使用不收費)。
- 邀測地址:提工單,選擇【表格儲存】>【產品功能、特性諮詢】>【建立工單】,申請內容如下:
- 問題描述:請填寫【申請SearchIndex邀測】
- 機密資訊:請填寫【地域+例項名】,例:上海+myInstanceName
3、SDK下載
使用具有多元索引(SearchIndex)的SDK,官網地址,暫時java、go、node.js、C#四種SDK增加了新功能
java-SDK
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>tablestore</artifactId>
<version>4.8.0</version>
</dependency>
複製程式碼
go-SDK
$ go get github.com/aliyun/aliyun-tablestore-go-sdk
複製程式碼
Nodejs-SDK
$ npm install tablestore@4.1.0
複製程式碼
C#
$ Install-Package Aliyun.TableStore.SDK -Version 4.1.0
複製程式碼
4、表設計
訂單系統不僅僅是訂單一張資料表,它應包含:消費者表、售貨員表、產品表、供貨商表、交易訂單表、支付訂單表等。在本樣例中,主要使用最基本的四張表(消費者表、售貨員表、產品表、交易訂單表),僅以訂單表舉例如下: 表名:order_contract
列名 | 資料型別 | 索引型別 | 欄位說明 |
---|---|---|---|
_id(主鍵列) | String | MD5(oId)避免熱點 | |
oId | String | KEYWORD | 訂單編號 |
pName | String | TEXT | 產品名,TEXT型別索引可模糊查詢,但不能排序 |
totalPrice | double | DOUBLE | 訂單總價 |
orderTime | long | LONG | 下單時間(時間戳) |
... | ... | ... | ... |
三、開始搭建(核心程式碼)
1、建立資料表
四張表:訂單表、消費者表、售貨員表、產品表 使用者僅需維護一個例項,按如下方式建立:通過控制檯建立、管理資料表(使用者也可以通過SDK直接建立):
2、建立資料表索引 TableStore自動做全量、增量的索引資料同步:使用者可以通過控制檯建立、管理SearchIndex(使用者也可通過SDK建立):
3、資料匯入
插入部分測試資料(控制檯樣例中插入了1億條資料,使用者自己可以通過控制檯插入少量測試資料);
訂單號 | 訂單(md5)(主鍵) | 消費者編號 | 消費者姓名 | 售貨員編號 | 售貨員姓名 | 產品編號 | 產品名 | 產品品牌 | 產品型別 | 下單時間 | 支付時間 | 支付狀態 | 產品單價 | 數量 | 總價錢 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
o0000000000 | c49f5fd5aba33159accae0d3ecd749a7 | c0019 | 消陳九 | s0020 | 售楚十 | p0003004 | vivo x21 | vivo | 手機 | 2018-07-17 21:00:00 | 否 | 2498.99 | 2 | 4997.98 |
消費者編號(主鍵) | 消費者姓名 | 消費者積分 | 註冊時間 |
---|---|---|---|
c0001 | 消趙一 | 818 | 2018-07-07 14:33:51 |
售貨員編號(主鍵) | 售貨員姓名 | 售貨員積分 | 入職日期 |
---|---|---|---|
s0001 | 售趙一 | 613 | 2018-07-07 14:27:59 |
產品編號(主鍵) | 產品名 | 產品品牌 | 產品型別 | 產品單價 | 新增時間 |
---|---|---|---|---|---|
p0001001 | iphone 6 | 蘋果 | 手機 | 6969.00 | 2018-07-07 14:44:39 |
4、資料讀取
資料讀取分為兩類:
主鍵讀取
基於原生表格儲存的主鍵列獲取:getRow, getRange, batchGetRow等。主鍵讀取用於索引(自動)反查,使用者也可以提供主鍵(訂單md5)的單條查詢的頁面,億量級下查詢速度極快。單主鍵查詢方式不支援多維度檢索;
索引讀取
基於新SearchIndex功能Query:search介面。使用者可以自由設計索引欄位的多維度條件組合查詢。通過設定選擇不同的查詢引數,構建不同的查詢條件、不同排序方式;目前支援:精確查詢、範圍查詢、字首查詢、匹配查詢、萬用字元查詢、短語匹配查詢、分詞字串查詢,並通過布林與、或組合。 如【c0001號消費者,且消費在99.99以上的訂單】組合方式如下:
List<Query> mustQueries = new ArrayList<Query>();
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("cId");
termQuery.setTerm(ColumnValue.fromString("c0001"));
mustQueries.add(termQuery);
RangeQuery rangeQuery = new RangeQuery();
rangeQuery.setFieldName("totalPrice");
rangeQuery.setFrom(ColumnValue.fromDouble(99.99));
mustQueries.add(rangeQuery);
BoolQuery boolQuery = new BoolQuery();
boolQuery.setMustQueries(mustQueries);
複製程式碼
四、歡迎加入
__引自雲棲:原文地址:yq.aliyun.com/articles/65…
這樣,系統的核心程式碼已經完成,基於表格儲存搭建訂單系統,是不是很簡單? 對錶格儲存(TableStore)感興趣的使用者,歡迎加入【表格儲存公開交流群】,群號:11789671。