【项目升级】单库、多库、读写分离 · 任你选

2022-04-11 14:12:32 浏览数 (1)

本期配套视频:

https://www.bilibili.com/video/BV1BJ411B7mn?p=6

继上周增加【任务调度】以后,继续对项目进行2.0版本升级,其实改动的地方并不多,主要的功能上,更丰富了,之前其实项目已经实现了多库的更新:

多库操作2:终于实现多个数据库操作

单单多库操作还不够完美,所以这几天就把读写分离给加上了,你可能会好奇,多库不就是读写分离么?主库和从库相互不影响的操作,满足xxxx的需求等等,其实不是的,至少在我这里两者不是一回事,下面我就简单的文字说一下,如果读不懂,或者不想读,可以直接看视频。

Github:相关代码目前在Is4分支。

1、多库操作与读写分离

单库模式就不说了,我们所有的项目都必须至少要支持这个,不然如何持久化?

多库操作,我理解的是,可以任意操作指定的任意数据库,只要允许访问,我们配置好连接字符串,并做一定的处理后,就可以CURD了,我这里可以简化称之为——C和Q,也就是命令和查询模式,命令就是指的写入、编辑、删除的操作。这里多个数据库是平等的,举个例子,我们可以在资源服务器Blog.Core中,来操作认证中心的role角色表,不仅可以读取,如果有必要,还可以修改,当然,这里业务上是不允许修改的。

读写分离,顾名思义,就是读(Q)和写(C)的动作是分开的,虽然也是多个数据库,虽然也是分主库和从库,但是读只能读取从库,写只能写在主库,这就是和普通的多库操作最大的也是最本质的不同之处。

简单解释过后,那我就说一下,Blog.Core项目中,如果实现单库模式、多库模式以及读写分离模式。

2、单库操作模式

这个很简单,当你第一次下载的时候,默认的就是单库模式:

MutiDBEnabled和CQRSEnabled都为false,所以如果你就只想连接一个数据库,那就把MainDB配置成下边对应的ConnId,然后把他对应Enabled设置为true就行了,其他的不用管,其他的就算设置为true,也不会影响。

举个例子,我只想配置一个SqlServer,连接字符串为xxxxxx:

代码语言:javascript复制
  "MainDB": "WMBLOG_MSSQL_1", //当前项目的主库,所对应的连接字符串的Enabled必须为true
  "MutiDBEnabled": false, //是否开启多库模式
  "CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
  "DBS": [
    {
      "ConnId": "WMBLOG_SQLITE",
      "DBType": 2,
      "Enabled": false,
      "HitRate": 50, // 值越大,优先级越高
      "Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
    },
    // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    {
      "ConnId": "WMBLOG_MSSQL_1",
      "DBType": 1,
      "Enabled": true,
      "HitRate": 40,
      "Connection": "xxxxxx",
      "ProviderName": "System.Data.SqlClient"
    },
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    {
      "ConnId": "WMBLOG_MSSQL_2",
      "DBType": 1,
      "Enabled": true,
      "HitRate": 30,
      "Connection": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQ",
      "ProviderName": "System.Data.SqlClient"
    },
    {
      "ConnId": "WMBLOG_MYSQL",
      "DBType": 0,
      "Enabled": false,
      "HitRate": 20,
      "Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
    },
    {
      "ConnId": "WMBLOG_ORACLE",
      "DBType": 3,
      "Enabled": false,
      "HitRate": 10,
      "Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
      "OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
    }
  ],

就是这么简单,那下边简单说一下,如何配置多库。

3、多库操作模式

这个可能稍微麻烦一丢丢,我就直接写步骤了:

1、配置MainDB —— 主库Id;

2、配置MutiDBEnabled —— true,开启多库模式;

3、配置DBS —— 将需要用到的数据库节点,Enabled=true;

4、在指定的实体类上边增加特性,指定对应的从库的连接Id;

举例说明,我想配置一个多库操作,主库是Sqlite,从库是Sqlserver:

代码语言:javascript复制
  "MainDB": "WMBLOG_SQLITE", //当前项目的主库,所对应的连接字符串的Enabled必须为true
  "MutiDBEnabled": true, //是否开启多库模式
  "CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
  "DBS": [
    // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    {
      "ConnId": "WMBLOG_SQLITE",
      "DBType": 2,
      "Enabled": true,// 主库
      "HitRate": 50, // 值越大,优先级越高
      "Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
    },
    {
      "ConnId": "WMBLOG_MSSQL_1",
      "DBType": 1,
      "Enabled": true,// 从库
      "HitRate": 40,
      "Connection": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
      "ProviderName": "System.Data.SqlClient"
    },
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    {
      "ConnId": "WMBLOG_MYSQL",
      "DBType": 0,
      "Enabled": false,// 不开启
      "HitRate": 20,
      "Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
    },
    {
      "ConnId": "WMBLOG_ORACLE",
      "DBType": 3,
      "Enabled": false,// 不开启
      "HitRate": 10,
      "Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
      "OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
    }
  ],

这样配置好后,我们的主库就是WMBLOG_SQLITE,一个从库是WMBLOG_MSSQL_1

然后配置下对应的实体类特性,指定这个表是从库的表:

然后我们可以看看,系统启动后,是怎么样的:

从启动日志上,我们可以看出来,已经实现了我们的目的。

4、读写分离模式

这个读写分离模式,其实和多库模式差不多,只不过更简单了:

1、配置MainDB —— 主库Id;

2、配置CQRSEnabled —— true,开启读写分离模式,必须是单库

3、配置DBS —— 将需要用到的数据库节点,Enabled=true;

举个例子,我想开启主库为WMBLOG_MSSQL_1,从库为WMBLOG_MSSQL_2:

代码语言:javascript复制
  "MainDB": "WMBLOG_MSSQL_1", //当前项目的主库,所对应的连接字符串的Enabled必须为true
  "MutiDBEnabled": false, //是否开启多库模式
  "CQRSEnabled": true, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
  "DBS": [
   {
      "ConnId": "WMBLOG_SQLITE",
      "DBType": 2,
      "Enabled": false,
      "HitRate": 50, // 值越大,优先级越高
      "Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
    },
    // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    {
      "ConnId": "WMBLOG_MSSQL_1",
      "DBType": 1,
      "Enabled": true,
      "HitRate": 40,
      "Connection": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
      "ProviderName": "System.Data.SqlClient"
    },
    {
      "ConnId": "WMBLOG_MSSQL_2",
      "DBType": 1,
      "Enabled": true,
      "HitRate": 30,
      "Connection": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
      "ProviderName": "System.Data.SqlClient"
    },
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    {
      "ConnId": "WMBLOG_MYSQL",
      "DBType": 0,
      "Enabled": false,
      "HitRate": 20,
      "Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
    },
    {
      "ConnId": "WMBLOG_ORACLE",
      "DBType": 3,
      "Enabled": false,
      "HitRate": 10,
      "Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
      "OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
    }
  ],

这里要注意一下:

1、开启读写分离模式的话,就必须要是单库模式,把MutiDBEnabled关掉,其实不关也行,只不过后期你可能会绕不过来,干脆禁掉。

2、不用再配置实体类了。

我们来看看系统启动日志:

目前是按照完美的设想进行的,那到底数据是不是成功呢,我们做下测试。

我们执行博客数据查询,总数是41条,这是读操作,走的是从库

然后,我们添加一条数据,这是写命令,走的是主库

可以看到,我们新建了一个Id是54的博客,但是我们能查询出来么?

答案是否定的,因为我们的查询是从库,这也就是证明了我们的读写分离已经生效了。

好啦,今天的内容暂时就写到这里吧,详细的说明和操作都在视频里,感兴趣的可以去看看。

0 人点赞