繼上一篇,介紹 CYQ.Data 在分散式緩存上支持高可用,詳見:CYQ.Data 對於分散式緩存Redis、MemCache高可用的改進及性能測試,本篇介紹 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); } } }
然後運行,看到以下輸出,寫在主庫,讀在從庫中切換:
接著,我們測試主備,把主庫弄掛了,這時會切到從,再把主庫恢復,這時候會切回來。
最後,我們隨時減少或增加從庫負載的實例:
沒錯,和分散式緩存一樣,框架已經從單機的應用,向分散式高負載和高可用性進化了。
總結:
別問我為什麼,總之,就是這麼強大。