SQLSERVER的User Connections 对应性能计数器中SQL实例的General StatisticsUser Connections 同时可参考才性能计数器中的:TCPv4Connections Established
在一台仅装有SQLSERVER服务的机器上,TCPV4 Connections Established && Mssql UserConnections这两个参数基本保持同步,在下面的测试内容里称为连接数
这个连接数是有限额的,类似于最大并发数上限。当这个上限达到时,即使有空闲的CPU,IO,MEM资源,也会导致查询无响应(部分,不是所有查询有影响)
TCPV4 Connections Established && Mssql UserConnections最大值能达到多少,跟以下因素有关
a.执行语句的复杂度有关,语句越复杂,连接数最大值就越小(这个影响很重要)
b.跟请求的线程并发度有关,
10个进程,每个进程开5000个线程去请求, SELECT getdate() 语句能到4000左右就已经废了(我的理解是很多线程虽然没有申请到资源,但是请求数大了,也有影响)
10个进程,每个进程开1000个线程去请求, SELECT getdate() 语句能到10000以上。
c.跟线程请求的频繁程度有关
假如每个线程运行一次查询后,暂停0-10000毫秒,会比不暂停占用更少的连接数,暂停的时间越长,服务端需要打开的userconnectons越少,查询结果超时现象出现的机率也更少
d.测试中还发现有一些不关闭的连接会造成计数器虚大的假想,不在讨论范围
10个进程 ,每个进程开1000个请求线程,每次查询后随机暂停(0到10秒)在服务器上测试结果如下:
执行:SELECT * FROM [system].[dbo].[DBA_alert]语句时(这个查询返回200行,最大连接数700就开始有问题 )
连接数压到700时部分开始报错,1200时开始出现大批量报错,1800左右连接数卡住不再往上升高。报错和迟钝的连接大量出现
执行:SELECT getdate()语句时(最大连接数3500就开始有问题 )
连接数压到3500时部分开始有报错,最高压到11000左右连接数还在缓慢往上升高。报错和迟钝的连接井喷
结论是:在给定的压力条件下:执行最简单的SELECT getdate() 时最大连接数可以到3500,执行SELECT * FROM [system].[dbo].[DBA_alert]语句时,最大连接数只能到700.查询超时是发生在CPU,IO,MEM都有大量闲置资源的情况下。
而生产环境上其实达不到10*1000个线程的压力,但是SQL会比测试的环境复杂。
并发数的瓶劲不是因为我的电脑或服务器网卡带宽引起的
为证明以上。做了以下测试,大并发情况下 exec dbo.run2 ;
ALTER proc [dbo].[run2]
as
set nocount on
select getdate()
declare @i int
set @i=0
while @i<1000 当这个值是1000时,最大连接数约在1300时查询大量超时,这个值是10时,到5000还正常。
begin
INSERT INTO [pubs].[dbo].[tb_test]([name]) values (newid())
set @i=@i+1
end
go
改动循环次数不会影响返回结果,也就是对网卡流量的压力是一样的,但是一个很快超时,一个一直能查,所以两边网卡带宽的影响可排除。
最大连接数停滞时的报错内容:
最大连接数停滞时的netstat-an结果(大量的established):
最大连接数停滞时的测试程序运行图:
值得注意的是:出错或超时的连接并不平均,会集中在部分进程的,也就是说有部分进程一直都能正常运行,另一部分长时间报错(跟进程的启动顺序也没关系,我的理解是有些进程持有了资源,就可以继续正常工作,而另一些进程里的线程原先的资源被抢占以后申请不到新的资源,就会一直反复报错)如上图所示,第2,7个进程开始出现大量的超时,别的进程还在继续工作 ,在服务器上可能会表现为一部分机器的查询不受影响或影响较小,一部分机器影响明显。
结论:SQLSERVER的User Connections的上限虽然跟一系列的条件有关,但是还是可以预估和预计的瓶劲所在,当达到这个上限时,会有大量的查询缓慢和超时(尽管CPU,IO.MEM,流量 都存在空闲的资源情况下也会发生)。事实上改动一些TCP参数会提高这个上限,后续可能会写补充
|