vlambda博客
学习文章列表

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

本期配套视频

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

(点击阅读原文,可看,如果没有,最晚下午可看)


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




单单多库操作还不够完美,所以这几天就把读写分离给加上了,你可能会好奇,多库不就是读写分离么?主库和从库相互不影响的操作,满足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:

 "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:

 "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:

 "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的博客,但是我们能查询出来么?


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


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