《
Discuz!NT論壇數(shù)據(jù)庫讀寫分離方案》文章地址:http://www.tfxk.com/wangyesheji/jianzhanjingyan/0302334a2013.htm
--> [
網(wǎng)站建設之]Discuz!NT論壇數(shù)據(jù)庫讀寫分離方案
它所做的就是確保用戶cud操作之后,在劃定的時間內(nèi)還是訪問主數(shù)據(jù)庫,當時光超過期,才將當前用戶的訪問要求(select)均衡到其它從數(shù)據(jù)庫中。
目前在Discuz!NT這個產(chǎn)品中,數(shù)據(jù)庫作為數(shù)據(jù)長久化工具,一定在并發(fā)訪問頻繁且負載壓力較大的情形下成 為體系性能的‘瓶頸’。即便應用本地緩存等方法來解決頻繁訪問數(shù)據(jù)庫的問題,但仍然會有大批的并發(fā)懇求要拜訪動態(tài)數(shù)據(jù),固然 SQL2005及2008以上版本中機能不斷晉升,查問打算跟存儲進程運行得越來越高效,但終極仍是 要面臨‘瓶頸’這一問 題。當然這也是很多大型網(wǎng)站一直研討摸索各式各樣的計劃來有效下降數(shù)據(jù)訪問負荷的原 因, 其中的‘讀寫分別’方案就是一種被普遍采取的方案。
Discuz!NT這個產(chǎn)品在其企業(yè)版中提供了對‘讀寫分離’機制的支撐,使對CPU及內(nèi)存耗費重大的操作(CUD)被 分離到一臺或幾臺性能很高的機器上,而將頻繁讀取的操作(select)放到幾臺配置較低的機器上,然后通過‘事務 發(fā)布訂閱機制’,實現(xiàn)了在多個sqlserver數(shù)據(jù)庫之間疾速高效同步數(shù)據(jù),從而到達了將‘讀寫請求’按實際負載 情況進行均衡散布的后果。
下面就扼要介紹一下實在現(xiàn)思路。注:有關數(shù)據(jù)同步的工具已在sqlserver中自帶了,可以參考這篇文章。
將相應的數(shù)據(jù)由Master(主)數(shù)據(jù)庫中‘宣布’出來,而后使用推送的方式(注:事務發(fā)布能夠指定是‘通過主 數(shù)據(jù)庫推送’ 還是‘訂閱服務器去獲取’)發(fā)送到訂閱它的數(shù)據(jù)庫中,就實現(xiàn)了數(shù)據(jù)同步功效。
下面就介紹一下如何通過改變既有代碼來實當初‘多少個從數(shù)據(jù)庫(相似快照)’間進行讀取數(shù)據(jù)的負載均衡。
原有的代碼中由于使用了分層機制,所以咱們只有在‘數(shù)據(jù)訪問層’動一下心理就可以了。在這里我的一個設 計思路就是不轉變已有的數(shù)據(jù)庫訪問接口(包含參數(shù)等)的條件下,實現(xiàn)底層主動將現(xiàn)有的數(shù)據(jù)訪問操作進行負載 均衡。這樣做的利益不必多說了,同時也讓這個負載均衡功能與數(shù)據(jù)訪問層相分離,不要耦合的太嚴密,同時假如不知道底層 的實現(xiàn)原理也可以只通過一個開關(后面會先容),就可以讓本人的sql語句自動實現(xiàn)動態(tài)負載均衡。
說到這里,我來對比代碼進一步論述:
首先就是(Discuz.Data\DbHelper.cs)代碼,重要變動如下(新增方法局部):
有關相應配置節(jié)點和負載均衡算法會在后面提到,這里為了堅持文章內(nèi)容的持續(xù)性暫且跳過,下面接著閱讀一下上面調(diào)用的‘UserSnapDatabase’辦法:
Code highlighting produced by Actipro CodeHighlighter (freeware)>DbSnapInfo dbSnapInfo = GetLoadBalanceScheduling.GetConnectDbSnap();
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)>/// <summary>
/// 是否使用快照數(shù)據(jù)庫
/// </summary>
/// <,
digg創(chuàng)始人經(jīng)驗分享 發(fā)展網(wǎng)站用戶的9個方法;param name="commandText">查詢</param>
/// <returns></returns>
private static bool UserSnapDatabase(string commandText)
{
// 如果上次刷新cookie距離小于5分鐘, 則不刷新數(shù)據(jù)庫最后運動時間
if (commandText.StartsWith(BaseConfigs.GetTablePrefix + "create"))
{
Utils.WriteCookie("JumpAfterWrite", Environment.TickCount.ToString());
 ,
dedecms織夢管理系統(tǒng)的網(wǎng)站搬家的步驟;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;
}
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)><?xml version="1.0"?>
<DbSnapAppConfig xmlns:xsi="
<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>
 ,
dedecms 負載性能優(yōu)化實例;<Enable>true</Enable>
 ,
CSS高級技巧 圖片替換; <DbconnectString>Data Source=DAIZHJ-PC\2222;User ID=sa;Password=123;Initial Catalog=tabletest;Pooling=true</DbconnectString>
<Weight>3</Weight>
</DbSnapInfo>
</DbSnapInfoList>
</DbSnapAppConfig>
Code highlighting produced by Actipro CodeHighlighter (freeware)>(Environment.TickCount - TypeConverter.StrToInt(Utils.GetCookie("JumpAfterWrite"), Environment.TickCount)) < DbSnapConfigs.GetConfig().WriteWaitTime * 1000)
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)>/// <summary>
/// 負載均衡調(diào)度接口
/// </summary>
private static ILoadBalanceScheduling m_loadBalanceSche;
/// <summary>
/// 初始化負載平衡調(diào)度接口實例
/// </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;
}
}
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)>/// <summary>
/// ,
CSS高手必知10大秘籍;獲取使用的數(shù)據(jù)庫(或快照)鏈接串
/// </summary>
/// <param name="commandText">存儲過程名或都SQL命令文本</param>
/// <returns></returns>
public static string GetRealConnectionString(string commandText)
{
if (DbSnapConfigs.GetConfig() != null && DbSnapConfigs.GetConfig().AppDbSnap)
{
 ,
CSS頁面布局中HTML結構化設計; 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,
 ,
CSS隱藏文字的幾個方法; dbSnapInfo.DbconnectString,
commandText.Replace("'",""),
 ,
CSS透明相關技巧的介紹; Discuz.Common.Utils.GetDateTime()));
return dbSnapInfo.DbconnectString;
}
}
return ConnectionString;
}
Tag:讀寫分離 Discuz 讀寫分離 Discuz
 ,css透明濾鏡 兼容ie6,ie7,ie8以及firefox; 上面的方法將會對傳入的sql語句進行剖析,找出其中是CUD操作還是SELECT操作,來差別是讀還是寫操作,CSS選擇符詳解。而snapLogList列表則是之前所配置的‘事務發(fā)布訂閱’模式下的相關‘從數(shù)據(jù)庫’(Slave Database)鏈接串的列表,例如(dbsnap.config文件的DbSnapInfoList節(jié)點):
它的作用就是加載配置文件信息,其中最主要的就是相應的‘負載均衡算法實例’來獲取相應的從數(shù)據(jù)庫鏈接串,下面先看一
下‘靜態(tài)屬性’GetLoadBalanceScheduling的相干信息:
當然,在GetRealConnectionString()方式中,還有一行代碼很主要,就是下面這一行:
該方法的作用很簡略,就是當數(shù)據(jù)庫有CUD操作時,通過寫cookie的方式向客戶端寫一個鍵值‘JumpAfterWrite’,這個鍵值很重要,就是供給一個標簽(flag)來唆使:‘當前用戶履行cud操作時,頁面跳轉到其它頁面而主數(shù)據(jù)庫還沒來得及將數(shù)據(jù)推送到從數(shù)據(jù)庫’這一情況而造成的‘數(shù)據(jù)不同步’問題。
舉了例子,當在一個版塊中‘發(fā)表主題’后系統(tǒng)自動跳轉到‘顯示該主題頁面’時,如果主數(shù)據(jù)庫中插入了一個新主題而從數(shù)據(jù)庫不被及時更新這一主題信息時,就會報‘主題不存在’這個過錯。所以這里加了一個設置,就是下面這一行:
(責任編輯:網(wǎng)站建設)
Discuz!NT論壇數(shù)據(jù)庫讀寫分離方案相關文章