SaaS多租戶背景
很多平臺(tái)類應(yīng)用或系統(tǒng)(如電商CRM平臺(tái)、倉(cāng)庫(kù)訂單平臺(tái)等等),它們的服務(wù)模型是圍繞用戶維度(這里的用戶維度可以是一個(gè)賣家或品牌,可以是一個(gè)倉(cāng)庫(kù)等)展開的。因此,這類型的平臺(tái)業(yè)務(wù),為了支持業(yè)務(wù)系統(tǒng)的水平擴(kuò)展性,業(yè)務(wù)的數(shù)據(jù)庫(kù)通常是按用戶維度進(jìn)行水平切分。
可是,當(dāng)平臺(tái)類應(yīng)用的一些用戶慢慢成長(zhǎng)為大用戶(比如大品牌、大賣家、大倉(cāng)庫(kù)等)后,這些大用戶由于其數(shù)據(jù)量或流量明顯要比其它用戶多得多,容易導(dǎo)致以下的現(xiàn)象:
???大用戶所在分片會(huì)成為業(yè)務(wù)系統(tǒng)的熱點(diǎn),占用大量的數(shù)據(jù)庫(kù)資源,其服務(wù)質(zhì)量容易因資源受限導(dǎo)致不穩(wěn)定;
?? 其它小用戶容易受到大用戶資源消耗的影響,服務(wù)質(zhì)量也受到影響。
最后就整個(gè)平臺(tái)的業(yè)務(wù)系統(tǒng)的熱點(diǎn)頻現(xiàn),數(shù)據(jù)庫(kù)訪問不穩(wěn)定,業(yè)務(wù)服務(wù)受影響。
SaaS多租戶模型作為一種應(yīng)用的架構(gòu),常用來解決業(yè)務(wù)的上述問題。在SaaS多租戶模型中,業(yè)務(wù)系統(tǒng)會(huì)需要服務(wù)多個(gè)用戶,每個(gè)用戶(或每批用戶)可以被視為一個(gè)租戶。
這些不同的租戶在業(yè)務(wù)系統(tǒng)內(nèi)會(huì)使用共同的基礎(chǔ)設(shè)施及其平臺(tái)進(jìn)行運(yùn)行,但來自不同租戶的數(shù)據(jù)仍將被獨(dú)立隔離,因此,通常租戶擁有自己物理資源來單獨(dú)存儲(chǔ)與管理數(shù)據(jù)。所以,SaaS多租戶解決業(yè)務(wù)系統(tǒng)穩(wěn)定性問題以及租戶資源彈性定制的核心思路,就是租戶間的資源隔離及數(shù)據(jù)隔離。
在實(shí)際的不同應(yīng)用場(chǎng)景下,常見的 SaaS 多租戶方案有兩種:
???Schema級(jí)SaaS多租戶
Schema 級(jí) SaaS 多租戶,是指一個(gè)租戶對(duì)應(yīng)一個(gè)包含多個(gè)Table定義的Schema(或一個(gè)Database,在MySQL, Schema概念等同Database),?不同租戶的Schema會(huì)分布在不同的機(jī)器上(如下圖1所示),實(shí)現(xiàn)資源隔離,該方案適用于不同租戶需要使用獨(dú)立Schema運(yùn)行的場(chǎng)景;
???Partition級(jí)SaaS多租戶
Partition 級(jí) SaaS 多租戶,是指一個(gè)租戶會(huì)對(duì)應(yīng)一個(gè)Table的一個(gè)或多個(gè)的分區(qū)(或是一個(gè)Table的一部分rows),不同租戶的Parittion會(huì)分布在不同的機(jī)器上(如上圖2所示),以實(shí)現(xiàn)資源隔離,該方案比較適用于不同租戶需要使用統(tǒng)一Schema運(yùn)行的場(chǎng)景。
從隔離程度來看, Schema 級(jí) SaaS 多租戶比 Partition 級(jí) SaaS 多租戶要隔離得更徹底,但前者因?yàn)橐S護(hù)眾多的Schema,會(huì)比后者會(huì)帶來更高的運(yùn)維成本及查詢分析成本。
不過,Partition級(jí)SaaS多租戶通常要依賴中間件分庫(kù)分表或分布式數(shù)據(jù)庫(kù)分區(qū)功能(不然單機(jī)數(shù)據(jù)庫(kù)無法做到資源隔離)才能運(yùn)作,而Schema級(jí)SaaS多租戶則不需要,用戶自己搭建幾個(gè)單機(jī)MySQL也可以運(yùn)作起來,準(zhǔn)入門檻更低。
業(yè)務(wù)的問題
業(yè)務(wù)多租戶場(chǎng)景
只說應(yīng)用架構(gòu)可能有些抽象,為了方便讀者更容易地理解 SaaS 多租戶是如何幫助業(yè)務(wù)解決問題, 本文將以一個(gè)真實(shí)的案例來進(jìn)行闡述。
正馬軟件的班牛平臺(tái)是國(guó)內(nèi)領(lǐng)先的提供電商全周期客戶服務(wù)的賣家訂單管理平臺(tái)(以下簡(jiǎn)稱B公司)。它的業(yè)務(wù)系統(tǒng)需要維護(hù)多個(gè)不同品牌的眾多賣家。通常一個(gè)品牌會(huì)有多個(gè)賣家(比如,一個(gè)品牌可能會(huì)開通多個(gè)線上店鋪),所以,品牌與賣家是一對(duì)多的關(guān)系。
目前,B公司的訂單管理平臺(tái)管理著超過50T的訂單數(shù)據(jù),日QPS近3W+,不同品牌的訂單量差異會(huì)比較大(大品牌的訂單可能是小品牌的訂單量的近百倍或更高)。一些大品牌除了訂單量比其它品牌的大很多之外,還會(huì)使用更高級(jí)的付費(fèi)VIP服務(wù):比如,要求訂單數(shù)據(jù)獨(dú)占資源與數(shù)據(jù)隔離、允許獨(dú)立地統(tǒng)計(jì)分析自己品牌的訂單數(shù)據(jù)等。
B公司為了解決不同品牌的數(shù)據(jù)的資源使用及其服務(wù)差異,就會(huì)對(duì)它的賣家按品牌劃分(相當(dāng)于一個(gè)品牌是一個(gè)租戶):
大品牌訴求:
訂單量大(如訂單數(shù)據(jù)存儲(chǔ)的大小超過1T或2T),數(shù)據(jù)存儲(chǔ)量大;
獨(dú)占一組的存儲(chǔ)資源、有獨(dú)立訪問分析數(shù)據(jù)的需求;
該品牌的所有商家都必須同一組的存儲(chǔ)資源;
大品牌的大賣家150+,后邊還會(huì)陸續(xù)增加;
小品牌訴求:
訂單表小,商家數(shù)目大(6W+賣家);
共用一組存儲(chǔ)資源;
要求所有賣家數(shù)據(jù)在存儲(chǔ)上均衡分布。
現(xiàn)在的核心問題是,B公司的訂單管理平臺(tái)的數(shù)據(jù)庫(kù)應(yīng)該如何設(shè)計(jì),才能滿足上述眾多不同品牌及其大賣家對(duì)于不同資源使用與數(shù)據(jù)隔離的訴求?
普通中間件方案及其問題
對(duì)于上述的業(yè)務(wù)場(chǎng)景,B公司若不使用分布式數(shù)據(jù)庫(kù),而是簡(jiǎn)單通過單機(jī)MySQL及一些開源的分庫(kù)分表中間件,自己搭建一套SaaS多租戶方案(比如將品牌及其賣家切分為租戶),進(jìn)行租戶的資源隔離。表面上,這貌似可行;但實(shí)際上,業(yè)務(wù)會(huì)因此要面臨更多更為棘手的問題。
首先是跨機(jī)分布式事務(wù)問題。絕大多數(shù)的分庫(kù)分表中間件無法提供強(qiáng)一致分布式事務(wù)能力,或者只能提供基于最終一致性的事務(wù)補(bǔ)償方案,這意味著業(yè)務(wù)需要做很多額外的應(yīng)用改造成本,才能盡量來避免跨機(jī)事務(wù)導(dǎo)致業(yè)務(wù)出現(xiàn)報(bào)錯(cuò)。
然后是 Schema 一致性問題?;谥虚g件分庫(kù)分表,無論是采用 Schema 級(jí)多租戶及是 Partition 級(jí)多租戶,B公司的訂單平臺(tái)都要面臨自己維護(hù)各個(gè)租戶的 Schema 或 Table 的元數(shù)據(jù)一致性。比如,MySQL的建刪表、加減列、加減索引等常見的DDL操作,中間件的方案無顯然法保證平臺(tái)所有租戶的表能同時(shí)生效,一旦執(zhí)行中斷,必須靠人工介入來訂正,人力成本高。
接著是租戶的數(shù)據(jù)遷移問題?;赟aaS多租戶方案,B公司若要給一個(gè)大品牌分配新的獨(dú)立資源,這自然免不了將租戶數(shù)據(jù)從原來機(jī)器到新機(jī)器的數(shù)據(jù)遷移。這個(gè)數(shù)據(jù)遷移操作只能依賴額外的同步工具構(gòu)建同步鏈路才能完成,這中間切割過程甚至還需要業(yè)務(wù)停機(jī)。這意味,業(yè)務(wù)執(zhí)行添加一個(gè)新租戶這一基本操作,也會(huì)帶來非常高昂的運(yùn)維成本。
綜合上述的分析,B公司直接基于單機(jī)MySQL及一些中間件的SaaS多租戶方案,并不是一個(gè)成本低廉的方案。
SaaS多租戶PolarDB分布式版方案
事實(shí)上,在阿里云瑤池旗下的云原生數(shù)據(jù)庫(kù)PolarDB分布式版 2.0(PolarDB for Xscale,簡(jiǎn)稱PolarDB-X)?中,B公司已經(jīng)可以通過結(jié)合非模板化二級(jí)分區(qū)與Locality兩項(xiàng)能力,來很好的解決其上述業(yè)務(wù)所面臨的問題。為了方便讀者更易理解,以下先簡(jiǎn)單介紹下 PolarDB分布式版 2.0 的非模板化二級(jí)分區(qū)與Locality兩項(xiàng)的功能。
非模板化二級(jí)分區(qū)
PolarDB分布式版?從 5.4.17 開始支持使用二級(jí)分區(qū)創(chuàng)建分區(qū)表。與其它分布式數(shù)據(jù)庫(kù)所有不同,PolarDB分布式版的二級(jí)分區(qū)除了語法能完全兼容原生MySQL二級(jí)分區(qū)語法外,還額外擴(kuò)展很多的二級(jí)分區(qū)的能力,比如:支持用戶定義非模板化二級(jí)分區(qū)(原生MySQL只支持模板化二級(jí)分區(qū))。
所謂的非模板化二級(jí)分區(qū),就是各個(gè)一級(jí)分區(qū)之下的二級(jí)分的分區(qū)數(shù)目及其邊界值定義允許不一致,如下所示:
/* 一級(jí)分區(qū) LIST COLUMNS + 二級(jí)分區(qū)HASH分區(qū) 的非模板化組合分區(qū) */
CREATE TABLE t_order /* 訂單表 */ (
id bigint not null auto_increment,
sellerId bigint not null,
buyerId bigint not null,
primary key(id)
)
PARTITION BY LIST(sellerId/*賣家ID*/) /* */
SUBPARTITION BY HASH(sellerId)
(
PARTITION pa VALUES IN (108,109)
SUBPARTITIONS 1 /* 一級(jí)分區(qū) pa 之下有1個(gè)哈希分區(qū), 保存大品牌 a 所有賣家數(shù)據(jù) */,
PARTITION pb VALUES IN (208,209)
SUBPARTITIONS 1 /* 一級(jí)分區(qū) pb 之下有1個(gè)哈希分區(qū), 保存大品牌 b 所有賣家數(shù)據(jù) */,
PARTITION pc VALUES IN (308,309,310)
SUBPARTITIONS 2 /* 一級(jí)分區(qū) pc 之下有2個(gè)哈希分區(qū), 保存大品牌 c 所有賣家數(shù)據(jù) */,
PARTITION pDefault VALUES IN (DEFAULT)
SUBPARTITIONS 64 /* 一級(jí)分區(qū) pDefault 之下有64個(gè)哈希分區(qū), 眾多小品牌的賣家數(shù)據(jù) */
);
基于上述的 LIST+HASH 非模板化二級(jí)分區(qū),它能給應(yīng)用直接帶來的的效果是:
- 對(duì)于大品牌的賣家(相當(dāng)一個(gè)租戶),可以將數(shù)據(jù)路由到單獨(dú)的一組分區(qū);
- 對(duì)于中小品牌,可以將數(shù)據(jù)按哈希算法自動(dòng)均衡到多個(gè)不同分區(qū),從而避免訪問熱點(diǎn)。
當(dāng)大品牌與中小品牌的商家數(shù)據(jù)按LIST分區(qū)實(shí)現(xiàn)了分區(qū)級(jí)的隔離后,那實(shí)現(xiàn)大品牌與中小品牌的存儲(chǔ)資源的物理隔離也就自然而言的事了。在 PolarDB分布式版 2.0 中,用戶可以借助Locality的能力,很容易地實(shí)現(xiàn)不同分區(qū)之間的資源隔離。
LOCALITY資源綁定
PolarDB分布式版支持通過LOCALITY關(guān)鍵字來指定數(shù)據(jù)庫(kù)分區(qū)的實(shí)際存儲(chǔ)資源位置(PolarDB分布式版中存儲(chǔ)資源由多個(gè)數(shù)據(jù)節(jié)點(diǎn)(DN節(jié)點(diǎn))組成,可以通過DN的ID進(jìn)行位置分配),以實(shí)現(xiàn)數(shù)據(jù)隔離或數(shù)據(jù)的均勻分布。它的具體語法如下所示:
ALTER TABLE #tableName
MODIFY (SUB)PARTITION #(sub)partName
SET LOCALITY='dn=dn1[, dn2,...]'
例如,B公司可以使用以下的SQL命令將 t_order 中的大品牌 pa 的數(shù)據(jù)全部單獨(dú)挪到一個(gè)存儲(chǔ)節(jié)點(diǎn) dn4 :
ALTER TABLE t_order MODIFY PARTITION pa SET LOCALITY='dn=dn4'
在實(shí)際使用中,用戶可以通過 SHOW STORAGE 查詢 PolarDB-X 的所有DN節(jié)點(diǎn)實(shí)例ID列表,例如:
mysql> show storage;
+----------------------------+----------------+------------+-----------+----------+-------------+--------+-----------+------------+--------+
| STORAGE_INST_ID | LEADER_NODE | IS_HEALTHY | INST_KIND | DB_COUNT | GROUP_COUNT | STATUS | DELETABLE | DELAY | ACTIVE |
+----------------------------+----------------+------------+-----------+----------+-------------+--------+-----------+------------+--------+
| polardbx-storage-0-master | 10.0.x.1:3306 | true | MASTER | 41 | 66 | 0 | false | null | null |
| polardbx-storage-1-master | 10.0.x.1:3307 | true | MASTER | 41 | 53 | 0 | true | null | null |
| ...... | ...... | true | META_DB | 2 | 2 | 0 | false | null | null |
+----------------------------+----------------+------------+-----------+----------+-------------+--------+-----------+------------+--------+
設(shè)計(jì)SaaS多租戶方案
回到之前B公司的例子,B公司的核心需求是要實(shí)現(xiàn)大品牌與中小品牌的賣家數(shù)據(jù)及其存儲(chǔ)資源的隔離。那么,B公司可以在上述的二級(jí)分區(qū)的分區(qū)表的基礎(chǔ)上,通過再給每個(gè)一級(jí)分區(qū)增加對(duì)應(yīng)的LOCALITY定義,以指定一級(jí)分區(qū)及其所有二級(jí)分區(qū)所允許使用的存儲(chǔ)資源,那么業(yè)務(wù)就可以在建表階段直接實(shí)現(xiàn)SaaS層多租戶(即品牌方)存儲(chǔ)資源的隔離,如下所示:
/* 一級(jí)分區(qū):list columns,二級(jí)分區(qū):key 的非模板化組合分區(qū) */
CREATE TABLE t_orders /* 訂單表 */ (
id bigint not null auto_increment,
sellerId bigint not null,
buyerId bigint not null,
primary key(id)
)
PARTITION BY LIST(sellerId /* 賣家ID */ )
SUBPARTITION BY HASH(sellerId)
(
PARTITION pa VALUES IN (108,109,....)
LOCALITY='dn=dn16' /* 大品牌 pa 獨(dú)占一個(gè)DN dn4 */
SUBPARTITIONS 1,
PARTITION pb VALUES IN (208,209,....)
LOCALITY='dn=dn17' /* 大品牌 pb 獨(dú)占一個(gè)DN dn5 */
SUBPARTITIONS 1 ,
PARTITION pc VALUES IN (308,309,310,...)
LOCALITY='dn=dn18,dn19' /* 大品牌 pc 獨(dú)占兩個(gè)DN: dn6 與 dn7 */
SUBPARTITIONS 2,
PARTITION pDefault VALUES IN (DEFAULT)
/* 一級(jí)分區(qū) pDefault 占用 dn0 ~ dn15 共16個(gè)DN, 中小品牌共享 */
LOCALITY='dn=dn0,dn1,...,dn2,dn15'
SUBPARTITIONS 64
);
如上圖所示,通過Locality對(duì)各個(gè)一級(jí)分區(qū)的DN節(jié)點(diǎn)資源的綁定,pa、pb、pc這3個(gè)大品牌的租戶被分別配了DN16、DN17 與 DN18~DN19 3組的節(jié)點(diǎn)資源,而中小賣家池的 pDefault 分區(qū)則被綁定了16個(gè)DN節(jié)點(diǎn)。
SaaS多租戶運(yùn)維管理
當(dāng)二級(jí)分區(qū)及Locality能力解決了B公司對(duì)于不同品牌的多租戶資源隔離后, 那馬上需要面臨的問題自然是:用戶將如何有效便捷地管理這些多租戶?答案是?PolarDB分布式版?2.0 的分區(qū)管理能力。
PolarDB分布式版?2.0 對(duì)于分區(qū)表提供了一系列完備的靈活強(qiáng)大的分區(qū)管理命令(如下圖所示),讓用戶能夠僅僅通過簡(jiǎn)單SQL命令,就可以實(shí)現(xiàn)在多租戶場(chǎng)景下的不同運(yùn)維變更的訴求。
接下來我們還是通過B公司的例子,來單獨(dú)介紹基于分區(qū)管理支持SaaS多租戶場(chǎng)景下的常見的運(yùn)維變更。
場(chǎng)景一:基于修改LIST分區(qū)實(shí)現(xiàn)給租戶添加新的賣家
以B公司為例,B公司的一個(gè)租戶對(duì)應(yīng)的是一個(gè)品牌方,一個(gè)品牌在B公司的平臺(tái)通常會(huì)有多個(gè)賣家。因此,當(dāng)品牌方開了新的商鋪時(shí),就需要將新的賣家ID加入到這個(gè)品牌方對(duì)應(yīng)的租戶資源之下。
借助 PolarDB-X 的 MODIFY PARTITION ADD/DROP VALUES 的功能,可以方便地給 LIST 分區(qū)添加新的賣家ID,如下所示:
/* 給品牌 pb 增加新的賣家 205 */
ALTER TABLE t_orders MODIFY PARTITION pb ADD VALUES (205);
在這個(gè)DDL的執(zhí)行中,PolarDB分布式版會(huì)自動(dòng)地從 LIST 的 DEFAULT 分區(qū)(如果有顯式定義 DEFAULT 分區(qū)的話)抽取 sellerId=205 的所有數(shù)據(jù),并遷移到 pb 分區(qū)中,DDL 全過程 Online ,業(yè)務(wù)應(yīng)用幾乎無感知。
場(chǎng)景二:基于增加LIST分區(qū)實(shí)現(xiàn)給添加新租戶并分配新的存儲(chǔ)資源
諸如B公司這類訂單管理平臺(tái),平臺(tái)上的各品牌的賣家通常會(huì)經(jīng)歷從無到有,從小賣家發(fā)展成大賣家的過程。因此,當(dāng)一個(gè)品牌的小賣家發(fā)展成一個(gè)大賣家時(shí),該品牌就可能會(huì)讓 B公司將它的賣家從中小品牌的賣家池(比如DEFAULT分區(qū))中抽取了出來,使之成為獨(dú)立租戶的VIP,并為之分配單獨(dú)的存儲(chǔ)資源。
借助PolarDB分布式版的 ADD/DROP PARTITION 及其 Locality 的功能,B公司可以很便捷地在線地完成上述場(chǎng)景的變更操作。例如,B公司想將新的大品牌 pe 的大賣家 301 從 DEFAULT 分區(qū)中抽取出來,并使之獨(dú)占新的存儲(chǔ)資源 new_dn ,如下所示:
/* 1.B公司在管控購(gòu)買新的 CN/DN 的節(jié)點(diǎn)資源... */
/* 2.增加新的大賣家,創(chuàng)建新分區(qū)并放置到特定的DN節(jié)點(diǎn) */
ALTER TABLE t_orders ADD PARTITION (
/* pDefault 分區(qū)里再抽取出新的大賣家 301 , 并命名為 pe, 并將其數(shù)據(jù)放置新節(jié)點(diǎn) new_dn */
PARTITION pe VALUES IN (301) LOCALITY='dn=new_dn' SUBPARTITIONS 1,
);
與MODIFY PARTITION類似,這些ADD/DROP PARTITION的變更操作也屬于Online DDL, 這中間的數(shù)據(jù)遷移操作對(duì)業(yè)務(wù)應(yīng)用近乎透明。
場(chǎng)景三:基于分區(qū)級(jí)Locality支持租戶內(nèi)二級(jí)分區(qū)數(shù)據(jù)的重均衡
PolarDB分布式版的LIST + KEY非模板化二級(jí)分區(qū),在多租戶場(chǎng)景下,能給用戶提供一個(gè)重要的特性,就是它允許不同的租戶的二級(jí)哈希分區(qū)數(shù)目不一樣。這樣意味著,不同的租戶允許通過定義不同的二級(jí)分區(qū)數(shù)目,可以使用不同數(shù)量的存儲(chǔ)資源。
例如,B公司的 t_orders 表的 LIST 分區(qū)定義中,大品牌 pc 的一級(jí) LIST 分區(qū)之下的二級(jí)分區(qū)數(shù)目是2,并同時(shí)獨(dú)占了2個(gè)DN節(jié)點(diǎn)來存儲(chǔ)訂單數(shù)據(jù)(即 pc 分區(qū)的每個(gè)DN節(jié)點(diǎn)都分配一個(gè)二級(jí)分區(qū))。此外,還有它的中小品牌的賣家所共享的 DEFAULT 分區(qū)之下有64個(gè)二級(jí)分區(qū),并且還獨(dú)占 dn0 ~ dn15 共16個(gè)DN節(jié)點(diǎn)(如下所示):
PARTITION pDefault VALUES IN (DEFAULT)
/* 一級(jí)分區(qū) pDefault 占用 dn0 ~ dn3 共16個(gè)DN, 中小品牌共享 */
LOCALITY='dn=dn0,dn1,...,dn2,dn15'
SUBPARTITIONS 64
可是,DEFAULT分區(qū)里的眾多中小賣家也可能存在一些熱點(diǎn)(比如,20%的頭部賣家可能占訂單數(shù)量80%),這些熱點(diǎn)賣家如果分布不合理,也可能會(huì)導(dǎo)致DEFAULT內(nèi)部的16個(gè)DN節(jié)點(diǎn)間負(fù)載不均衡。
因此,B公司需要面臨的問題是:該如何管理這64個(gè)二級(jí)分區(qū)的眾多中小賣家的訂單數(shù)據(jù),才能相對(duì)均衡地分布到這16個(gè)DN節(jié)點(diǎn),并保證系統(tǒng)整體的負(fù)載均衡呢?這就是需要使用PolarDB分布式版的分區(qū)級(jí)Rebalance能力。
PolarDB分布式版的分區(qū)級(jí) Rebalance 功能允許用戶對(duì)一個(gè)一級(jí)分區(qū)內(nèi)部的多個(gè)二級(jí)分區(qū),按一級(jí)分區(qū)的 Locality 進(jìn)行自動(dòng)的物理分片調(diào)度,使這些二級(jí)分區(qū)在 Locality 所定義的DN節(jié)點(diǎn)上保持均衡分布。用戶只需要執(zhí)行一條SQL命令(如下所示), 即可完成上述的均衡變更:
REBLANCE TABLE t_orders PARTITIONS=pDefault;
場(chǎng)景四:基于分區(qū)選擇及視圖功能支持租戶的數(shù)據(jù)查詢及數(shù)據(jù)安全
PolarDB分布式版的分區(qū)表及Locality的SaaS級(jí)多租戶能力,對(duì)于諸如B公司這類訂單管理平臺(tái),除了能滿足其對(duì)品方的數(shù)據(jù)隔離與資源隔離的訴求外,還可以為業(yè)務(wù)提供更多的數(shù)據(jù)查詢的能力。
比如,B公司平臺(tái)上的大品牌,偶爾還需要使用諸如獨(dú)立查詢及分析自己的訂單數(shù)據(jù)等的VIP服務(wù)。這些品牌方會(huì)通過B公司所提供一些Web SQL工具來直接查詢分析自己的訂單數(shù)據(jù)(比如查詢重要客戶的訂單數(shù)目等)。
可是,B公司作為平臺(tái)性的系統(tǒng),它需要保證不同租戶間的數(shù)據(jù)安全及其隔離:即租戶查詢訂單數(shù)據(jù)只能看到自己的數(shù)據(jù),無法看到其它租戶的任何數(shù)據(jù)。
那么,基于PolarDB分布式版的分區(qū)表,B公司是如何解決不同租戶的數(shù)據(jù)隔離的問題呢?答案是借助分區(qū)選擇與視圖定義。
比如,B公司如果想授權(quán)它的租戶 pb 單獨(dú)查詢及分析它自己的訂單數(shù)據(jù),它的Web SQL工具將會(huì)自動(dòng)化地使用類似以下的SQL命令提前在PolarDB分布式版上為該租戶 pb 創(chuàng)建出對(duì)應(yīng)的只讀視圖 t_order_pb_view :
CREATE VIEW t_order_pb_view AS
SELECT *
FROM t_orders PARTITION(pb) /* t_orders 表的數(shù)據(jù)只會(huì)返回 pb分區(qū)以及下所有二級(jí)分區(qū) */ ;
然后,平臺(tái)再通過對(duì)租戶 pb 賬號(hào)信息進(jìn)行自動(dòng)化的相關(guān)授權(quán)操作后,租戶 pb 在其所提供的 Web SQL工具里登錄后將只允許看到 t_order_pb_view 這個(gè)只讀視圖。
那么,假如租戶要執(zhí)行諸如下邊所示的這類的統(tǒng)計(jì)訂單總數(shù)的視圖查詢:
/* 大租戶 pb 查詢訂單數(shù)據(jù)的SQL:統(tǒng)計(jì)訂單數(shù)目 */
SELECT COUNT(1) FROM t_order_pb_view;
PolarDB分布式版將自動(dòng)地把視圖 t_order_pb_view 替換為對(duì)應(yīng)的子查詢:
/* 大租戶 pb 查詢訂單數(shù)據(jù)的SQL:統(tǒng)計(jì)訂單數(shù)目 */
SELECT COUNT(1) FROM
(
SELECT *
FROM
t_orders PARTITION(pb)
) as t_order_pb_view;
如此一來,基于分區(qū)選擇語法的限定,視圖 t_order_pb_view 將只允許返回 pb 分區(qū)的數(shù)據(jù)。這樣租戶 pb 無法查詢到其它租戶的賣家訂單數(shù)據(jù),從而達(dá)到數(shù)據(jù)隔離的效果。
實(shí)踐總結(jié)
PolarDB分布式版分區(qū)表及其配套的靈活的管理語法,在不同的業(yè)務(wù)場(chǎng)景下,可以包裝出各種業(yè)務(wù)模型。比如,本文所介紹的基于非模板化二級(jí)分區(qū) + Locality能力的所構(gòu)建的SaaS多租戶就是其中的經(jīng)典用法之一。
事實(shí)上,本文所提及的真實(shí)案例的B公司的商家訂單管理系統(tǒng)已經(jīng)基于上述的 PolarDB分布式版?2.0 的 SaaS 多租戶方案成功上線(其應(yīng)用架構(gòu)如下圖所示),目前它所提供的平臺(tái)負(fù)責(zé)管理著超過50T的訂單數(shù)據(jù)。
但是,B公司的案例顯然是一個(gè)能夠復(fù)制并推而廣之的案例。比如,它的租戶維度--品牌,可以很容易聯(lián)想到其它的業(yè)務(wù)維度并可以構(gòu)建類似的實(shí)踐,比如:各大倉(cāng)庫(kù)物流單管理、直播平臺(tái)各直播室的觀眾送禮物的數(shù)據(jù)管理、各大城市交通監(jiān)控?cái)?shù)據(jù)管理、各大省份氣象監(jiān)控?cái)?shù)據(jù)收集,等等。
簡(jiǎn)單總結(jié)一下最佳實(shí)踐,若業(yè)務(wù)場(chǎng)景存在:
???需要對(duì)數(shù)據(jù)按某個(gè)維度(如地域、倉(cāng)庫(kù)、商家或品牌等)進(jìn)行水平切分,劃分多個(gè)業(yè)務(wù)單元;
???還需要為切分后的業(yè)務(wù)單元進(jìn)行不同的資源配置及數(shù)據(jù)的物理隔離;文章來源:http://www.zghlxwxcb.cn/news/detail-793009.html
涉及到以上幾點(diǎn)的用戶都可以參考使用本文SaaS多租戶方案進(jìn)行數(shù)據(jù)庫(kù)設(shè)計(jì)。文章來源地址http://www.zghlxwxcb.cn/news/detail-793009.html
到了這里,關(guān)于典型場(chǎng)景解析|PolarDB分布式版如何支撐SaaS多租戶?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!