saas 多租户系统数据隔离方案

关注WX公众号: commindtech77, 获得数据资产相关白皮书下载地址

  1. 回复关键字:数据资源入表白皮书

下载 《2023数据资源入表白皮书》

  1. 回复关键字:光大银行

下载 光大银行-《商业银行数据资产会计核算研究报告》

  1. 回复关键字:数据资产估值

下载 《商业银行数据资产估值白皮书》

  1. 回复关键字:上海银行

下载 上海银行《商业银行数据资产体系白皮书》

  1. 回复关键字:商业银行数据资产管理

下载 《商业银行数据资产管理体系建设实践报告》

一、背景

网上一堆 saas多租户系统数据隔离方案的文章,本文着重于生产环境实践

二、怎样区分租户

有3种方式:

  1. 通过不同的访问url来区分;
  2. 相同的访问url,由用户输入租户ID;
  3. 相同的访问url,用户登陆后,查询租户ID;
方案 优点 缺点
通过不同的访问url来区分 1. 不用登陆; 2. 不同租户下面的用户名允许重复 用户需要记住url
相同的访问url,由用户输入租户ID 1. 不用登陆; 2. 不同租户下面的用户名允许重复 用户需要记住租户ID
相同的访问url,用户登陆后,查询租户ID 不需要记住租户ID; 1. 需要用户登陆,才能获取租户ID; 2. 用户名不能一样,否则会冲突;

阿里云、腾讯云都是使用第2种方案

阿里云子账号登陆界面

腾讯云子账号登陆界面

三、 3种数据隔离方案架构

  1. 数据库表通过租户ID字段来区分

说明:图片不是原创,在网上找的

  1. 独立的数据库(schema)

说明:图片不是原创,在网上找的

  1. 独立数据库实例

说明:图片不是原创,在网上找的

方案 优点 缺点
数据库表通过租户ID字段来区分 (1)成本低,支持的租户多; (2)实现简单,直接使用mybatis plus的TenantLineInnerInterceptor拦截器即可; (3)系统升级最方便,表变更只要执行一次即可; (4)运营做数据分析方便,不同将多个库的数据汇总分析; (1)数据隔离性差; (2)所有数据存在一起,性能随着数据的增加会变得越来越差;
独立的数据库(schema) (1)成本较低,支持的租户较多; (2)性能够好,当存在性能问题时,迁移到独立数据库实例,程序不需要改动; (3)数据隔离性好; (1)系统升级不方便,需求所有数据库都执行一次表变更的sql。随着租户增加,运维的工作量会越来越多; (2)增加一个租户,需要创建一个新的数据库,增加运维的工作量; (3)增加一个租户时,要插入一些初始化数据,开发、运维之间,要维护一个初始化数据sql文件。生产中,经常会出现由于缺少部分初始化数据,导致新租户异常的情况; (4)运营做数据分析时,不方便;
独立数据库实例 (1)性能好,可以横向扩容。可以针对租户的性能需求,配置不同性能的数据库实例。例如,租户A的数据多,用户多,要求性能高,数据库实例的配置可以分配更多的内存、更高频率CPU;租户B的数据少,用户少,性能要求低,数据库实例的配置低一些没关系; (2)数据隔离性好; (1)系统升级不方便,需求所有数据库都执行一次表变更的sql。随着租户增加,运维的工作量会越来越多; (2)增加一个租户,需要创建一个新的数据库,增加运维的工作量; (3)增加一个租户时,要插入一些初始化数据,开发、运维之间,要维护一个初始化数据sql文件。生产中,经常会出现由于缺少部分初始化数据,导致新租户异常的情况; (4)运营做数据分析时,不方便;

四、生产环境实践

在公司的项目中,通过团队的讨论,最终决定使用数据库表通过租户ID字段来区分的方案。原因如下:

  1. 当时项目刚启动,人手不足,希望成本(服务器成本、运维成本)尽可能低;
  2. 系统对数据隔离性要求不高,同时预计的数据量不太;
  3. 后期数据库如果存在性能问题,可以改用tidb横向扩容;
  4. 产品要分析租户的数据(公司的运营管理后台),如果租户数据分到不同的数据库(或者数据库实例),数据统计分析会很不方便;

五、生产实践遇到的问题

  1. 公司采用通过表增加tenantId字段来做数据隔离,采用mybatis plus的TenantLineInnerInterceptor拦截器,在查询时,自动加上tenantId查询条件,在插入数据时,自动填上用户的tenantId。
  2. 存在一些表(例如一些配置参数表),所有租户都会用到,而且都一样的。这些表在系统迭代过程中,数据会不断增加。如果也加上tenantId(即每个租户一份数据),会导致运维工作增加。例如,每增加一个租户,都要copy一份这些数据;新插入一条数据,要查询系统所有租户ID,给每个租户都增加一条数据。如果忘记这个操作,会导致部分租户异常。这个可以通过重写mybatis plus的TenantLineInnerInterceptor拦截器的ignoreTable方法,忽略指定的表,解决这个问题。
  3. 肯定要有tenantId(才知道哪个用户是哪个租户下面的),登陆接口要查用户表,但此时不知道用户是哪个租户下面的,mybatis plus的TenantLineInnerInterceptor拦截器查询时,会自动增加tenantId查询条件,会导致查询不到这个客户。可以通过查询用户的mybatis接口的方法上,加上@InterceptorIgnore(tenantLine = "1")注解即可忽略TenantLineInnerInterceptor拦截器;
    InterceptorIgnore注解,请参考mybatis plus的官方文档

插件主体 | MyBatis-Plus​baomidou.com/pages/2976a3/#mybatis-config-xml

相关推荐
zt1985q4 分钟前
本地部署开源网络书签与内容管理工具 Karakeep 并实现外部访问
运维·服务器·网络·数据库·网络协议·开源
IvorySQL1 小时前
PostgreSQL 日报| PostgreSQL 19 默认 WAL 压缩算法(8 月 8 日)
数据库·postgresql·区块链
油丶酸萝卜别吃1 小时前
MySQL B+ 树查询全过程详解
数据库·mysql
leisoo80971 小时前
股票数据本地化存储实战:JSON、数据库与列式存储的方案对比
jvm·数据库·json
Exclusive_Cat2 小时前
MySQL回表机制解析与优化策略
数据库·sql
circuitsosk2 小时前
向量数据库选型与性能压测:Milvus、Pinecone、Chroma在真实业务下的对比
数据库·python·pinecone·milvus·向量数据库·chroma
影寂ldy2 小时前
SQL 索引(Index)完整笔记
数据库·笔记·sql
切糕师学AI2 小时前
从压缩到查询:PostgreSQL中JSON数据的存储与处理实践
数据库·postgresql·json
渣渣盟2 小时前
当 Redis 写入成为性能瓶颈时,如何利用 异步批量 Sink 将吞吐量从 1w QPS 提升到 10w+?
数据库·redis·php
SelectDB2 小时前
Apache Doris 2026 Roadmap:AI 成为主流负载后数据基础设施的演进方向
数据库