利用多租户模式演化成分库分表和读写分离

前言

最近两周我都发了随笔写关于利用EF core实现多租户,并且给出了一些关于EF 自动迁移的内容。

这个系列的随笔是想要把这部分的代码优化和做成类库的。

我已经整理和抽象好了,本来想介绍一下整理的思路的。但后来发现这里的代码量太少了,好像没什么可以说的。

所以这篇随笔会讲解利用这个类库可以实现的功能。

 

多租户介绍

按照系列的随笔介绍,现在主要支持3种模式。分别是: 按表、按Schema和按数据库分离数据。

支持的数据库有MySql和SqlServer,并且在我重构的时候,把Postgre也集成进去了。

通过这次的代码重构,代码的结构已经不像前面的文章一样,停留在Demo层面。

代码修改后,我的目标是同时支持最基本的多租户,多租户演变成读写分离。

典型的模式

1. 按数据库分离的模式,可以看到一个DbContext会同时连接3个不同的数据库,每个库里面都有一个Product表.

 

 2. 按表分离的模式,这里可以看到一个DbContext只会同时连接一个数据库,数据库里面有3个结构相同的Product表,但是它们的名称是根据前缀区分的。

 

 3. 按Schema分离的模式,这里是一个DbContext只会同时连接一个数据库,数据库里面有3个Schema,3个Schema同时具有Product表

 

 

在多租户的场景下的变型

通过通过数据库的结构,我们能知道,数据库、Schema和表是有层级关系的。一个数据库有n个Schema,一个Schema有n个表。

通过这个层级特性,我们是可以把他变型成4种模式:数据库和表混合模式、数据库和Schema混合模式、Schema和表混合模式、数据库和Schema和表混合模式

但一般来说,后面2中模式把更加多的压力都同时在一个数据库,并没有从硬件/数据库实例方面进行分离,数据量继续增长的情况下,最终还是需要通过多个数据库分离数据。

 

1. 数据库和表混合模式,可以看到DbContext里面有3个连接分别连接到3个Store Container的数据库,里面各自存在3个结构相同的数据表。

通过3个Store container,共有9个租户

 

 

2. 数据库和Schema混合模式,一个DbContext里面有3个连接连接到3个Store Container的数据库,里面各自有3个Schema,每个Schema下都有一个结构相同的数据表

通过3个Store Container, 共有9个租户

 

 

转变为读写分离

在目前的系统中,读写分离是的应用更加广泛。通过下面的图看出,同一个DbContext下有3个连接分别链接到不同的数据库。数据库里见面有完全相同的表

其中一个是主库,2个是从库。

如果对比我们典型的多租户模式,其实是非常类型的,显而易见他们之间是可以互相演变的。事实上我项目中其实就是通过多租户模式下演变成读写分离的。

 

读写分离&多租户图解

我们这里先看看下图中的结构。其实这里的图就是我整个系列的主要流程。其中有几个关键步骤

A. Http Request通过asp.net core的中间件或者拦截器。通过AOP的模式,通过http header和url等, 调用Tenant Generator。

B. Tenant Generator根据调用的接口参数,获取这是哪一个租户和API的操作类型(读或写),并且讲租户信息和操作类型返回

C. Connection Resolver接收租户和操作信息的组合,通过配置文件或配置中心获取具体的连接字符串,并且把连接字符串作为参数传入到DbContext的构造函数。

D. Db Context利用接收到连接字符串,通过EF core的封装,自动连接到不同的数据库。

注:租户和操作信息的组合,拿store1 & read的组合举个例子,他的配置的连接字符串的键值是 store_read。同理 store2 & write 的键值就是store2_write

 

 通过上图的结构,其实读写分离在我们的封装下,也是能轻而易举的实现的。估计读者来到这里会发现有3个关键组件是需要用户自定义才能完成。

分别是中间件或拦截器、Tenant Generator和Connection Resolver。他们3者需要同时维护和使用一个TenantInfo。

 

总结

好了,来到这里已经是本文的结束。是的,本文并没有贴出任何代码,仅仅是一个介绍的随笔。

本文的目的是,让阅读者对多租户和读写分离模式有抽象的概念,利用图和抽象对象尽量描述出这个模式实现下的关键是什么。

从系列的第一篇开始,是对多租户的入门,之后的随笔是对该模式的深入理解和加深实施办法。

经过了前面几篇文章的基础,通过本文的抽象概念和之前的实施代码进行融合,从而希望读者能够系统地了解到分库分表。

 

关于代码

由于之前的代码都只停留在Demo阶段,所以后来我重构了,并且使用了新的Github Repository.

并且我把如何使用的示例代码都放在了同一个Repository下。

请到这个github地址下获取重构的代码:

https://github.com/woailibain/kiwiho.EFcore.MultiTenant

对于这份代码,由于我也是在最近2天写的,只做了基础功能测试,并且事例代码量有限,我会随着系列文章的进行中,不断补充事例代码也同时修复bug。

其中事例代码,我会包含今天讲到的所有内容。并且我在编写example的同时,也会发文写关于怎么使用,为什么这样使用的详细。

 

往期文章

如果读者是首次阅读本系列,建议阅读系列的其他文章。因为本文是对前文的总结

Asp.net core下利用EF core实现从数据实现多租户(1)

Asp.net core下利用EF core实现从数据实现多租户(2) : 按表分离

EF core (code first) 通过自定义 Migration History 实现多租户使用同一数据库时更新数据库结构

EF core (code first) 通过自动迁移实现多租户数据分离 :按Schema分离数据

 

posted @ 2020-03-01 22:42  woailibian  阅读(2538)  评论(3编辑  收藏  举报