【SaaS】多租户系统设计

news2024/11/13 10:27:16

文章目录

  • 多租户系统设计
  • 一、SaaS 的系统分级
  • 二、应用程序必须支持多租户
  • 三、数据隔离方案
    • 3.1、独立应用独立库
    • 3.2、同一个应用程序,每个租户一个库
    • 3.3、同一个应用程序,同一个数据库
    • 3.4、分片多租户
  • 四、我们的模型选择
    • 4.1、开发实践
    • 4.2、元数据/配置驱动
  • 参考

多租户系统设计

一、SaaS 的系统分级

SaaS 系统架构成熟度模型的 5 个级别——从“混乱”到“乌托邦“

  • 第 0 级(混乱):每次新增一个客户,都会新增软件的一个实例。

  • 第 1 级(受控的混乱):所有客户都运行在软件的同一个版本上,而且任何的定制化都通过修改配置来实现。

  • 第 2 级(多租户 [multi-tenant]、高层建筑 [Highrise]):所有的客户都已经可以在软件的同一个版本上运行了,而且他们都在同一个“实例”上运行。

  • 第 3 级(多租户, 扩建 [Build-Out]):此时你已经拥有了多租户、单一版本的软件模型。不过你还是可以通过硬件扩展(scale-out)的方式来进行扩充。

  • 第 4 级(乌托邦):如同第 3 级,除非你可以找出有效的方式,以在不同的“实例”上运行不同版本的软件。

在这里插入图片描述

二、应用程序必须支持多租户

多租户可以分为几个不同的类别:

  • 云中的简单虚拟化,其中只对硬件进行共享。

  • 共享应用程序,对每个租户使用不同的数据库。

  • 共享应用程序和数据库(效率最高,真正的多租户)。

三、数据隔离方案

我们要实现的也即效率最高的,真正的多租户业务模型。但选择是有个筛选的过程的,下面分别介绍下各种多租户的数据隔离方案。

3.1、独立应用独立库

有多个不同的应用,每个应用都有自己的数据库。这种方式虽然保证了租户数据的隔离,但无论是在扩展性和成本上都是最差的,故首先淘汰这种方式。

3.2、同一个应用程序,每个租户一个库

  • 优点是

    • 租户数据在数据库维护物理上隔离了,

    • 由于是每个租户一个库可以在库表设计上做单独扩展,但这也引起了应用程序的兼容问题

  • 缺点是

    • 数据库维护成本高,(举例:在相同数据结构的情况下,增加表中的列或索引,需要操作多个库)开发成本也高。

在这里插入图片描述

3.3、同一个应用程序,同一个数据库

  • 缺点:

    • 多租户数据库必然会牺牲租户隔离。多个租户的数据一起存储在一个数据库中。在开发过程中,确保查询不会暴露来自多个租户的数据。
  • 优点:

    • 是所有方案中成本最低的。

在这里插入图片描述

3.4、分片多租户

分片多租户即:多租户的单应用+支持多租户的单数据库(分片)

在这里插入图片描述

看起来是不是跟第一个图中:同一个应用程序,每个租户一个库模式差不多,只不过每个库多了几个租户数据?

其实是大不相同的。

首先,第一种模式中不同租户的库是可以分别扩展的,也就是结构可以不一样,但分片多租户的是同一种数据结构。

其次,分片模式的扩展性很强,它可以是一个分片一个租户,也可以是一个分片多个租户,具体要看具体的分片策略。

来看下分片模式下具体的指标情况:

指标分片多租户
可扩展性无限 1-1000000s
租户隔离性中等
每一个租户的数据库成本最低
性能监控和管理综合和单个(偏综合)
开发复杂度中等
运维复杂度从低到高,单租户的管理比较复杂

四、我们的模型选择

基于以上的分析,我们选择采用分片多租户的模型,因为这样可以获得无限的扩展能力,且对租户数据的隔离性也比较好。

这样的话数据库结构就是统一的,不同分片是同一库表结构。而具体分库规则是可以配置的,建议前期按照 一租户一库 的策略配置。

4.1、开发实践

  • 每一个表的设计都应该考虑是否要加入 “租户 ID”字段,用来区别不同“租户”,或者不同客户,另外,也方便后面用“租房 ID”作为 分片键

  • 我们将引入 ShardingSphere 帮我们做数据库的分库分表,对于应用来说是相对透明的,减少应用开发在数据库层面由于引入分库分表的复杂度。

  • 我们利用分片规则对数据进行分片,例如根据租户 ID,配置分库分表规则

# 配置分片规则
- !SHARDING
  tables:
    # 配置 t_order 表规则
    t_order: 
      actualDataNodes: ds${0..1}.t_order${0..1}
      # 配置分库策略
      databaseStrategy:
        standard:
          shardingColumn: user_id
          shardingAlgorithmName: database_inline
      # 配置分表策略
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: table_inline
    t_order_item: 
    # 省略配置 t_order_item 表规则。..
    # ...
    
  # 配置分片算法
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds${user_id % 2}
    table_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}

当数据库表结构有变更的时候(DDL),通过 ShardingProxy 进行代理修改,ShardingProxy 会按照分库分表规则进行多库表的自动修改。

4.2、元数据/配置驱动

一个好的 SaaS 解决方案应该是高效的多租户。可以使用每个租户的元数据来实现多租户。可以为每个特定组件定义元数据。它定义了运行时的应用程序数据、应用程序的基础功能,以及特定租户的数据和自定义(如果有的话)。

参考

  • https://linpxing.cn/cxy_saas_tenant_db_11/

  • http://www.uml.org.cn/yunjisuan/2021051944.asp?artid=23981

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue路由传参+案例(使用mock模拟后端数据)

路由传参 跳转路由时,可以给路由对应的组件内传参 声明式导航 /path?参数名值 /path/值 —需要路由对象提前配置 path: ‘/path/:参数名’ 对应的页面组件接收传递过来的值 $route.query.参数名 $route.params.参数名 router/index.js import Vue from vue // 1. …

解析matlab的audioread()输入输出参数

目录 一、API简介 二、实验 1. matlab 2. C语言 一、API简介 链接如下: 读取音频文件 - MATLAB audioread- MathWorks 中国 也可以浏览最新的英文版API说明: 简单说明如下: 1. 读取wav格式的文件,会自动跳过44个字节的文件…

初识React/JSX/组件/state/受控组件

JSX 推荐使用小括号包裹jsx 使用函数创建组件 使用类创建组件 抽离组件 事件绑定 事件对象 有状态和无状态组件/state 抽离事件处理程序 表单元素 受控组件 多表单优化 非受控组件(了解即可)

vhost-net-原理-初始化流程-数据传输流程-vhost-net后端

文章目录 1.vhost net2.vhost-net的初始化流程vhost net设置vhost dev设置vhost vring设置 3.数据收发流程分析3.1 数据发送3.2 数据接收 4ioventfd和irqfd的通知机制4.1ioeventfdqemu侧kvm侧总体效果 4.2irqfdqemu侧kvm侧总体效果 参考: 1.vhost net 传统的virtio…

ChatGPT Plugins内幕、源码及案例实战(一)

ChatGPT Plugins内幕、源码及案例实战 6.1 ChatGPT Plugins的工作原理 本节主要跟大家谈ChatGPT的插件(Plugins),这个内容非常重要。现在很多企业级的开发,一般都会基于ChatGPT 插件进行一些服务的封装,相当于开发了一个代理(Agent),把一些服务或者API封装在里面,然后…

eclipse编辑器汉化;eclipse安装中文插件

eclipse IDE默认是英文环境,使用起来略微不便,汉化还是很有必要的;下面记录一下安装中文插件的过程: 文章目录 一、 选择安装包地址二、 在eclipse安装中文插件2.1 在线安装2.2 手动下载安装包2.3 导入到eclipse 三、汉化插件介绍 一、 选择安…

实例005 可以拉伸的菜单界面

实例说明 如果管理程序功能菜单非常多,而用户只使用一些常用菜单,这时,可以将主菜单项下的不常用菜单隐藏起来。此种显示方式类似于对菜单进行拉伸。使用时,只需单击展开菜单,即可显示相应菜单功能。运行本例&#xf…

python matplotlib中colorbar的位置设置

colorbar单独设置一个轴对象,再对轴对象进行灵活设置 import numpy as np import matplotlib.pyplot as plt# 创建一个二维随机数组 data np.random.rand(10, 10)# 创建一个图形和一个子图 fig, ax plt.subplots()# 绘制热力图 heatmap ax.imshow(data, cmaphot…

在linux中快速安装Redis数据库

Redis中文网 点击该链接下载最5.0.4版本的Redis的压缩包 使用Xftp工具将Redis安装包上传到linux中 1.将压缩包解压到/opt目录下: tar -zxvf redis-5.0.4.tar.gz 2. 更新yun: sudo yum makecache fast 3.安装gcc: yum -y install gcc 4.安装完成通过输入 : gcc -v …

tiny tool - get_file_path_name_by_drop_file

文章目录 tiny tool - get_file_path_name_by_drop_file概述工程效果收获的知识点vs2022工程, 必须自己设置对话框可以接受文件的风格vs2022建立的工程, 默认是unicode编码, 设置剪贴板数据时, 必须要设置为unicode的格式, 否则剪切板中只有第一个字符工程主要实现END tiny too…

短信压力测试系统,支持自定义接口

短信压力测试系统,支持自定义接口 支持卡密充值,短信压力测试系统,解决一切骚扰电话,教程在压缩包里面 可多个服务器挂脚本分担压力,套了cdn导致无法正常执行脚本可以尝试添加白名单 这边建议使用MySQL方式 同服务器下直接配置…

MySQL生产环境高可用架构实战

分布式技术MongoDB 1. MySQL高可用集群介绍1.1 数据库主从架构与分库分表1.2 MySQL主从同步原理 2. 动手搭建MySQL主从集群2.1 基础环境搭建2.2 安装MySQL服务2.2.1 初始化MySQL2.2.2 启动mysql2.2.3 连接MySQL 2.3 搭建主从集群2.3.1 配置master主服务2.3.2 配置slave从服务主…

Radzen Blazor Studio 1.12 Crack

Radzen Blazor Studio 是一款桌面工具,使 开发人员 能够创建精美的商业 Blazor 应用程序。快速地。 开放技术栈 没有供应商锁定。生成的源代码是人类可读的,您可以使用免费工具构建它。 Radzen 由流行的开源技术 - ASP.NET Core、Blazor、Bootstrap 提供…

较少的分区也报错too many range table entries

问题现象 postgresql中update执行语句报错too many range table entries 源sql with t as (select id from LZLTAB where id8723 limit 100 ) update LZLTAB setSTATUS 00,FILE_ID null,DATE_UPDATED localtimestamp(0) where id in (select id from t)如果把update改写成…

碳排放预测模型 | Python实现基于机器学习的碳排放预测模型——数据清理和可视化

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于机器学习的碳排放预测模型——数据清理和可视化 研究内容 碳排放被认为是全球变暖的最主要原因之一。 该项目旨在提供各国碳排放未来趋势的概述以及未来十年的全球趋势预测…

三维空间刚体运动之旋转矩阵与变换矩阵

1. 旋转矩阵 1.1 点、向量和坐标系 点:点是空间中的基本元素,没有长度,没有体积; 向量:把两个点连接起来,就构成了向量,向量可以看成从某点指向另一点的一个箭头;只有当我们指定这…

threejs精灵和粒子系统

个人博客地址: https://cxx001.gitee.io 前面我们了解到了场景中的网格对象由几何体和材质组成,并且分别系统学习了它们。这节我们将学习一个特殊的网格对象-----粒子(精灵)。 了解粒子 一个粒子(新版叫精灵)是 一个二维平面(小方块) ,它总是面向摄像…

Linux--阅读文本指令:more、less

生成10000行数字并将其写入普通文件的指令&#xff1a; count0; while [ $count -le 10000 ]; do echo "hello bit ${count}"; let count; done > file.txt 直接cat < file.txt会刷屏的&#xff0c;故引入more 注&#xff1a;enter键控制下翻&#xff0c;q直…

拷贝对象,拷贝快乐:揭开JavaScript中拷贝的神奇面纱

文章目录 浅拷贝&#xff08;Shallow Copy&#xff09;1. 使用 Object.assign() 方法2. 使用展开运算符&#xff08;Spread Operator&#xff09;3. 使用数组的 slice() 或 concat() 方法 深拷贝&#xff08;Deep Copy&#xff09;1. 使用 JSON 对象的方法2. 使用递归方法自行实…

@validated的自定义注解校验编程式校验

自定义注解校验 前面的文章中&#xff0c;我们都是采用validate机制自带的条件注解来进行参数校验&#xff0c; 比如Min、NotNull…等等&#xff0c; 这些的确可以帮我们省去一部分的参数校验&#xff0c;可惜还有一部分的业务校验规则并不是如这般简单的&#xff0c; 比如前端…