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


前言:

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

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

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

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

下面就開始介紹:

1、數據庫集群與負載的高可用:

1、集群與故障轉移

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

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

折騰到最后的結果,浪費了一台服務器做熱備。

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

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

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

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

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

1、指定配置外鏈:

原有的配置:

<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"
              ]
      }
}

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

配置后好,剩下的問題就是你有多少台服務器可以安裝數據庫實例了。

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

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

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

3、關於讀的負載調度:

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

因此,如果寫的任務不多,可以把主庫的鏈接也加入到Slave中,分擔讀的壓力。

再把備庫的鏈接都加載入到Slave中,反正備庫平時也用不上,一樣可以繼續分擔讀的壓力。

另外,Slave由於是順序調度,所以要加大某實例的負載時,可以將該實例的鏈接復制多份,以提高被執行的概率。

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

下面來做一個測試實驗:

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

 首先,創建了五個數據庫:MasterDB、BackupDB、SlaveDB1、SlaveDB2、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);
            }
        }
    }

然后運行,看到以下輸出,寫在主庫,讀在從庫中切換:

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

最后,我們隨時減少或增加從庫負載的實例:

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

總結:

別問我為什么,總之,就是這么強大。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM