国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - Discuz!NT數據庫讀寫分離方案詳解

Discuz!NT數據庫讀寫分離方案詳解

2019-09-06 13:14腳本之家 ASP.NET教程

Discuz!NT這個產品在其企業版中提供了對‘讀寫分離’機制的支持,使對CPU及內存消耗嚴重的操作(CUD)被 分離到一臺或幾臺性能很高的機器上,而將頻繁讀取的操作(select)放到幾臺配置較低的機器上,然后通過‘事務 發布訂閱機制’

目前在Discuz!NT這個產品中,數據庫作為數據持久化工具,必定在并發訪問頻繁且負載壓力較大的情況下成 為系統性能的‘瓶頸'。即使使用本地緩存等方式來解決頻繁訪問數據庫的問題,但仍舊會有大量的并發請求要訪問動態數據,雖然 SQL2005及2008以上版本中性能不斷提升,查詢計劃和存儲過程運行得越來越高效,但最終還是 要面臨‘瓶頸'這一問 題。當然這也是許多大型網站不斷研究探索各式各樣的方案來有效降低數據訪問負荷的原 因, 其中的‘讀寫分離'方案就是一種被廣泛采用的方案。
      Discuz!NT這個產品在其企業版中提供了對‘讀寫分離'機制的支持,使對CPU及內存消耗嚴重的操作(CUD)被 分離到一臺或幾臺性能很高的機器上,而將頻繁讀取的操作(select)放到幾臺配置較低的機器上,然后通過‘事務 發布訂閱機制',實現了在多個sqlserver數據庫之間快速高效同步數據,從而達到了將‘讀寫請求'按實際負載 情況進行均衡分布的效果。

      下面就簡要介紹一下其實現思路。注:有關數據同步的工具已在sqlserver中自帶了,可以參考這篇文章

      將相應的數據由Master(主)數據庫中‘發布'出來,然后使用推送的方式(注:事務發布可以指定是‘通過主 數據庫推送' 還是‘訂閱服務器去獲取')發送到訂閱它的數據庫中,就實現了數據同步功能。

      下面就介紹一下如何通過改變既有代碼來實現在‘幾個從數據庫(類似快照)'間進行讀取數據的負載均衡。

      原有的代碼中因為使用了分層機制,所以我們只要在‘數據訪問層'動一下心思就可以了。在這里我的一個設 計思路就是不改變已有的數據庫訪問接口(包括參數等)的前提下,實現底層自動將現有的數據訪問操作進行負載 均衡。這樣做的好處不用多說了,同時也讓這個負載均衡功能與數據訪問層相分離,不要耦合的太緊密,同時如果不曉得底層 的實現原理也可以只通過一個開關(后面會介紹),就可以讓自己的sql語句自動實現動態負載均衡。

      說到這里,我來對照代碼進一步闡述:

      首先就是(Discuz.Data\DbHelper.cs)代碼,主要變動如下(新增方法部分):   

復制代碼代碼如下:


/// <summary> 
/// 獲取使用的數據庫(或快照)鏈接串 
/// </summary> 
/// <param name="commandText">存儲過程名或都SQL命令文本</param> 
/// <returns></returns> 
public static string GetRealConnectionString(string commandText) 

if (DbSnapConfigs.GetConfig() != null && DbSnapConfigs.GetConfig().AppDbSnap) 

commandText = commandText.Trim().ToLower(); 
if (commandText.StartsWith("select") || ((commandText.StartsWith(BaseConfigs.GetTablePrefix) && UserSnapDatabase(commandText)))) 

DbSnapInfo dbSnapInfo = GetLoadBalanceScheduling.GetConnectDbSnap(); 
if (DbSnapConfigs.GetConfig().RecordeLog && snapLogList.Capacity > snapLogList.Count) 
snapLogList.Add(string.Format("{{'SouceID' : {0}, 'DbconnectString' : '{1}', 'CommandText' : '{2}', 'PostDateTime' : '{3}'}},", 
dbSnapInfo.SouceID, 
dbSnapInfo.DbconnectString, 
commandText.Replace("'",""), 
Discuz.Common.Utils.GetDateTime())); 
return dbSnapInfo.DbconnectString; 


return ConnectionString; 


上面的方法將會對傳入的sql語句進行分析,找出其中是CUD操作還是SELECT操作,來區別是讀還是寫操作。而snapLogList列表則是之前所配置的‘事務發布訂閱'模式下的相關‘從數據庫'(Slave Database)鏈接串的列表,例如(dbsnap.config文件的DbSnapInfoList節點): 

復制代碼代碼如下:


<?xml version="1.0"?> 
<DbSnapAppConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<AppDbSnap>true</AppDbSnap> 
<WriteWaitTime>1</WriteWaitTime> 
<LoadBalanceScheduling>RoundRobinScheduling</LoadBalanceScheduling> --WeightedRoundRobinScheduling 
<RecordeLog>false</RecordeLog> 
<DbSnapInfoList> 
<DbSnapInfo> 
<SouceID>1</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ\DNT_DAIZHJ;User ID=sa;Password=123123;Initial Catalog=dnt_snap;Pooling=true</DbconnectString> 
<Weight>4</Weight> 
</DbSnapInfo> 
<DbSnapInfo> 
<SouceID>2</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ-PC\2222;User ID=sa;Password=123;Initial Catalog=tabletest;Pooling=true</DbconnectString> 
<Weight>3</Weight> 
</DbSnapInfo> 
</DbSnapInfoList> 
</DbSnapAppConfig> 


有關相應配置節點和負載均衡算法會在后面提到,這里為了保持文章內容的連續性暫且跳過,下面接著瀏覽一下上面調用的‘UserSnapDatabase'方法: 

復制代碼代碼如下:


/// <summary> 
/// 是否使用快照數據庫 
/// </summary> 
/// <param name="commandText">查詢</param> 
/// <returns></returns> 
private static bool UserSnapDatabase(string commandText) 

// 如果上次刷新cookie間隔小于5分鐘, 則不刷新數據庫最后活動時間 
if (commandText.StartsWith(BaseConfigs.GetTablePrefix + "create")) 

Utils.WriteCookie("JumpAfterWrite", Environment.TickCount.ToString()); 
return false; 

else if (!String.IsNullOrEmpty(Utils.GetCookie("JumpAfterWrite")) && (Environment.TickCount - TypeConverter.StrToInt(Utils.GetCookie("JumpAfterWrite"), Environment.TickCount)) < DbSnapConfigs.GetConfig().WriteWaitTime * 1000) 
return false; 
else if (!commandText.StartsWith(BaseConfigs.GetTablePrefix + "get")) 
return false; 
return true; 


該方法的作用很簡單,就是當數據庫有CUD操作時,通過寫cookie的方式向客戶端寫一個鍵值‘JumpAfterWrite',這個鍵值很重要,就是提供一個標簽(flag)來指示:‘當前用戶執行cud操作時,頁面跳轉到其它頁面而主數據庫還沒來得及將數據推送到從數據庫'這一情況而造成的‘數據不同步'問題。 
舉了例子,當在一個版塊中‘發表主題'后系統自動跳轉到‘顯示該主題頁面'時,如果主數據庫中插入了一個新主題而從數據庫沒有被及時更新這一主題信息時,就會報‘主題不存在'這個錯誤。所以這里加了一個設置,就是下面這一行: 

復制代碼代碼如下:


(Environment.TickCount - TypeConverter.StrToInt(Utils.GetCookie("JumpAfterWrite"), Environment.TickCount)) < DbSnapConfigs.GetConfig().WriteWaitTime * 1000) 


它所做的就是確保用戶cud操作之后,在規定的時間內還是訪問主數據庫,當時間超過時,才將當前用戶的訪問請求(select)均衡到其它從數據庫中。 
當然,在GetRealConnectionString()方法中,還有一行代碼很重要,就是下面這一行: 

復制代碼代碼如下:


DbSnapInfo dbSnapInfo = GetLoadBalanceScheduling.GetConnectDbSnap(); 



它的作用就是加載配置文件信息,其中最主要的就是相應的‘負載均衡算法實例'來獲取相應的從數據庫鏈接串,下面先看一 
下‘靜態屬性'GetLoadBalanceScheduling的相關信息: 

代碼 

復制代碼代碼如下:


/// <summary> 
/// 負載均衡調度接口 
/// </summary> 
private static ILoadBalanceScheduling m_loadBalanceSche; 
/// <summary> 
/// 初始化負載均衡調度接口實例 
/// </summary> 
private static ILoadBalanceScheduling GetLoadBalanceScheduling 

get 

if (m_loadBalanceSche == null) 

try 

m_loadBalanceSche = (ILoadBalanceScheduling)Activator.CreateInstance(Type.GetType(string.Format("Discuz.EntLib.{0}, Discuz.EntLib", DbSnapConfigs.GetConfig().LoadBalanceScheduling), false, true)); 

catch 

throw new Exception("請檢查config/dbsnap.config中配置是否正確"); 


return m_loadBalanceSche; 


它主要是通過反射的方法將Discuz.EntLib.dll文件中的相應負載均衡算法實例進行綁定,然后以m_loadBalanceSche這個靜態變量進行保存,而m_loadBalanceSche本身就是ILoadBalanceScheduling接口變量,該接口即是相應負載均衡算法的實現接口。同樣因為文章內容的連續性,這里先不深挖相應的實現算法,我會在后面進行介紹。下面再來看一下GetRealConnectionString()中還有一段代碼,如下: 
代碼 

復制代碼代碼如下:


if (DbSnapConfigs.GetConfig().RecordeLog && snapLogList.Capacity > snapLogList.Count) 
snapLogList.Add(string.Format("{{'SouceID' : {0}, 'DbconnectString' : '{1}', 'CommandText' : '{2}', 'PostDateTime' : '{3}'}},", 
dbSnapInfo.SouceID, 
dbSnapInfo.DbconnectString, 
commandText.Replace("'",""), 
Discuz.Common.Utils.GetDateTime())); 
return dbSnapInfo.DbconnectString; 


上面代碼將當前的負載均衡得到的鏈接串保存到一個snapLogList列表中,該列表聲明如下: 

復制代碼代碼如下:


List<string> snapLogList = new List<string>(400) 


為什么要提供這個列表并進行記錄?主要是為了考查負載均衡算法的工作情況,因為在數據訪問層獲取相應鏈接串信息并進行記錄很不方便,所以我用這個變量記錄大約400條‘負載均衡'數據鏈接串,以便在相應的Discuz.EntLib.ToolKit工具包中進行觀察,監視其‘工作情況'。這里我們只要知道通過GetRealConnectionString()方法就實現了對sql語句或存儲過程進行分析并進行負載均衡的效果了(注:該操作可能會耗時,所以在DbSnapConfigs中提供了一個開關‘RecordeLog'來進行控制,后面會介紹)。 

下面再來簡單介紹一下,如何改造DbHelper.cs中原有方法,使其支持負載均衡功能。這里強調一點,就是: 
GetRealConnectionString()方法只是造了一個房子,里面的家具還是要自己搬。 
而家具就是那些老的方法,比如: 

代碼 

復制代碼代碼如下:


public static object ExecuteScalar(DbConnection connection, CommandType commandType, string commandText, params DbParameter[] commandParameters) 

if (connection == null) throw new ArgumentNullException("connection"); 
//connection.Close(); 
connection.ConnectionString = GetRealConnectionString(commandText);//負載均衡改造完成的方法 
connection.Open(); 
// 創建DbCommand命令,并進行預處理 
DbCommand cmd = Factory.CreateCommand(); 
bool mustCloseConnection = false; 
PrepareCommand(cmd, connection, (DbTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection); 
// 執行DbCommand命令,并返回結果. 
object retval = cmd.ExecuteScalar(); 
// 清除參數,以便再次使用. 
cmd.Parameters.Clear(); 
if (mustCloseConnection) 
connection.Close(); 
return retval; 


上面的 ‘connection.ConnectionString ='之前綁定的ConnectionString這個靜態屬性,而這個屬性鏈接的就是‘主數據庫', 
這里我們只要將GetRealConnectionString(commandText)賦值給它就可以了,還是那句話,在GetRealConnectionString()就實現了 
數據庫鏈接串的負載均衡,呵呵。類似上面的變動在DbHelper.cs還有幾處,好在變化不太大,當然更不需要改變原有的數據訪問層 
(比如IDataProvider.cs文件)了。 
其實本文中介紹的數據庫層負載均衡實現方法在MYSQL中早有相應的插件實現了,參見這篇文章。      
Discuz!NT數據庫讀寫分離方案詳解
該文章中的LUA腳本實現方式與本文類似,如下: 
--發送所有的非事務性SELECT到一個從數據庫 

復制代碼代碼如下:


if is_in_transaction == 0 and packet:byte() == proxy.COM_QUERY and packet:sub(2, 7) == "SELECT" then 
local max_conns = -1 
local max_conns_ndx = 0 
for i = 1, #proxy.servers do 
local s = proxy.servers[i] 
-- 選擇一個擁有空閑連接的從數據庫 
if s.type == proxy.BACKEND_TYPE_RO and s.idling_connections > 0 then 
if max_conns == -1 or s.connected_clients < max_conns then 
max_conns = s.connected_clients 
max_conns_ndx = i 
end 
end 
end 
..... 


接著,我再介紹一下相應的配置文件和負載均衡算法的實現情況:) 
配置文件(比如:Discuz.EntLib.ToolKit\config\dbsnap.config): 
代碼 

復制代碼代碼如下:


<?xml version="1.0"?> 
<DbSnapAppConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<AppDbSnap>true</AppDbSnap> 
<WriteWaitTime>1</WriteWaitTime> 
<LoadBalanceScheduling>RoundRobinScheduling</LoadBalanceScheduling> --WeightedRoundRobinScheduling 
<RecordeLog>false</RecordeLog> 
<DbSnapInfoList> 
<DbSnapInfo> 
<SouceID>1</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ\DNT_DAIZHJ;User ID=sa;Password=123123;Initial Catalog=dnt_snap;Pooling=true</DbconnectString> 
<Weight>4</Weight> 
</DbSnapInfo> 
<DbSnapInfo> 
<SouceID>2</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ-PC\2222;User ID=sa;Password=123;Initial Catalog=tabletest;Pooling=true</DbconnectString> 
<Weight>3</Weight> 
</DbSnapInfo> 
<DbSnapInfo> 
<SouceID>3</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ-PC\333333;User ID=sa;Password=123;Initial Catalog=tabletest;Pooling=true</DbconnectString> 
<Weight>2</Weight> 
</DbSnapInfo> 
<DbSnapInfo> 
<SouceID>4</SouceID> 
<Enable>true</Enable> 
<DbconnectString>Data Source=DAIZHJ-PC\44444444;User ID=sa;Password=123;Initial Catalog=tabletest;Pooling=true</DbconnectString> 
<Weight>2</Weight> 
</DbSnapInfo> 
</DbSnapInfoList> 
</DbSnapAppConfig> 


上面的DbSnapInfoList就是相應的slave數據庫鏈接列表,其中它的相應節點信息說明如下(Discuz.Config\DbSnapInfo.cs): 
代碼 

復制代碼代碼如下:


[Serializable] 
public class DbSnapInfo 

/// <summary> 
/// 源ID,用于唯一標識快照在數據庫負載均衡中的信息 
/// </summary> 
private int _souceID; 
/// <summary> 
/// 源ID,用于唯一標識快照在數據庫負載均衡中的信息 
/// </summary> 
public int SouceID 

get { return _souceID; } 
set { _souceID = value; } 

/// <summary> 
/// 快照是否有效 
/// </summary> 
private bool _enable; 
/// <summary> 
/// 是否有效 
/// </summary> 
public bool Enable 

get { return _enable; } 
set { _enable = value; } 

/// <summary> 
/// 快照鏈接 
/// </summary> 
private string _dbConnectString; 
/// <summary> 
/// 快照鏈接 
/// </summary> 
public string DbconnectString 

get { return _dbConnectString; } 
set { _dbConnectString = value; } 

/// <summary> 
/// 權重信息,該值越高則意味著被輪循到的次數越多 
/// </summary> 
private int _weight; 
/// <summary> 
/// 權重信息,該值越高則意味著被輪循到的次數越多 
/// </summary> 
public int Weight 

get { return _weight; } 
set { _weight = value; } 


當然DbSnapAppConfig作為DbSnapInfo列表的容器,其結構如下: 
代碼 

復制代碼代碼如下:


[Serializable] 
public class DbSnapAppConfig : Discuz.Config.IConfigInfo 

private bool _appDbSnap; 
/// <summary> 
/// 是否啟用快照,如不使用,則即使DbSnapInfoList已設置有效快照信息也不會使用。 
/// </summary> 
public bool AppDbSnap 

get { return _appDbSnap; } 
set { _appDbSnap = value; } 

private int _writeWaitTime = 6; 
/// <summary> 
/// 寫操作等待時間(單位:秒), 說明:在執行完寫操作之后,在該時間內的sql請求依舊會被發往master數據庫 
/// </summary> 
public int WriteWaitTime 

get { return _writeWaitTime; } 
set { _writeWaitTime = value; } 

private string _loadBalanceScheduling = "WeightedRoundRobinScheduling"; 
/// <summary> 
/// 負載均衡調度算法,默認為權重輪詢調度算法 http://www.pcjx.com/Cisco/zhong/209068.html 
/// </summary> 
public string LoadBalanceScheduling 

get { return _loadBalanceScheduling; } 
set { _loadBalanceScheduling = value; } 

private bool _recordeLog = false; 
/// <summary> 
/// 是否記錄日志 
/// </summary> 
public bool RecordeLog 

get { return _recordeLog; } 
set { _recordeLog = value; } 

private List<DbSnapInfo> _dbSnapInfoList; 
/// <summary> 
/// 快照輪循列表 
/// </summary> 
public List<DbSnapInfo> DbSnapInfoList 

get { return _dbSnapInfoList; } 
set { _dbSnapInfoList = value; } 


通過這兩個配置文件,就可以實現對數據訪問層負載均衡的靈活配置了,不過上面的DbSnapAppConfig還有一個非常重要的 
屬性沒有介紹清楚,就是‘LoadBalanceScheduling',其接口聲明如下: 
代碼 

復制代碼代碼如下:


/// <summary> 
/// 負載均衡調度接口 
/// </summary> 
public interface ILoadBalanceScheduling 

/// <summary> 
/// 獲取應用當前負載均衡調度算法下的快照鏈接信息 
/// </summary> 
/// <returns></returns> 
DbSnapInfo GetConnectDbSnap(); 


它就是負載均衡算法的實現接口,為了便于說明在Discuz.EntLib中內置的兩個負載均衡算法的實現情況,請先看下圖: 
Discuz!NT數據庫讀寫分離方案詳解
內置的兩個負載均衡算法,一個是RoundRobinScheduling,即輪叫調度(Round Robin Scheduling)算法,它的實現比較簡單,就是對從數據庫鏈接列表的依次遍歷,如下: 
代碼 

復制代碼代碼如下:


/// <summary> 
/// 輪叫調度(Round Robin Scheduling)算法 
/// </summary> 
public class RoundRobinScheduling : ILoadBalanceScheduling 

private static object lockHelper = new object(); 
/// <summary> 
/// 當前的快照索引和權重信息 
/// </summary> 
static int curentSnapIndex = 0; 
static RoundRobinScheduling() 
{} 
public DbSnapInfo GetConnectDbSnap() 

lock (lockHelper) 

if (curentSnapIndex >= DbSnapConfigs.GetEnableSnapList().Count) 
curentSnapIndex = (curentSnapIndex) % DbSnapConfigs.GetEnableSnapList().Count; 
return DbSnapConfigs.GetEnableSnapList()[curentSnapIndex++]; 



而另一種負載均衡算法就相對負載了,不過它也更符合實際的應用場景,它使用了權重的方法來讓性能優良的機器分到 
更多的任務來均衡整個方案的性能,即權重輪詢調度算法,實現代碼如下: 
代碼 

復制代碼代碼如下:


/// <summary> 
/// 權重輪詢調度算法 
/// http://www.pcjx.com/Cisco/zhong/209068.html 
/// http://id-phatman.spaces.live.com/blog/cns!CA763CA8DB2378D1!627.entry 
/// </summary> 
public class WeightedRoundRobinScheduling : ILoadBalanceScheduling 

private static object lockHelper = new object(); 
/// <summary> 
/// 快照的權重列表 
/// </summary> 
static List<int> snapWeightList = new List<int>(); 
/// <summary> 
/// 當前的快照索引和權重信息 
/// </summary> 
static int curentSnapIndex, currentWeight; 
/// <summary> 
/// 快照權重列表中最大的權重值和最大公約數 
/// </summary> 
static int maxWeight, gcd; 
static WeightedRoundRobinScheduling() 

curentSnapIndex = -1; 
currentWeight = 0; 
snapWeightList = GetSnapWeightList(); 
maxWeight = GetMaxWeight(snapWeightList); 
gcd = GCD(snapWeightList); 

/// <summary> 
/// 獲取應用當前負載均衡調度算法下的快照鏈接信息 
/// </summary> 
/// <returns></returns> 
public DbSnapInfo GetConnectDbSnap() 

lock (lockHelper) 

DbSnapInfo current = RoundRobinScheduling(); 
if (current != null) 
return current; 
else 
return DbSnapConfigs.GetEnableSnapList()[0]; 


/// <summary> 
/// 獲取快照權重的列表 
/// </summary> 
/// <returns></returns> 
static List<int> GetSnapWeightList() 

List<int> snapWeightList = new List<int>(); 
foreach (DbSnapInfo dbSnapInfo in DbSnapConfigs.GetEnableSnapList()) 

snapWeightList.Add(dbSnapInfo.Weight); 

return snapWeightList; 

/// <summary> 
/// 權重輪詢調度算法 
/// </summary> 
static DbSnapInfo RoundRobinScheduling() 

while (true) 

curentSnapIndex = (curentSnapIndex + 1) % DbSnapConfigs.GetEnableSnapList().Count; 
if (curentSnapIndex == 0) 

currentWeight = currentWeight - gcd; 
if (currentWeight <= 0) 

currentWeight = maxWeight; 
if (currentWeight == 0) 
return null; 


if (DbSnapConfigs.GetEnableSnapList()[curentSnapIndex].Weight >= currentWeight) 
return DbSnapConfigs.GetEnableSnapList()[curentSnapIndex]; 


/// <summary> 
/// 獲取最大權重 
/// </summary> 
/// <param name="snapList"></param> 
/// <returns></returns> 
static int GetMaxWeight(List<int> snapWeightList) 

int maxWeight = 0; 
foreach (int snapWeight in snapWeightList) 

if (maxWeight < snapWeight) 
maxWeight = snapWeight; 

return maxWeight; 

/// <summary> 
/// 獲取權重的最大公約數 
/// </summary> 
/// <returns></returns> 
static int GCD(List<int> snapWeightList) 

// 排序,得到數字中最小的一個 
snapWeightList.Sort(new WeightCompare()); 
int minNum = snapWeightList[0]; 
// 最大公約數肯定大于等于1,且小于等于最小的那個數。 
// 依次整除,如果余數全部為0說明是一個約數,直到打出最大的那個約數 
int gcd = 1; 
for (int i = 1; i <= minNum; i++) 

bool isFound = true; 
foreach (int snapWeight in snapWeightList) 

if (snapWeight % i != 0) 

isFound = false; 
break; 


if (isFound) 
gcd = i; 

return gcd; 

/// <summary> 
/// 實現IComparer接口,用于對數字列表進行排序 
/// </summary> 
private class WeightCompare : System.Collections.Generic.IComparer<int> 

public int Compare(int weightA, int weightB) 

return weightA - weightB; 



到這里,主要的功能代碼就介紹的差不多了,我們可以通過對dbsnap.config的相應節點配置,來靈活定制我們的負載均衡方案。同時,對一般開發者而言,這種架構是透明的,大家可以完全在不了解它的情況下開發自己的數據訪問功能,并通過相應開關來讓自己的代碼支持均衡負載。 
當然這個方案還有一些沒考慮到的問題比如: 
1.對‘主從數據庫的健康度檢查',即如果主或從數據庫出現故障的時候該如何處理,當然在sqlserver中還提供了鏡像功能來解決類似問題,所以它也可做為一個備選方案。 
2.當主數據庫被發布出去后,主數據庫的表和存儲過程就會被‘鎖定',其不允許被再次修改了,所以還要繼續研究如何解決這一問題。 
原文鏈接:http://www.cnblogs.com/daizhj/archive/2010/06/21/dbsnap_master_slave_database.html  

作者: daizhj, 代震軍

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美日韩精品综合 | 在线观看黄色 | 欧美日韩国产一区二区三区不卡 | 在线中文字幕av | 欧美在线免费观看 | av免费网 | 欧美一级免费看 | 91精品福利少妇午夜100集 | 一本一道久久久a久久久精品91 | 国产精品二区一区二区aⅴ污介绍 | 国产成在线观看免费视频 | 激情欧美一区二区三区中文字幕 | 青青草91在线视频 | 欧美自拍小视频 | 欧美日韩视频一区二区 | 一本一道久久久a久久久精品91 | 欧美久久成人 | 国产51人人成人人人人爽色哟哟 | 国产精品美女久久久久久免费 | 亚洲一区二区三区在线播放 | 欧美1区2区3区 | 黄色一级片a | 中文久久 | 一区二区三区日韩 | 国产成人精品久久二区二区91 | 日韩欧美中文字幕在线视频 | av一区在线| 国产亚洲精品美女久久久久久久久久 | 久久99国产精品久久99果冻传媒 | 国产精品一区二区不卡 | 一区二区三区视频在线观看 | 黄桃av| 无码日韩精品一区二区免费 | 99久久婷婷国产综合精品电影 | 国产精品毛片久久久 | 在线四区 | 亚洲欧美在线一区 | a级性生活| 中文字幕一区二区三区精彩视频 | 最新免费av网站 | 羞羞视频在线观看 |