搜索
您的当前位置:首页Mycat+druid+zk实现多租户

Mycat+druid+zk实现多租户

来源:世旅网

前言

Mycat的应用场景之一就是实现多租户,多租户应用,每个应用一个库,但应用程序只连接 Mycat,从而不改造程序本身,实现多租户化;接下来我们使用mycat,结合druid拦截sql添加注释头,利用zk修改mycat配置文件中的schema、dataNode节点等信息,来实现多租户。

三种实现方案

多租户在数据存储上存在三种主要的方案,分别是:

独立数据库

这种方案一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本也高。

优点:

为不同的租户提供独立的数据库,有助于简化数据模型的扩展设计,满足不同租户的独特需求;

如果出现故障,恢复数据比较简单。

缺点:

增大了数据库的安装数量,随之带来维护成本和购置成本的增加。

共享数据库,独立Schema

这是方案即多个或所有租户共享 Database,但是每个租户一个 Schema。

优点:

为安全性要求较高的租户提供了一定程度的逻辑数据隔离,并不是完全隔离;

每个数据库可以支持更多的租 户数量。

缺点:

如果出现故障,数据恢复比较困难,因为恢复数据库将牵扯到其他租户的数据;

如果需要跨租户统计数据,存在一定困难。

共享数据库,共享Schema,共享数据表

这种方案即租户共享同一个 Database、同一个 Schema,但在表中通过 TenantID 区分租户的数据。 这是共享程度最高、隔离级别最低的模式。

优点:

三种方案比较,第三种方案的维护和购置成本最低,允许每个数据库支持的租户数量最多。

缺点:

隔离级别最低,安全性最低,需要在设计开发时加大对安全的开发量;

数据备份和恢复最困难,需要逐表逐条备份和还原;

如果希望以最少的服务器为最多的租户提供服务,并且租户接受以牺牲隔离级别换取降低成本,这种方案最 适合。

如何选择

首先,mysql数据库中没有schema的概念,所以对于mysql用户来说,只有两种方案:独立数据库和共享数据库,共享数据表。

独立数据库可以做到各租户数据互不影响,所以我们选择的是独立数据库。

而对于上面的三种方案来说:

如果想有较好的隔离性,选择方案一或方案二,但是设计和实现的难度和成本较高。

如果想有较好的共享性,选择方案三或方案二,这时运行成本较低,并且同一运行成本下支持的用户较多。

如果租户数量较多,可以选择方案三或方案二,这样可以降低成本

如果想针对每一租户提供附加的服务,比如数据备份和恢复等,可以选择方案一,这样有更好的隔离性

 

独立数据库架构实现多租户

选用技术

mycat + druid + zk

实现方式

mycat实现分库,拦截带有注释头的sql流向不同的数据库;druid拦截初始sql,添加注释头;程序通过zk修改mycat的配置文件,比如添加新租户时,通过zk添加新的schema和datanode节点,然后同步到mycat的schema.xml文件。

注解

MyCat对自身不支持的Sql语句提供了一种解决方案——在要执行的SQL语句前添加额外的一段由注解SQL组织的代码,这样Sql就能正确执行,这段代码称之为“注解”。

注解的使用相当于对mycat不支持的sql语句做了一层透明代理转发,直接交给目标的数据节点进行sql语句执行,其中注解SQL用于确定最终执行SQL的schema或DB。

注解格式

/*!mycat:schema=[schemaName] */

schema.xml配置文件
 

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
   
   //每个租户对应一个schema节点
    <schema name="667078BnaL7HrFBqYVsLude4MNVd" checkSQLschema="false" sqlMaxLimit="100" dataNode="auth_667078_integral_dev"/>
    <schema name="111222BnaL7HrFBqYVsLude4MNVd" checkSQLschema="false" sqlMaxLimit="100" dataNode="auth_111222_integral_dev"/>
    <schema name="667098BnaL7HrFBqYVsLude4MNVd" checkSQLschema="false" sqlMaxLimit="100" dataNode="auth_667098_integral_dev"/>
    <schema name="667108BnaL7HrFBqYVsLude4MNVd" checkSQLschema="false" sqlMaxLimit="100" dataNode="auth_667108_integral_dev"/>
 
    //auth服务器中的四个库,是四个租户的数据库
    <dataNode name="auth_667078_integral_dev" dataHost="auth" database="667078_integral_dev"/>  
    <dataNode name="auth_111222_integral_dev" dataHost="auth" database="111222_integral_dev"/>
    <dataNode name="auth_667098_integral_dev" dataHost="auth" database="667098_integral_dev"/>
    <dataNode name="auth_667108_integral_dev" dataHost="auth" database="667108_integral_dev"/>
    
    <dataHost balance="0" maxCon="1000" minCon="10" name="auth" writeType="0" switchType="1" slaveThreshold="100" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM1" url="192.168.25.54:3306" password="XXX" user="XXX"/>
    </dataHost>
</mycat:schema>

server.xml

在server.xml配置文件的user用户配置节点,将所有的schema节点的name属性值配置在property属性中。

 <user name="root">
        <property name="password">123456</property>
        <property name="schemas">667108BnaL7HrFBqYVsLude4MNVd,667098BnaL7HrFBqYVsLude4MNVd,111222BnaL7HrFBqYVsLude4MNVd,667078BnaL7HrFBqYVsLude4MNVd</property>
</user>

说明

对SQL加注解的实现则交由druid的插件功能完成,通过自定义druid的Interceptor类,拦截要执行的sql语句加上对应注解,实现方式见下边的  2.2、过滤sql语句。这样就实现了数据库的多租户改造。下面分几个部分来说明。

前提说明

公司旗下,有权限项目和多个其他项目,权限项目实现了多租户的配置,其他项目如果接入多租户,只需要按步骤配置即可实现多租户。
 

因篇幅问题不能全部显示,请点此查看更多更全内容

Top