主从模式,几乎大部分出名的数据库都支持的一种集群模式。
当Web站点的访问量上去之后,很多站点,选择读写分离,减轻主数据库的的压力。当然,一主多从也可以作用多个功能,比如备份。这里主要演示如何实现从数据库集群的读负载均衡
搭建一主三从的MSSQL集群
192.168.99.250 //主服务器
192.168.99.8 //从服务器(WIN-6S3JNU8C4TB)
192.168.99.10 //从服务器(WIN-HF1GQ5U288H)
192.168.99.11 //从服务器(WIN-EAPJ2QB5AGM)
![9ec81738be91116f61dd7c54f9c8f5ca.png](https://i-blog.csdnimg.cn/blog_migrate/bbd7e0f08d3cf0e1ecbb18d1ef05797f.png)
本地发布一般而言,我们只需要安装数据库引擎服务即可。复制服务需要另外安装,所以我们进行发布/订阅模式的话,需要安装复制组件
![7811837e1e7b2ad791697abcaa846fbe.png](https://i-blog.csdnimg.cn/blog_migrate/323fc904f278057556eb69a8b8ff0a68.png)
![5a07df881df4d32db7cdebdae053abb0.png](https://i-blog.csdnimg.cn/blog_migrate/5e7c2fd27c491293855b31b1b2987eb5.png)
192.168.99.250 主服务器发布数据同步,接三台从服务器订阅发布。
本地订阅同样本地订阅,也需要安装复制组件。
![41aff373774cfea8f32a89240d40240b.png](https://i-blog.csdnimg.cn/blog_migrate/77831047d79b68d4b1050cca781bb879.jpeg)
![36e7c8b99535ed9fa9a09b57c30b7f2b.png](https://i-blog.csdnimg.cn/blog_migrate/9af24e6e143e1df251b7a45c3194b50e.png)
![3c5658f0b4292bc36d73ea8fd1920dfd.png](https://i-blog.csdnimg.cn/blog_migrate/3ee7181472a3124e3cf91daef5a8a17e.png)
模拟写数据
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
using System.Text;
using System.Linq;
namespace Read
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("模拟大量读取");
var ef = new EFDbContext();
var i = 0;
while (i < 1000)
{
i++;
var user = ef.OAUser.OrderBy(n => Guid.NewGuid()).Take(1).FirstOrDefault();
Console.WriteLine($"读取用户{user.UserName}资料");
}
Console.WriteLine("读取完毕");
}
}
public class EFDbContext : DbContext
{
public EFDbContext()
{
base.ChangeTracker.AutoDetectChangesEnabled = false;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=192.168.99.120;Initial Catalog=oa;User Id=sa;Password=123;",
n => n.UseRowNumberForPaging());
}
/// <summary>
/// 用户表
/// </summary>
public DbSet<OAUser> OAUser { set; get; }
}
/// <summary>
/// 用户表
/// </summary>
[Table("OAUser")]
public class OAUser
{
/// <summary>
/// 主健
/// </summary>
[Key]
public int Id { set; get; }
/// <summary>
/// 用户账号
/// </summary>
[Required, MaxLength(15), MinLength(6)]
public string UserName { set; get; }
/// <summary>
/// 用户密码
/// </summary>
[Required, StringLength(64)]
public string PassWord { set; get; }
/// <summary>
/// 昵称
/// </summary>
[Required, StringLength(30)]
public string NickName { get; set; }
/// <summary>
/// 加密盐
/// </summary>
[Required, StringLength(20)]
public string Salt { set; get; }
/// <summary>
/// 是否冻结
/// </summary>
public bool IsFrozen { set; get; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { set; get; }
}
}
![eab847dc5ab5a56971273081d2df6fc3.png](https://i-blog.csdnimg.cn/blog_migrate/8ab7f931236359da8724ef7233119b03.png)
![5095bec1d34e8592da3305dc6b97d14f.png](https://i-blog.csdnimg.cn/blog_migrate/09c14a7311e8c10be93e4f710951c106.png)
经过多次测试发现,每次只在一台从服务器上面进行读取,纳闷,后来输出发现
Console.WriteLine(con.ClientConnectionId);
![09fd2766d89a587510275e9abaaecaec.png](https://i-blog.csdnimg.cn/blog_migrate/f3998279dd352c0b10251cbd71b8b9ee.jpeg)
连接ID一样,重新启动,刚连接ID会有变动,然后果另一个从服务器进行大量读取。
初步猜测,应该是连接池的搞的鬼,如果关闭连接,但是实际上,并没有关闭数据库连接,而是归还连接池。重新打开数据库,又重连接池分配一条连接。
目前不清楚连接池的分配规则,从结果来看,应该是每次都是分配了相同的程序池连接。
现在暂进不测了,下班走,改天,部署WEB结构,然后用压力测试测试,看看数据库读取是否均衡。