跟我上“云”端(二)多租户的数据隔离

多租户两种极端实现方式

  • 启用多租户的方法有很多,我不想做一一的介绍,但是有两个极端我们可以考虑一下:

    • 极端一:

      是所有租户共享单一应用程序实例,也就是相同的服务器、中间件和应用程序。实现的方法是用租户标识参数对应用程序的单一实例进行参数化。

      图1 在多个租户之间共享应用程序和中间件的单一实例

    • 极端二:

      是租户在单独的服务器上运行自己的应用程序实例(当前许多 Application Service Provider [ASP] 采用这种方法)。

      租户只共享数据中心的基础结构(比如供电和制冷),但是使用应用程序、中间件、操作系统和服务器的不同实例。在图 2所示的示例中,租户 A、B 和 C 使用三个不同的应用程序实例 AppA、AppB 和 AppC,它们在与租户相关的中间件实例、操作系统实例和物理服务器上运行。这种方法最适合那些要求为不同的租户提供充分隔离和定制的工作负载和场景

      图2 ASP 通过在多个单独的服务器上运行多个实例启用多租户

      其实我们经常在这样做,我们为某个A企业开发了一个OA办公系统,当另一个B企业也需要类似的系统时。我们往往在重新发布一个Application实例,供B企业使用,但我们的目的往往是为了简单方便,而不会去考虑为不同的租户提供充分隔离和定制的工作负载和场景。

    • 由于极端二对于我们实现上是没有任何问题的,即使是需要一些个性化的配置,由于是两套完全独立的Application,我就就可以随意的改动而不影响其他的企业。所以我们今天的重点是分析极端一的实现方式。极端一的方式中Application只发布一个实例,但可以为多个承租者提供服务。实现这种方式最关键的技术是仙子按多租户的数据隔离。

多租户数据层设计模式

  • 通过前面的分析我们知道传统的应用,仅仅服务于单个租户,数据库多部署在企业内部网络环境,对于数据拥有者来说,这些数据是自己“私有”的,它符合自己所定义的全部安全标准。而在云计算时代,随着应用本身被放到云端,导致数据层也经常被公开化,但租户对数据安全性的要求,并不因之下降。同时,多租户应用在租户数量增多的情况下,会比单租户应用面临更多的性能压力。那么多租户在数据层的框架如何在共享、安全与性能间进行取舍。

常见的三种模式

  1. 独立数据库
  2. 共享数据库、独立 Schema
  3. 共享数据库、共享 Schema、共享数据表
    • 独立数据库是一个租户独享一个数据库实例,它提供了最强的分离度,租户的数据彼此物理不可见,备份与恢复都很灵活;共享数据库、独立 Schema 将每个租户关联到同一个数据库的不同 Schema,租户间数据彼此逻辑不可见,上层应用程序的实现和独立数据库一样简单,但备份恢复稍显复杂; 最后一种模式则是租户数据在数据表级别实现共享,它提供了最低的成本,但引入了额外的编程复杂性(程序的数据访问需要用 tenantId 来区分不同租户),备份与恢复也更复杂。这三种模式的特点可以用一张图来概括:

      图 3. 三种部署模式的异同

    • 上图所总结的是一般性的结论,而在常规场景下需要综合考虑才能决定那种方式是合适的。例如,在占用成本上,认为独立数据库会高,共享模式较低。但如果考虑到大租户潜在的数据扩展需求,有时也许会有相反的成本耗用结论。
    • 而多租户采用的选择,主要是成本原因,对于多数场景而言,共享度越高,软硬件资源的利用效率更好,成本也更低。但同时也要解决好租户资源共享和隔离带来的安全与性能、扩展性等问题。毕竟,也有客户无法满意于将数据与其他租户放在共享资源中。
    • 目前市面上各类数据厂商在多租户的支持上,大抵都是遵循上文所述的这几类模式,或者混合了几种策略,具体的介绍,可以看下面这篇博客进行的详细的介绍:

      数据层的多租户浅谈

    • 在这篇文章中比较系统全面的介绍了hibernate和eclipselink对于多租户的具体的实现,文章的最后也有源码可以下载,经过简单的配置就能正常的运行。是学习多租户的很好的文章。

学习体会

  • 本来我不应该再对此做过多的解释了,但是我还是有一些自己的想法想给大家分享一下。

hibernate

  • 首先说hibernate的实现上,在文章中并没有给出独立数据库的实现方式,只是说这种模式可以通过实现 MultiTenantConnectionProvider 接口或继承 AbstractMultiTenantConnectionProvider 类等方式来实现。如果读者认真的分析了代码就会发现对于共享数据库,独立 Schema模式也是需要实现MultiTenantConnectionProvider接口的,其代码如下:
public class SchemaBasedMultiTenantConnectionProvider implements MultiTenantConnectionProvider, Stoppable,
        Configurable, ServiceRegistryAwareService {

    private final DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();

    //得到数据库连接
    @Override
    public Connection getAnyConnection() throws SQLException {
        return connectionProvider.getConnection();
    }
    //关闭数据库连接
    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        connectionProvider.closeConnection(connection);
    }

    //根据不同用户,Use对应用户的库的链接
    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        final Connection connection = getAnyConnection();
        try {
            connection.createStatement().execute("USE " + tenantIdentifier);//重点关注1
        } catch (SQLException e) {
            throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier
                    + "]", e);
        }
        return connection;//重点关注2
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        try {
            connection.createStatement().execute("USE main");
        } catch (SQLException e) {
            throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier
                    + "]", e);
        }
        connectionProvider.closeConnection(connection);
    }
    ……
}
  • 在重点关注1中其实就是使用当前的connection执行一下“use Schema名”,这样我们下面使用这个链接做的操作就会在新的Schema下操作了。
  • 再看重点关注2返回值是一个connection,如果是共享数据库独立schema使用的connection只需要有一个,但如果想实现独立数据库的隔离,其实只需要改变getConnection方法的实现,根据tenantdentifier的值生成不同的connection就能实现了。

多租户下的 Hibernate 缓存

  • 我们还应该注意文章中对于多租户下hibernate缓存的说明,为了让读者加深印象我这里也粘贴过来。
  • 基于独立 Schema 模式的多租户实现,其数据表无需额外的 tenant_id。通过 ConnectionProvider 来取得所需的 JDBC 连接,对其来说一级缓存(Session 级别的缓存)是安全的可用的,一级缓存对事物级别的数据进行缓存,一旦事物结束,缓存也即失效。但是该模式下的二级缓存是不安全的,因为多个 Schema 的数据库的主键可能会是同一个值,这样就使得 Hibernate 无法正常使用二级缓存来存放对象。例如:在 hotel_1 的 guest 表中有个 id 为 1 的数据,同时在 hotel_2 的 guest 表中也有一个 id 为 1 的数据。通常我会根据 id 来覆盖类的 hashCode() 方法,这样如果使用二级缓存,就无法区别 hotel_1 的 guest 和 hote_2 的 guest。
  • 在共享数据表的模式下的缓存, 可以同时使用 Hibernate的一级缓存和二级缓存, 因为在共享的数据表中,主键是唯一的,数据表中的每条记录属于对应的租户,在二级缓存中的对象也具有唯一性。Hibernate 分别为 EhCache、OSCache、SwarmCache 和 JBossCache 等缓存插件提供了内置的 CacheProvider 实现,读者可以根据需要选择合理的缓存,修改 Hibernate 配置文件设置并启用它,以提高多租户应用的性能。

eclipseLink

  • 对于eclipseLink,他完整实现了jpa标准,这也对我们实现企业级的应用提供了保障,在下一篇文章中我们也会针对于这一点展开详细的说明。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 07:44:03

跟我上“云”端(二)多租户的数据隔离的相关文章

跟我上“云”端(四)使用eclipselink构建企业级多租户应用

上一篇博客中我们介绍了多租户的数据隔离,文中具体的介绍了hibernate和eclipselink对于多租户的实现情况,博客的最后,我也对hibernate实现多租户的细节上做了解释,这次,我想带大家一起来使用eclipselink构建企业级的多租户项目. eclipselink的三种实现 由于eclipselink完整实现了jpa规范,我们就可以使用ejb构建一个企业级的多租户项目,首先eclipselink支持3中多租户的模式: - Single-Table Multi-tenancy,依靠

跟我上“云”端(一)认识多租户

什么是多租户,其优缺点是什么? 从软件的单个共享实例将软件交付给多个客户端组织(或承租者)的能力是 Web 交付解决方案的重要要求.例如,假设有一个由银行服务提供者作为服务提供的简单银行应用程序.本上下文中的多租户 是指从银行应用程序的单个共享实例向多个银行提供银行服务的能力.图 1 说明了从共享的应用程序服务器.数据库.操作系统和物理服务器向两个银行(北卡罗来纳州第一银行和加拿大第二银行)提供的多承租银行服务. 图 1. 使用共享中间件和硬件为银行业务构建的示例 Web 交付的多承租服务 上图

跟我上“云”端(三)eclipselink+jboss实现多租户基本配置

本文主要介绍,如何在jboss EAP6.2中使用eclipselink 开发工具:jboss EAP6.2+maven eclipselink版本:2.6.0 添加eclipselink的module 使用预包装的集成库,下载地址:(eclipselink+jobss EAP6.2集成module) 下载完成以后解压,并使用maven编译,解压后的文件: 查看其中的pom.xml文件: 其中properties结点中加入自己想使用的eclipselink版本,并修改 eclipselink.v

数据进入MaxCompute的N种方式,大数据实战Demo系统数据上云实践

摘要: 2018"MaxCompute开发者交流"钉钉群直播分享,由阿里云数据技术专家彬甫带来以"MaxCompute数据仓库数据转换实践"为题的演讲.本文首先介绍了MaxCompute的数据架构和流程,其次介绍了ETL算法中的三大算法,即更新插入算法.直接加载算法.全量历史表算法,再次介绍了在OLTP系统中怎样处理NULL值,最后对ETL相关知识进行了详细地介绍. 2018"MaxCompute开发者交流"钉钉群直播分享,由阿里云数据技术专家彬

saas系统多租户数据隔离的实现(一)数据隔离方案

0. 前言 前几天跟朋友聚会的时候,朋友说他们公司准备自己搞一套saas系统,以实现多个第三方平台的业务接入需求.聊完以后,实在手痒难耐,于是花了两天时间自己实现了两个saas系统多租户数据隔离实现方案.俗话说“独乐乐不如众乐乐”,所以我把我的“研究成果”写出来,让大家乐呵乐呵. 在分享我的研究成果之前,我们先了解一下相关的定义吧.如果对这部分内容熟悉的同学,可以直接略过. 1. 什么是saas系统 引用百度百科上面的描述, “SaaS平台是运营saas软件的平台.SaaS提供商为企业搭建信息化

EEPlat PaaS中的多租户数据隔离模式

EEPlat PaaS支持三种租户的数据隔离技术:Sparce Column.tenantId字段隔离.每个租户独立数据库. 1)Sparce Column,和Salesforce Appforce 类似,主要通过一个通用表来存放所有自定义信息,里面有租户字段和很多统一的数据栏位(比如500个).EEPlat PaaS平台通过租户分区的方式进行租户数据的查询优化. 和Appforce 不同的是,EEPlat PaaS平台产品提供了2层的元数据抽象,EEPlat PaaS平台产品中业务元数据和租户

云平台之多租户

云平台之多租户 在云领域我们常常会听到一个词:多租户.这个词在不同的语境中有着不同的含义.本文将介绍云平台中的多租户的概念以及实现多租户支持的思路. 什么是租户 刚開始接触这个概念时,你肯定感觉"租户"这个词怪怪的.但假设我们换个词,我相信你立即就有感觉了.这个词就是"客户"(这里的客户指的就是商业上面的客户). 一个租户就是一个客户,比方我们开发的服务是给 XXX 企业使用的,那该企业就是我们的一个客户/租户:假设这个服务是面向互联网的,那么使用该服务的每一个互联

《近匠》APICloud:“云”+“端”一体的移动API提供者

CSDN移动:请讲讲你们是谁?你们以往的从业经历? APICloud最开始只有两个创始人刘鑫和邹达,但是半年时间就发展成超过50人的互联网团队.APICloud的两个创始人性格迥异.CEO刘鑫是个典型的叛逆者,大学读到一半就辍学创业,后来又心血来潮的扑到北京重新开始,风风火火十多年见证了中国移动互联网从SP抢钱时代到智能机普及的完整历程.CTO邹达则是同事眼中的“Nice man”,极具个性的光头造型让人印象深刻,倒是这种“穷凶极恶”的硬汉形象配上“Nice man”的个性让人记忆犹新,在API

当红架构Cloud_Native_怎么搭建才能成为上云助攻手?

一.什么是Cloud Native? 说到Cloud Native,国内大多数都翻译成云原生,就是让云成为成功的基石,而不是障碍.陈谔对于为什么要实现云原生应用深有体会,网易从2012年开始实施云化的战略,当第一版云计算平台建好的时候,开始引导公司的项目逐渐向云迁移.这个过程中就遇到了一个问题:用上云之后,并没有变得效率奇高,甚至有些项目的效率反而有所下降,大家都有很多抱怨. 从那时陈谔就有一个想法,云计算怎样才能成为公司和开发团队成功的基石,而不是用上云之后给你制造麻烦.他认为要做到这一点首先