云原生 Serverless Database 使用體驗(yàn)
近十年來(lái)互聯(lián)網(wǎng)技術(shù)得到了飛速的發(fā)展,越來(lái)越多的行業(yè)加入到了互聯(lián)網(wǎng)的矩陣,由此帶來(lái)了更為豐富且復(fù)雜的業(yè)務(wù)場(chǎng)景需求,這對(duì)于數(shù)據(jù)應(yīng)用系統(tǒng)的性能無(wú)疑是巨大的挑戰(zhàn)。
關(guān)系型數(shù)據(jù)庫(kù) MySQL 是應(yīng)用系統(tǒng)中最廣泛使用的數(shù)據(jù)庫(kù)產(chǎn)品,擁有強(qiáng)大的數(shù)據(jù)查詢(xún)和強(qiáng)事務(wù)處理能力。在如今的云時(shí)代,應(yīng)用系統(tǒng)逐漸演進(jìn)到基于云原生 Serverless 架構(gòu)去進(jìn)行搭建,因?yàn)樗哂?strong>低成本、高彈性的優(yōu)勢(shì)。但基于 MySQL 的數(shù)據(jù)存儲(chǔ)在 Serverless 架構(gòu)體系下仍存在一些明顯的不足:
-
彈性擴(kuò)展能力差。Serverless 場(chǎng)景中一個(gè)重要特點(diǎn)是應(yīng)用負(fù)載具有顯著的波峰波谷。當(dāng)面臨流量洪峰時(shí),DBA 又需要手動(dòng)對(duì)集群進(jìn)行擴(kuò)容以避免集群被打爆;而適逢流量低谷時(shí),則需要對(duì)集群進(jìn)行縮容以節(jié)省成本。
-
運(yùn)維復(fù)雜度高。MySQL 搭建需要進(jìn)行購(gòu)置集群、安裝服務(wù)、管理連接。業(yè)務(wù)上線(xiàn)后還要關(guān)注數(shù)據(jù)安全、服務(wù)可用性、響應(yīng)時(shí)間等等,用于集群運(yùn)維的時(shí)間占比會(huì)變高,無(wú)法把更多的精力專(zhuān)注于業(yè)務(wù)研發(fā)上。
-
成本高。通常 DBA 需要預(yù)估業(yè)務(wù)規(guī)模來(lái)事先設(shè)定數(shù)據(jù)庫(kù)初始容量,當(dāng)業(yè)務(wù)請(qǐng)求量未達(dá)到預(yù)估值時(shí),集群中的資源會(huì)一直處于閑置狀態(tài),造成資源浪費(fèi)。
Serverless DataBase
Cloud Native
MySQL 支持的關(guān)系模型和其強(qiáng)事務(wù)的特性,使其在應(yīng)用系統(tǒng)中有非常重要的位置,是目前不可完全替代的存儲(chǔ)組件之一。但若一味地依賴(lài) MySQL 又會(huì)使得應(yīng)用系統(tǒng)無(wú)法完全 Serverless 化,不能享受 Serverless 帶來(lái)的極致彈性。
在阿里內(nèi)部我們有一些新的架構(gòu)實(shí)踐,那些需要強(qiáng)事務(wù)處理的數(shù)據(jù)仍舊使用關(guān)系表存儲(chǔ),而對(duì)于非強(qiáng)事務(wù)表數(shù)據(jù)存儲(chǔ),我們則設(shè)計(jì)出了一款擁有極致彈性的 Serverless 表存儲(chǔ)。
關(guān)于 Serverless 數(shù)據(jù)庫(kù)產(chǎn)品,我們的設(shè)計(jì)要求是必須具備以下幾個(gè)特征:
-
完全彈性。可根據(jù)應(yīng)用負(fù)載自動(dòng)彈性擴(kuò)縮容,這一特性可為用戶(hù)帶來(lái)更經(jīng)濟(jì)的計(jì)費(fèi)模式和更絲滑的體驗(yàn)。
-
按量計(jì)費(fèi)。Serverless 數(shù)據(jù)庫(kù)的使用成本主要來(lái)自于計(jì)算成本和存儲(chǔ)成本。用戶(hù)只需為業(yè)務(wù)實(shí)際產(chǎn)生的存儲(chǔ)單元和響應(yīng)單元付費(fèi),節(jié)省成本。
-
零運(yùn)維。即開(kāi)即用,無(wú)需管理容量、水位、軟件升級(jí)、內(nèi)核優(yōu)化等運(yùn)維事項(xiàng),真正讓研發(fā)專(zhuān)注于業(yè)務(wù)開(kāi)發(fā)。
Serverless 架構(gòu)在諸多業(yè)務(wù)場(chǎng)景中都有廣泛的應(yīng)用實(shí)踐。例如世紀(jì)聯(lián)華集團(tuán)在其核心的電商業(yè)務(wù)中,針對(duì)自建 IDC 機(jī)房遇到的資源難以預(yù)算、系統(tǒng)部署困難等痛點(diǎn)問(wèn)題,將業(yè)務(wù)實(shí)現(xiàn)全面上云并逐步改造為全 Serverless 架構(gòu)的中臺(tái)模式。
世紀(jì)聯(lián)華集團(tuán)采用了函數(shù)計(jì)算+ API 網(wǎng)關(guān)+ Tablestore 方案,輕松支撐起了 6.18、雙 11 等大促活動(dòng)。其中,表格存儲(chǔ) Tablestore 作為世紀(jì)聯(lián)華電商系統(tǒng)的云上 Serverlesss 架構(gòu)中的核心存儲(chǔ),具備極致彈性、免運(yùn)維、成本低等優(yōu)勢(shì)。
表格存儲(chǔ) Tablestore 簡(jiǎn)介
Cloud Native
表格存儲(chǔ) Tablestore 于 2009 年阿里云成立之初便立項(xiàng)研發(fā),基于底層飛天平臺(tái)從零開(kāi)始構(gòu)建,是一款多模型、多引擎的 Serverless 表存儲(chǔ)。在公共云上輸出了國(guó)內(nèi)外 30 多個(gè)區(qū)域,擁有 1.5 萬(wàn)服務(wù)器規(guī)模和 200PB 存儲(chǔ)規(guī)模,是阿里云眾多商業(yè)化產(chǎn)品的底層核心存儲(chǔ)。
同時(shí)在線(xiàn)下已輸出到金融、能源、電力、物流、醫(yī)療、政企等行業(yè),服務(wù)于公共云 1000+ 企業(yè)客戶(hù)和 500+ 線(xiàn)下項(xiàng)目。
表格存儲(chǔ) Tablestore 具備 HBase 和 ElasticSearch 的融合功能,擁有極致彈性體驗(yàn)、免運(yùn)維、即開(kāi)即用的特性,支持 GB 到 PB 的彈性存儲(chǔ)和 十萬(wàn)級(jí) TPS 服務(wù)能力的無(wú)感知擴(kuò)展。支撐海量的表數(shù)據(jù)的同時(shí),提供豐富的數(shù)據(jù)檢索與分析能力,是集存儲(chǔ)、搜索和分析多功能一體的一站式結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)平臺(tái)。
表格存儲(chǔ) Tablestore 的整體架構(gòu)如下圖所示:
Tablestore 架構(gòu)圖
表格存儲(chǔ)提供了多種數(shù)據(jù)模型,主要包括寬表模型(Widecolumn)、消息模型(Timeline)和時(shí)序模型(Timeseries)。
-
寬表模型主要承載表結(jié)構(gòu)數(shù)據(jù)存儲(chǔ),例如電商訂單數(shù)據(jù)。
-
消息模型主要承載消息數(shù)據(jù)存儲(chǔ),例如 IM/Feeds 消息。
-
時(shí)序模型主要承載時(shí)序數(shù)據(jù)存儲(chǔ),例如物聯(lián)網(wǎng)設(shè)備時(shí)序數(shù)據(jù)。
下面我們將以電商訂單場(chǎng)景為例子,帶大家體驗(yàn)基于 Tablestore 的寬表模型構(gòu)建一個(gè) Serverless 的訂單存儲(chǔ)系統(tǒng)。
Tablestore 體驗(yàn)
Cloud Native
1準(zhǔn)備工作
在體驗(yàn) Tablestore 帶來(lái)的極致彈性之前,需要準(zhǔn)備如下幾個(gè)步驟:
(1)創(chuàng)建一個(gè)阿里云賬號(hào),并獲取到阿里云賬號(hào)的 AK。(云賬號(hào) AK 是訪(fǎng)問(wèn)所有云服務(wù)包括 Tablestore 的密鑰,后續(xù)需要通過(guò) AK 來(lái)訪(fǎng)問(wèn) Tablestore 服務(wù))。
(2)下載并啟動(dòng) Tablestore 提供的命令行工具 Tablestore CLI,命令行工具提供一些簡(jiǎn)單的指令來(lái)管理表格存儲(chǔ)服務(wù)。
首先通過(guò) config 命令配置連接密鑰并通過(guò) enable_service 命令開(kāi)通 Tablestore 服務(wù):
?
config --id accessKeyID --key accessKeySecretenable_service
(3)通過(guò) create_instance 命令創(chuàng)建一個(gè)實(shí)例:
create_instance -d "order storage" -n serverless-db -r cn-hangzhou
實(shí)例相當(dāng)于 MySQL 數(shù)據(jù)庫(kù)的概念,實(shí)例創(chuàng)建后無(wú)需思慮實(shí)例所在物理機(jī)集群的水位,只需專(zhuān)注開(kāi)發(fā)業(yè)務(wù)邏輯即可。同時(shí)實(shí)例上的讀寫(xiě)和存儲(chǔ)均為按量計(jì)費(fèi),若無(wú)讀寫(xiě)無(wú)存儲(chǔ),實(shí)際則不會(huì)產(chǎn)生任何費(fèi)用。
至此,一個(gè)能夠支持 GB 到 PB 存儲(chǔ)的、無(wú)并發(fā)限制、零運(yùn)維、完全彈性的 Serverless DataBase 就創(chuàng)建完成了。
創(chuàng)建表
寬表模型是(Widecolumn) 是 Schema-free 的一種數(shù)據(jù)表,與關(guān)系型數(shù)據(jù)庫(kù) MySQL 不同的是,創(chuàng)建一張表 Widecolumn 模型的數(shù)據(jù)表僅需要定義主鍵結(jié)構(gòu),并不需要定義屬性列結(jié)構(gòu)。
例如一張訂單表 order 的表結(jié)構(gòu)如下圖表格所示:
創(chuàng)建一張寬表模型的訂單表,屬性列信息無(wú)需定義,只需定義訂單表主鍵 id ,命令如下:
create_instance -d "order storage" -n serverless-db -r cn-hangzhou
執(zhí)行 create 命令后成功創(chuàng)建一張訂單寬表,剛創(chuàng)建的訂單寬表會(huì)被初始化 1 個(gè)數(shù)據(jù)分區(qū)。
隨著訂單數(shù)據(jù)量的增加或訪(fǎng)問(wèn)量的增加,寬表模型會(huì)根據(jù)第一主鍵的分布范圍(上述數(shù)據(jù)模型中即是訂單 ID)分裂擴(kuò)展成多個(gè)數(shù)據(jù)分區(qū)平均分布到多臺(tái)物理機(jī)上以支持更大的數(shù)據(jù)規(guī)模(TB 甚至 PB)和讀寫(xiě)吞吐(十萬(wàn) TPS 以上),整個(gè)擴(kuò)展過(guò)程完全由服務(wù)端自動(dòng)完成,無(wú)需人工干預(yù)。
數(shù)據(jù)導(dǎo)入
模擬生成了 100 萬(wàn)條樣例訂單數(shù)據(jù),并通過(guò) import 命令批量導(dǎo)入到 order 表中。單數(shù)據(jù)分區(qū)的寫(xiě)入速度可以達(dá)到幾萬(wàn)行/s,隨著分區(qū)擴(kuò)展,寫(xiě)入吞吐還可以進(jìn)一步提高。
import -i orderDataFile -l 1000000
Current speed is: 10000 rows/s. Total succeed count 10000, failed count 0.Current speed is: 12600 rows/s. Total succeed count 22600, failed count 0.......Current speed is: 9200 rows/s. Total succeed count 1000000, failed count 0.Import finished, total count is 1000000, failed 0 rows.
訂單查詢(xún)
使用 get 命令按照訂單號(hào)(id)單行查詢(xún)寬表模型,得到一條訂單數(shù)據(jù)。get 命令只能夠基于 rowKey 來(lái)進(jìn)行單行查詢(xún)。
查詢(xún)一條訂單示例:
id = "0000005be2b43dd134eae18ebe079774"
get --pk '["0000005be2b43dd134eae18ebe079774"]
+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+--------+---------+-------+-------+--------+------------+| order_id | cId | cName | hasPaid | oId | orderTime | pBrand | pCount | pId | pName | pPrice | pType | sId | sName | totalPrice |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+--------+---------+-------+-------+--------+------------+| 0000005be2b43dd134eae18ebe079774 | c0015 | 消周五 | false | o0035062633 | 1507519847532 | 小米 | 3 | p0005003 | 小米 6 | 2299.21 | 手機(jī) | s0017 | 售鄭七 | 6897.63 |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+--------+---------+-------+-------+--------+------------+
訂單檢索與統(tǒng)計(jì)
訂單場(chǎng)景中經(jīng)常會(huì)出現(xiàn)依賴(lài)多條件組合篩選,這種情況下需要依賴(lài) Tablestore 的多元索引特性。多元索引是 Tablestore 提供的類(lèi)似 Elasticsearch 的表數(shù)據(jù)索引,支持豐富的查詢(xún)方式和數(shù)據(jù)聚合能力,可在多個(gè)列上分別建立索引。和 MySQL 中的聯(lián)合索引不同的是,多元索引可根據(jù)任意字段組合查詢(xún),不會(huì)按照多列的最左前綴來(lái)匹配。
例如我們?cè)?id、pName、totalPrice 等字段上分別建立索引,采用倒排索引、分詞、BKDTree 等數(shù)據(jù)結(jié)構(gòu),提供了精確查詢(xún)、全文檢索、范圍查詢(xún)等查詢(xún)能力。另外,多元索引也支持按字段分組、多字段排序以及統(tǒng)計(jì)聚合能力。
使用 create_search_index 命令在寬表上建立多元索引,起到查詢(xún)加速的作用。
create_search_index -t order -n order_index{ "IndexSetting": null, "FieldSchemas": [{ "FieldName": "id", "FieldType": "KEYWORD", "Index": true, "EnableSortAndAgg": true, "Store": true },{ "FieldName": "pName", "FieldType": "TEXT", "Index": true, "EnableSortAndAgg": false, "Store": true },{ "FieldName": "totalPrice", "FieldType": "DOUBLE", "Index": true, "EnableSortAndAgg": true, "Store": true } ...//其他字段 ] }
Tablestore 支持 SQL 查詢(xún)能力,兼容了 MySQL 的查詢(xún)語(yǔ)法,并且盡量保留了關(guān)系型數(shù)據(jù)庫(kù)的使用習(xí)慣。SQL 能夠自動(dòng)選擇索引并進(jìn)行查詢(xún)加速,通過(guò)多元索引的查詢(xún)加速,在百億數(shù)據(jù)規(guī)模下也具備了毫秒級(jí)延遲查詢(xún)的能力。
根據(jù) sName、pBrand、pName 三個(gè)字段條件進(jìn)行訂單檢索:
select * from `order` where sName = "售周五" and pBrand = "小米" and pName like "紅米%"limit 3;
+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+---------+--------+-------+---------------+-------+--------+------------+| id | cId | cName | hasPaid | oId | orderTime | pBrand | pCount | pId | pName | pPrice | pType | payTime | sId | sName | totalPrice |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+---------+--------+-------+---------------+-------+--------+------------+| 00001c760c04126da067e90409467c4e | c0022 | 消趙一 | true | o0009999792 | 1494976931954 | 小米 | 3 | p0005004 | 紅米 5s | 499.01 | 手機(jī) | 1494977189780 | s0005 | 售周五 | 1497.03 |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+---------+--------+-------+---------------+-------+--------+------------+| 0000d89f46952ac03da71a33c8e83eef | c0012 | 消錢(qián)二 | false | o0024862442 | 1502415559707 | 小米 | 2 | p0005004 | 紅米 5s | 499.01 | 手機(jī) | null | s0015 | 售周五 | 998.02 |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+---------+--------+-------+---------------+-------+--------+------------+| 0000f560b62779285e86947f8e8d0e4c | c0008 | 消馮八 | false | o0000826505 | 1490386088808 | 小米 | 1 | p0005004 | 紅米 5s | 499.01 | 手機(jī) | null | s0015 | 售周五 | 499.01 |+----------------------------------+-------+--------+---------+-------------+---------------+--------+--------+----------+---------+--------+-------+---------------+-------+--------+------------+
統(tǒng)計(jì)所有訂單中每個(gè)商品品牌的訂單數(shù):
select pBrand,count(*) from `order` group bypBrand;
+--------+----------+| pBrand | count(*) |+--------+----------+| vivo | 162539 |+--------+----------+| 聯(lián)想 | 304252 |+--------+----------+| oppo | 242513 |+--------+----------+| 蘋(píng)果 | 96153 |+--------+----------+| 小米 | 194543 |+--------+----------+
總結(jié)
Cloud Native
表格存儲(chǔ) Tablestore 作為一款廣泛應(yīng)用 Serverless DataBase,提供了經(jīng)濟(jì)的計(jì)費(fèi)模式,能大幅縮減業(yè)務(wù)成本。以上文訂單場(chǎng)景為例子,在一億訂單數(shù)據(jù)量級(jí)和平均 2000TPS 的讀寫(xiě)量下,采用表格存儲(chǔ) Tablestore 僅需不到 400元/月 的使用成本。與此同時(shí),Tablestore 具備極致的彈性服務(wù)能力和完全零運(yùn)維的特性,能夠給用戶(hù)帶來(lái)更絲滑的使用體驗(yàn)。