這篇來看看我如何在AlwaysOn中使用HAproxy,看看是否可以更有效利用Readable secondary。
我之前在SQL2016/2017 AG架構下,我實際透過application(NetCore and NetFramework)測試發現,
必須設定connectionstring中的pooling=false(預設true)才不用真正結束db session,
就有Load-Balancing效果,但這結果我並不意外,畢竟,connection pool是client在handle,
但我還是想測試看看透過HAproxy是否可以更有效率的進行Load-Balancing。
Note:
不使用connection pool對效能有滿大影響,
我以前對connection pool測試文章和XACT_Abort如何影響connection也可以參考看看
[C#][Tips]Dispose是否影響Connection Pooling?
[C#][Tips]如何確定Connection Pooling裡的Connection有效性
[SQL Server]Talking about XACT_ABORT
由於我們打算採取讀寫分離(AP至少有兩種以上connectionstring),
我為了讓AG中所有Secondary可以更有效利用,
所以我決定在既有AlwaysOn AG架構中加入HAproxy,看看是否能夠在更有效利用Secondary資源。
之前我已經在HAproxy設定好兩台的secondary sql server,透過HAproxy管理頁面確認如下
確認AG’s health
架構大概如下圖
測試:下面我會同時執行三個console
const string Connectionstringwithag = "Server=192.168.137.5;database=AdventureWorks2017;user id=sa;password=xxxx;Application Name=LoadBalanceWithAG;ApplicationIntent=ReadOnly;Timeout=60;";
const string Connectionstringwithvip = "Server=192.168.137.238;database=AdventureWorks2017;user id=sa;password=xxxx;Application Name=LoadBalanceWithVIP;Timeout=60;";
static void Main(string[] args)
{
var t1 = Task.Factory.StartNew(() =>
{
SelectMSSQL(Connectionstringwithag);
});
var t2 = Task.Factory.StartNew(() =>
{
SelectMSSQL(Connectionstringwithvip);
});
Task.WaitAll(new Task[] { t1, t2 });
Console.WriteLine("Completed!");
Console.ReadLine();
}
static void SelectMSSQL(string connectionstring)
{
var builder = new SqlConnectionStringBuilder(connectionstring);
string sqlstatement = @"
SELECT TOP 1
[Schema]
FROM [dbo].[DatabaseLog]
union all
select 'Current Server:'+@@SERVERNAME as [SERVERNAME]";
int i = 0;
while (i < 6)
{
try
{
using (SqlConnection cn = new SqlConnection(connectionstring))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand(sqlstatement, cn))
{
cmd.CommandType = System.Data.CommandType.Text;
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
Console.WriteLine($"Result:{dr[0].ToString()} from {builder.ApplicationName}");
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception:{ex.Message}");
}
i++;
}
Console.WriteLine($"Done from :{builder.ApplicationName}");
}
第一個console
使用VIP的都存取 WIN2K16D\SQL2K17
使用AG的都存取 WIN2K16C\SQL2K17
第二個console
使用VIP的都存取 WIN2K16C\SQL2K17
使用AG的都存取 WIN2K16C\SQL2K17
第三個console
使用VIP的都存取 WIN2K16D\SQL2K17
使用AG的都存取 WIN2K16D\SQL2K17
結果
使用VIP: WIN2K16D\SQL2K17 => WIN2K16C\SQL2K17 => WIN2K16D\SQL2K17
使用AG: WIN2K16C\SQL2K17 => WIN2K16C\SQL2K17 => WIN2K16D\SQL2K17
看來結果大同小異,雖然這次測試,HAproxy可以更有效利用Secondary資源,
但相對也要付出整合維護HAproxy成本,是否要使用就見仁見智了。
參考
[SQL SERVER]SQL2016-設定Alwayson AG Load Balance
[SQL Server] Config SQL Server 2017 availability group on Windows