CYQ.Data 支持分佈式數據庫(主從備)高可用及負載調試

前言:

繼上一篇,介紹 CYQ.Data 在分佈式緩存上支持高可用,詳見:CYQ.Data 對於分佈式緩存Redis、MemCache高可用的改進及性能測試html

本篇介紹 CYQ.Data 在對數據庫層面對分佈式數據庫的主從備的高可用的及負載調度。git

目前框架支持的數據庫(及緩存)種類爲:github

Support:Txt、Xml、Access、Sqlite、Mssql、Mysql、Oracle、Sybase、Postgres、Redis、MemCache。算法

下面就開始介紹:sql

一、數據庫集羣與負載的高可用:

一、集羣與故障轉移

想當年,在北京聯通的項目上,爲了實現數據庫集羣故障轉移,那但是一堆人在機房折騰的死去活來。數據庫

還要開什麼研論會,要機房,網絡設計人員,和項目層面的三方人碼動手。json

折騰到最後的結果,浪費了一臺服務器作熱備。緩存

二、由客戶端調度主從備,實現故障轉移與負載。

CYQ.Data 在很早前,就實現了主從備的切換了,只是沒有實現高可用。服務器

這一次,迎合NET Core 在將來分佈式應用下的需求,補上了這個功能。網絡

二、CYQ.Data 在分佈式下的數據庫可高用:

下面來看簡單的使用過程:

一、指定配置外鏈:

原有的配置:

<connectionStrings>
<add name="Conn" connectionString="server=.;database=test;uid=sa;pwd=123456"/>
<add name="Conn_Bak" connectionString="server=.;database=test;uid=sa;pwd=123456"/>
<add name="Conn_Slave1" connectionString=".;database=test;uid=sa;pwd=123456"/>
<add name="Conn_Slave2" connectionString="server=.;database=demo;uid=sa;pwd=123456"/>
</connectionStrings>

將配置寫在原的config中,是當修改時,會引起(Window下)整個程序重啓(而NetCore默認不重啓,須要特殊處理配置文件從新加載事件)。

改進後配置(文件後綴能夠指定*.ini,*.txt, *.json):

<add name="Conn" value="conn.json"/>

對應的conn.json 文件:

{
  "Conn": {
        "Master": "server=.;database=demo;uid=sa;pwd=123456",
        "Backup": "server=.;database=test;uid=sa;pwd=123456",
        "Slave": [
              "server=.;database=test;uid=sa;pwd=123456",
              "server=.;database=demo;uid=sa;pwd=123456"
              ]
      }
}

將配置外置後,程序會自動監控文件的變化,每次修改都會即時生效,內部自動調整算法,實現高可用。

配置後好,剩下的問題就是你有多少臺服務器能夠安裝數據庫實例了。

二、數據庫主從備的機制說明:

主備:當主庫發生故障時,會自動切換到備庫。

主從:主庫負責寫,從庫負責讀。

三、關於讀的負載調度:

只要是被加入Slave的連接,都會順序被執行。

所以,若是寫的任務很少,能夠把主庫的連接也加入到Slave中,分擔讀的壓力。

再把備庫的連接都加載入到Slave中,反正備庫平時也用不上,同樣能夠繼續分擔讀的壓力。

另外,Slave因爲是順序調度,因此要加大某實例的負載時,能夠將該實例的連接複製多份,以提升被執行的機率。

所以,只要配合服務器性能監控,再動態修改連接指向的配置文件,便可實現高可用的性能負載。

下面來作一個測試實驗:

三、主從備負載切換的實驗:

 首先,建立了五個數據庫:MasterDB、BackupDB、SlaveDB一、SlaveDB二、SlaveDB2。

而後:數據庫間的同步,這一步就先省了。

寫測試代碼,運行兩個線程,分別是讀與寫:

 public class MasterBackupSlave
    {
        public static void Start()
        {
            AppConfig.Log.LogConn = "Conn";
            ThreadPool.QueueUserWorkItem(new WaitCallback(Read), "Read");
            ThreadPool.QueueUserWorkItem(new WaitCallback(Write), "Write");
            Console.Read();
        }
        private static void Read(object threadFlag)
        {
           
            while (true)
            {
                using (SysLogs logs = new SysLogs())
                {
                    logs.Fill(1);

                    Console.WriteLine("Read : " + ((MAction)logs).DataBase);
                }
                Thread.Sleep(1000);
            }
        }
        private static void Write(object threadFlag)
        {
            while (true)
            {
                using (SysLogs logs = new SysLogs())
                {
                    logs.Message = Guid.NewGuid().ToString();
                    logs.Insert();

                    Console.WriteLine("--------------Write : " + ((MAction)logs).DataBase);
                }
                Thread.Sleep(1000);
            }
        }
    }

而後運行,看到如下輸出,寫在主庫,讀在從庫中切換:

接着,咱們測試主備,把主庫弄掛了,這時會切到從,再把主庫恢復,這時候會切回來。

最後,咱們隨時減小或增長從庫負載的實例:

沒錯,和分佈式緩存同樣,框架已經從單機的應用,向分佈式高負載和高可用性進化了。

總結:

別問我爲何,總之,就是這麼強大。

相關文章
相關標籤/搜索