暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

典型场景 | PolarDB-X 如何支撑SaaS多租户? 下

小希 2024-06-26
320

当二级分区及Locality能力解决了B公司对于不同品牌的多租户资源隔离后, 那马上需要面临的问题自然是:用户将如何有效便捷地管理这些多租户?答案是 PolarDB-X 2.0 的分区管理能力。

PolarDB-X 2.0 对于分区表提供了一系列完备的灵活强大的分区管理命令(如下图所示),让用户能够仅仅通过简单SQL命令,就可以实现在多租户场景下的不同运维变更的诉求。

下边我们还是通过B公司的例子,来单独介绍基于分区管理支持SaaS多租户场景下的常见的运维变更。

场景一:基于修改LIST分区实现给租户添加新的卖家

以B公司为例,B公司的一个租户对应的是一个品牌方,一个品牌在B公司的平台通常会有多个卖家。因此,当品牌方开了新的商铺时,就需要将新的卖家ID加入到这个品牌方对应的租户资源之下。

借助 PolarDB-X 的 MODIFY PARTITION ADD/DROP VALUES 的功能,可以方便地给 LIST 分区添加新的卖家ID, 如下所示:

/* 给品牌 pb 增加新的卖家 205 */
ALTER TABLE t_orders MODIFY PARTITION pb ADD VALUES (205);

在这个DDL的执行中,PolarDB-X 会自动地从 LIST 的 DEFAULT 分区 (如果有显式定义 DEFAULT 分区的话)抽取 sellerId=205 的所有数据,并迁移到 pb 分区中,DDL 全过程 Online ,业务应用几乎无感知。

场景二:基于增加LIST分区实现给添加新租户并分配新的存储资源

诸如B公司这类订单管理平台,平台上的各品牌的卖家通常会经历从无到有,从小卖家发展成大卖家的过程。因此,当一个品牌的小卖家发展成一个大卖家时,该品牌就可能会让 B公司将它的卖家从中小品牌的卖家池(比如,DEFAULT 分区)中抽取了出来,使之成为独立租户的VIP,并为之分配单独的存储资源。

借助 PolarDB-X 的 ADD/DROP PARTITION 及其 Locality 的功能,B公司可以很便捷地在线地完成上述场景的变更操作。例如,B公司想将新的大品牌 pe 的大卖家 301 从 DEFAULT 分区中抽取出来,并使之独占新的存储资源 new_dn ,如下所示:

/* 1.B公司在管控购买新的 CN/DN 的节点资源... */
/* 2.增加新的大卖家,创建新分区并放置到特定的DN节点 */
ALTER TABLE t_orders ADD PARTITION (
  /* pDefault 分区里再抽取出新的大卖家 301 , 并命名为 pe, 并将其数据放置新节点 new_dn */
	PARTITION pe VALUES IN (301) LOCALITY='dn=new_dn' SUBPARTITIONS 1,
);

与 MODIFY PARTITION 类似,这些 ADD/DROP PARTITION 的变更操作也属于 Online DDL, 这中间的数据迁移操作对业务应用近乎透明。

场景三:基于分区级Locality支持租户内二级分区数据的重均衡

PolarDB-X 的 LIST + KEY 非模板化二级分区,在多租户场景下,能给用户提供一个重要的特性,就是它允许不同的租户的二级哈希分区数目不一样。这样意味着,不同的租户允许通过定义不同的二级分区数目,可以使用不同数量的存储资源。

例如,B公司的 t_orders 表的 LIST 分区定义中,大品牌 pc 的一级 LIST 分区之下的二级分区数目是2,并同时独占了2个DN节点来存储订单数据(即 pc 分区的每个DN节点都分配一个二级分区)。此外,还有它的中小品牌的卖家所共享的 DEFAULT 分区之下有64个二级分区,并且还独占 dn0 ~ dn15 共16个DN节点(如下所示):

  PARTITION pDefault VALUES IN (DEFAULT) 
    /* 一级分区 pDefault 占用 dn0 ~ dn3 共16个DN, 中小品牌共享 */
  	LOCALITY='dn=dn0,dn1,...,dn2,dn15' 
    SUBPARTITIONS 64 

可是,DEFAULT分区里的众多中小卖家也可能存在一些热点(比如,20%的头部卖家可能占订单数量80%),这些热点卖家如果分布不合理,也可能会导致DEFAULT内部的16个DN节点间负载不均衡。

因此,B公司需要面临的问题是:该如何管理这64个二级分区的众多中小卖家的订单数据,才能相对均衡地分布到这16个DN节点,并保证系统整体的负载均衡呢? 这就是需要使用 PolarDB-X 的分区级 Rebalance 能力 。

PolarDB-X 的 分区级 Rebalance 功能允许用户对一个一级分区内部的多个二级分区,按一级分区的 Locality 进行自动的物理分片调度,使这些二级分区在 Locality 所定义的DN节点上保持均衡分布。用户只需要执行一条SQL命令(如下所示), 即可完成上述的均衡变更,:

REBLANCE TABLE t_orders PARTITIONS=pDefault;

场景四:基于分区选择及视图功能支持租户的数据查询及数据安全

PolarDB-X 的分区表及 Locality 的 SaaS 级多租户能力,对于诸如B公司这类订单管理平台,除了能满足其对品方的数据隔离与资源隔离的诉求外,还可以为业务提供更多的数据查询的能力。

比如,B公司平台上的大品牌,偶尔还需要使用诸如独立查询及分析自己的订单数据等的VIP服务。这些品牌方会通过B公司所提供一些Web SQL工具来直接查询分析自己的订单数据(比如,查询重要客户的订单数目等)。

可是,B公司作为平台性的系统,它需要保证不同租户间的数据安全及其隔离:即租户查询订单数据只能看到自己的数据,无法看到其它租户的任何数据。

那么,基于PolarDB-X 的分区表,B公司是如何解决不同租户的数据隔离的问题呢? 答案是借助分区选择与视图定义。

比如,B公司如果想授权它的租户 pb 单独查询及分析它自己的订单数据,它的Web SQL工具将会自动化地使用类似以下的 SQL 命令提前在 PolarDB-X 上为该租户 pb 创建出对应的只读视图 t_order_pb_view :

CREATE VIEW t_order_pb_view AS 
SELECT * 
FROM t_orders PARTITION(pb) /*  t_orders 表的数据只会返回 pb分区以及下所有二级分区 */ ;

然后,平台再通过对租户 pb 账号信息进行自动化的相关授权操作后,租户 pb 在其所提供的 Web SQL工具里登录后将只允许看到 t_order_pb_view 这个只读视图。

那么,假如租户要执行诸如下边所示的这类的统计订单总数的视图查询:

/* 大租户 pb  查询订单数据的SQL:统计订单数目 */
SELECT COUNT(1) FROM t_order_pb_view;

,PolarDB-X 将自动地把视图 t_order_pb_view 替换为对应的子查询:

/* 大租户 pb  查询订单数据的SQL:统计订单数目 */
SELECT COUNT(1) FROM 
(
   SELECT * 
	 FROM 
   t_orders PARTITION(pb)
) as t_order_pb_view;

如此一来,基于分区选择语法的限定,视图 t_order_pb_view 将只允许返回 pb 分区的数据。这样租户 pb 无法查询到其它租户的卖家订单数据,从而达到数据隔离的效果。

实践总结

PolarDB-X 分区表及其配套的灵活的管理语法,在不同的业务场景下,可以包装出各种业务模型。比如,本文所介绍的基于非模板化二级分区 + Locality 能力的所构建的SaaS多租户就是其中的经典用法之一。

事实上,本文所提及的真实案例的B公司的商家订单管理系统已经基于上述的 PolarDB-X 2.0 的 SaaS 多租户方案成功上线(其应用架构如下图所示),目前它所提供的平台负责管理着超过50T的订单数据。

但是,B公司的案例显然是一个能够复制并推而广之的案例。比如,它的租户维度--品牌,可以很容易联想到其它的业务维度并可以构建类似的实践,比如,各大仓库物流单管理、直播平台各直播室的观众送礼物的数据管理、各大城市交通监控数据管理、各大省份气象监控数据收集,等等。

简单总结一下最佳实践,若业务场景存在

  • 需要对数据按某个维度(比如,地域、仓库、商家或品牌等)进行水平切分,划分多个业务单元;
  • 还需要为切分后的业务单元进行不同的资源配置及数据的物理隔离;

以上几点的,用户都可以参考使用本文 SaaS 多租户方案进行数据库设计。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论