SaaS多租户应用程序与数据库数据隔离方案设计与选择
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
软件即服务 (Software as a service,SaaS) 是一种通过互联网按需交付软件应用程序的方法,通常采用订阅方式。借助 SaaS,云服务提供商 (CSP) 可以托管和管理应用程序软件和底层基础设施,保证系统的可靠性。用户可以通过手机或电脑上的网络连接到应用程序。 通俗地讲,就是将用户的服务器相关硬件、操作系统、应用程序搬到云上,让软件提供商来维护。SaaS的优势多用于ToB的业务,将客户本地部署的系统迁移到云上,方方便客户的同时,软件提供商也创新了盈利模式。 SaaS对客户来说有什么优势呢?
客户本地数据迁移到云上或者直接订阅使用云上产品,不可避免需要关注数据的安全隔离。使用单租户模式还是实现多租户数据共存与访问,企业在系统设计之初必须规划多租户的架构解决方案。 我们了解下租户概念:
相信大家也有个疑问,在多租户场景中,为什么要进行用户数据隔离?操作数据时加条件筛选不也可以吗?如下查询:
如果开发者在某个地方漏掉 tenant_id 条件,可能出现以下问题:
通过数据隔离,上述问题就可以完全避免。尽管在操作数据时加条件在一定程度上可以实现多租户数据的隔离,但它存在明显的安全问题。在实际场景中,数据隔离通常是通过物理或逻辑上的手段综合实现的,具体包括分库分表、分区、租户标识符控制等方式。 多租户场景之所以要数据隔离,完全是出于数据安全与隐私保护。数据隔离可以降低数据泄露潜在风险、增强用户对企业系统的信任、符合隐私法规(如GDPR、CCPA等)。 多租户的架构中,最常见的方案主要有四种:
接下来,我简单介绍这几种方案的优劣情况和使用场景。
优点:
缺点:
场景:
优点:
缺点:
场景:
优点:
缺点:
场景:
优点:
缺点:
场景:
在设计有效的多租户数据库时,必须仔细平衡数据隔离、可扩展性、性能和安全性。对于成功运行的多租户系统,每一个要素都至关重要。随着租户数量的增加,数据库需要具有可扩展性,以便处理增加的负载。为了保证数据库能够快速有效地访问数据,性能至关重要。对于这些应用程序,需要考虑实时数据访问。 租户数据库的设计方案,需要结合自身的业务选型。在数据库方面,实现数据隔离主要有数据库、schema、行级这三种。当然也有分区模式和混合模式。 这三个方案会面临的问题,我简单总结如下:
通常SaaS场景下的单个租户数据量不会太大,一般从几十MB至几十GB。新方案初期难确定容量大小,当服务器性能无法满足时,再新增服务器分配新租户来使用。因此设计数据库的时候,需要一个专门存储租户信息的数据库,该数据库用于管理租户、同时也记录该租户数据所在的数据库连接信息。
如果明确租户增长不会太大,且业务功能的使用也不同(较多表可能存在数据倾斜),数据量都是几十GB的,推荐使用数据库隔离模式。我们可以将几十个数据库放在同一个实例中,有效利用计算资源。数据库隔离模式也适合schema隔离模式,当然需要考虑上面提到面临的问题。 当租户数量达成千上万的时候,或者未来租户数能达到这个量级,数据库隔离模式就不必再考虑了,schema隔离模式确实可以考虑。能使用schema模式的常见关系型数据库,如Oracle、SQL Server、PostgreSQL,但如果使用 PostgreSQL 的多schema隔离模式,autovacuum 可能会频繁执行,将是比较大的性能问题! 当上万的租户、或者数据量少的租户,推荐使用行级隔离。行级隔离的基本原理是,当用户操作数据库表时,系统判断是否是某个租户的数据,必须在连接会话中获取能识别租户的信息,如租户账号、租户ID等。获取到的信息需要与表中的行数据进行筛选匹配,如匹配表中字段tenant_id中的值,这样操作的数据只能是该连接的租户数据。 行级隔离不是简单地加where条件筛选指定的租户,因为无法不免有漏掉条件的可能。使用行级别安全(Row Level Security,RLS),即使不加租户相关条件,租户也只能操作自己的数据,达到租户之间的数据安全隔离。目前Oracle、SQL Server、PostgreSQL 等都支持行级别安全。 使用RLS也可能存在数据倾斜,导致数量差异大的租户操作SQL的执行计划不准确,该如何处理呢?前面提到过混合场景和分区方案就是其中的解决方案。数据库少的租户可使用RLS方案,数据量大的租户可以使用数据库或schema方案。另外还可以使用分区方案,分区方案只是辅助RLS解决数据倾斜问题,不作为正式的租户隔离方案。对于数据量大的租户,可以将表进行分区,一个或多个分区存储大租户的数据,另一个分区存储数据量少的租户。 我这里介绍两种案例:
SQL Server有真正的行级隔离方案,但这里我介绍的是另一种非正式的隔离方案,可以说也是一种通用方案,在其他数据库都可以实现。 该方案在视图中添加where条件,识别当前上下文环境的登录用户ID,到表中进行筛选。以下是一个完整的简单示例。
应用程序只操作视图,每张视图背后都对应一张表。由于视图已经隔离了用户数据,任何用户都不可能操作其他用户的数据。如果表结构发生变化,可以通过存储过程sp_refreshview刷新视图定义。这是我以前公司用的一种租户隔离方案,类似RLS。当前你也可以使用SQL Server 官方真正的“行级别安全性(RLS)”设计租户隔离。
另一个实际的案例就是PostgreSQL的“行级安全策略(RLS)”。每张表都存在字段tenant_id,存储租户id,租户id的管理可以从平台数据库中获取。
我们定义策略参数app.tenant_id,当租户连接数据库时,需要设置app.tenant_id的值。当访问表的时候,rls策略将获取上下文信息app.tenant_id的参数值,相当于将“tenant_id=?” 拼接到where条件中,与前面的“SQL Server 使用视图进行行级隔离”有相似之处。 数据库级别与schema级别的数据隔离比较好理解,对租户来说隔离性好,但不适合大量租户的情况。一个企业的租户数据量差异比较大,这就需要考虑产品是否真的符合租户的业务场景。也就是说,企业内部需要对发布多个版本或多个产品满足不同的客户需求,在多租户的数据库设计方面也评估使用不同的数据隔离方案。 我们除了在数据库选型、租户架构选型之外,也要考虑云资源成本。客户获取成本、 客户生命周期价值、月度经常性收入、 客户流失率 是SaaS提供商特别关注的一些关键绩效和业务指标。这些指标对于业务优化和增长至关重要,并且它们提供了SaaS公司财务状况的全面概览。针对租户资源的成本占比、租户均值成本等,评估租户开销是否超出了计划。 阅读原文:https://mp.weixin.qq.com/s/Ba_KqWY5a_SAKN4RvPqH5Q 该文章在 2025/1/25 9:13:25 编辑过 |
关键字查询
相关文章
正在查询... |