日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于TableStore的海量电商订单元数据管理

發布時間:2024/8/23 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于TableStore的海量电商订单元数据管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、背景

訂單系統存在于各行各業,如電商訂單、銀行流水、運營商話費賬單等,是一個非常廣泛、通用的系統。對于這類系統,在過去十幾年發展中已經形成了經典的做法。但是隨著互聯網的發展,以及各企業對數據的重視,需要存儲和持久化的訂單量越來越大。數據的重視程度與數據規模的膨脹帶來了新的挑戰,原有的系統是否還能繼續滿足需求成了焦點?

需求場景

某電商平臺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的方案,開發、運維成本很高,方案選擇也存在弊端。

能力分析MySqlHBaseElasticsearchTableStore
存儲方式行存儲列存儲索引存儲列存儲+索引存儲
擴展性單機、擴展性差水平擴展水平擴展(自動)水平擴展
一致性強一致性強一致性、時序一致性?強一致性、時序一致性
檢索較弱的支持不支持支持支持
數據量~ 1T,~億行~10 PB,~萬億行~1 PB,~千億行~10 PB,~萬億行

TableStore方案

如果使用表格存儲(TableStore)研發的多元索引(SearchIndex)方案,則可以完美地解決以上問題。TableStore具有即開即用,按量收費等特點。多元索引隨時創建,是海量電商訂單元數據管理的優質方案。
TableStore作為阿里云提供的一款全托管、分布式NoSql型數據存儲服務,具有【海量數據存儲】、【熱點數據自動分片】、【海量數據多維檢索】等功能,天然地解決了訂單數據大爆炸這一挑戰;
同時,SearchIndex功能在保證用戶數據高可用的基礎上,提供了數據多維度搜索、統計等能力。針對多種場景創建多種索引,實現多種模式的檢索。用戶可以僅在需要的時候創建、開通索引。由TableStore來保證數據同步的一致性,這極大的降低了用戶的方案設計、服務運維、代碼開發等工作量。

?

三、基于表格存儲實現的訂單場景Demo

業務描述:

每成功完成一筆交易,就會生成一筆交易數據。交易數據包含了交易中的必要元素,如:交易時間、交易的雙方、交易的產品、數量、價格等,這里選擇最基本元素舉例,僅將必要字段簡歷索引,格式如下:

訂單持久化數據

表名:"order_table"

列名索引類型類型索引字段
order_id(主鍵列)KEYWORDString均勻散列的字符串
time_stampLONGlong交易時間戳
consumer_idKEYWORDString消費者
seller_idKEYWORDString商家unique編號
product_idKEYWORDString產品unique編號
product_nameKEYWORDString產品名
product_typeKEYWORDString產品類型
product_priceDOUBLEdouble產品單價
product_count?double?
total_pay?double?
description?String?
........................

創建訂單表

用戶僅需維護一個數據庫,按如下方式創建:用戶可以通過控制臺創建、管理Table,也可通過SDK

List<PrimaryKeySchema> primaryKey = Arrays.asList(new PrimaryKeySchema("order_id", PrimaryKeyType.STRING) );TableMeta tableMeta = new TableMeta(tableName); tableMeta.addPrimaryKeyColumns(primaryKey); CreateTableRequest request = new CreateTableRequest(tableMeta, new TableOptions(-1, 1)); CreateTableResponse createTableResponse = otsClient.createTable(request);

創建索引

用戶根據自身需求,在需要的時候隨時創建索引。TableStore自動做全量、增量的索引數據同步:用戶可以通過控制臺創建、管理SearchIndex,也可通過SDK按如下方式創建(索引暫不支持update)

CreateSearchIndexRequest createSearchIndexRequest = new CreateSearchIndexRequest(); createSearchIndexRequest.setTableName("tableName"); createSearchIndexRequest.setIndexName("indexName");IndexSchema indexSchema = new IndexSchema(); indexSchema.setIndexSetting(new IndexSetting(1));//必寫 indexSchema.setFieldSchemas(Arrays.asList(new FieldSchema("product_id", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("product_name", FieldType.TEXT).setIndex(true),//TEXT不能設置docValuesnew FieldSchema("product_type", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("product_count", FieldType.DOUBLE).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("consumer_id", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("seller_id", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("total_pay", FieldType.DOUBLE).setIndex(true).setEnableSortAndAgg(true).setStore(true),new FieldSchema("time_stamp", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true).setStore(true) )); createSearchIndexRequest.setIndexSchema(indexSchema);CreateSearchIndexResponse createSearchIndexResponse = otsClient.createSearchIndex(createSearchIndexRequest);

數據讀取

數據讀取分為兩類:
1、基于原生表格存儲的主鍵列獲取:getRow, getRange, batchGetRow等;
2、基于新SearchIndex功能Query:search;

主鍵讀取

GetRowRequest getRowRequest = new GetRowRequest();PrimaryKey pk = new PrimaryKey(new PrimaryKeyColumn[]{new PrimaryKeyColumn("order_id", PrimaryKeyValue.fromString("fa960b5af")) });SingleRowQueryCriteria singleRowQueryCriteria = new SingleRowQueryCriteria("order_table", pk); singleRowQueryCriteria.setMaxVersions(1); getRowRequest.setRowQueryCriteria(singleRowQueryCriteria);GetRowResponse rowResponse = o?tsClient.getRow(getRowRequest);

Search讀取

新增的search接口,通過設置QueryRequest實現不同query,不同aggregation,不同sort的功能

SearchQuery searchQuery = new SearchQuery();//設置查詢條件,用戶發揮 searchQuery.setQuery(Query anyQuery);//做分頁 searchQuery.setLimit(10); searchQuery.setOffSet(0);SearchRequest searchRequest = new SearchRequest("tableName", "indexName", searchQuery);SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); columnsToGet.setColumns(columnsToShow);//List<String> columnsToShow searchRequest.setColumnsToGet(columnsToGet);SearchResponse resp = otsClient.search(searchRequest);

返回結構

SearchResponse extends Response {private long totalCount;//query匹配成功數據總數private List<Row> rows;//query匹配數據列表(1)private boolean isAllSuccess; }

場景Demo

search功能主要分為三種:(多維度)查詢,排序,聚合,使用上通過三種功能的組合來實現;

場景1:多維度查詢

【"consumer_001"用戶】【上個月】購買【產品名含某"牙膏"字段】的訂單記錄
使用:BoolQuery, TermQuery, RangeQuery, MatchPhraseQuery

BoolQuery boolQuery = new BoolQuery();TermQuery termQuery = new TermQuery(); termQuery.setFieldName("consumer_id"); termQuery.setTerm(ColumnValue.fromString("consumer_001"));RangeQuery rangeQuery = new RangeQuery(); rangeQuery.setFieldName("time_stamp"); rangeQuery.greaterThanOrEqual(ColumnValue.fromLong(fromTime)); rangeQuery.lessThanOrEqual(ColumnValue.fromLong(toTime));MatchPhraseQuery matchPhraseQuery = new MatchPhraseQuery(); matchPhraseQuery.setFieldName("product_name"); matchPhraseQuery.setText("牙膏");boolQuery.setMustQueries(Arrays.asList(termQuery, rangeQuery, matchPhraseQuery ));SearchQuery searchQuery = new SearchQuery(); searchQuery.setQuery(boolQuery); searchQuery.setLimit(10);//僅構建Query SearchRequest searchRequest = new SearchRequest("tableName", "indexName", searchQuery);

場景2:查詢,排序

整個平臺【上個月】【單訂單支付金額】排行榜Top10
使用:RangeQuery, FieldSort

RangeQuery rangeQuery = new RangeQuery(); rangeQuery.setFieldName("time_stamp"); rangeQuery.greaterThanOrEqual(ColumnValue.fromLong(fromTime)); rangeQuery.lessThanOrEqual(ColumnValue.fromLong(toTime));//排序因子 FieldSort fieldSort = new FieldSort("total_pay"); fieldSort.setOrder(SortOrder.DESC);SearchQuery searchQuery = new SearchQuery(); searchQuery.setQuery(rangeQuery); searchQuery.setSort(new Sort(Arrays.asList(fieldSort))); searchQuery.setLimit(10);//構建Query+Sort SearchRequest searchRequest = new SearchRequest("tableName", "indexName", searchQuery);


原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。

總結

以上是生活随笔為你收集整理的基于TableStore的海量电商订单元数据管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。