ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 为什么生产环境会跑得比测试环境还慢

为什么生产环境会跑得比测试环境还慢

原创 Linux操作系统 作者:apgcdsd 时间:2011-09-21 09:12:42 0 删除 编辑

一套数据库应用系统,在测试环境里运行得非常理想,性能不错。生产环境中的服务器比测试环境要高档,价钱更贵,应该会跑得更快吧?可是在某些情况下,事与愿违,整个应用,或者应用的某个功能组件,在生产环境里跑得比测试环境反而还慢。如果项目实施的时候有这种事情发生,真是很尴尬,令人难以接受。是SQL Server的问题么?还是应用程序的问题?有些时候,两者都不是。

 

我们先来探讨一个前提,为什么同一个应用,生产环境中的服务器比测试环境要高档,价钱更贵,就应该会跑得更快?一般来讲,服务器高档,体现在下面几个明显的特征。

  • CPU数目更多

             或者

  • 内存更大

             或者

  • 有磁盘阵列(SAN/RAID)

更多的系统资源,应该能帮助SQL Server运行得更快。所以在绝大部分情况下,自然是高档的服务器跑得更快。那为什么有些用户会遇到生产环境跑得比测试环境还慢这样的悲剧呢?常见的原因有以下几种。


1CPU数目虽多,但是单个CPU的能力不一定强;而跑得慢的操作,需要消耗一定的CPU资源,同时SQL Server又是用单线程完成的。

OLTP类型的应用里,语句相对比较简单,操作的数据量比较少,SQL
Server
会选择用单个线程完成。也就是说,每个操作,SQL Server都是用单个CPU做的。CPU数目多,可以使得SQL Server能够在同一个时间,处理更多的并发请求。但是对于单个操作的时间长短,则是由单个CPU的能力决定的。

现在服务器上的CPU,往往一个就包含4核、8核,而且常常设置成Hyper-Threading。结果是在Windows里看上去,CPU的数目很多。但是这些CPU都是逻辑CPU。它们单个的处理能力怎么样?最好能测试一下。


2.内存虽多,但是SQL Server用不上。

如果内存足够多,SQL Server会把所要访问和处理的数据都缓存在内存里。所以更多的内存绝大多数时候能够提高性能。但是如果数据库比较小,所要访问和处理的数据还没有物理内存大的时候,再增加内存就没有什么意义了。不能说内存越大,SQL性能就一定越好。


3.服务器是NUMA结构,而问题语句所需要的内存,大于单个NUMA节点的内存数

现在的很多服务器都采用了NUMA技术,将CPU和内存分组,每个NUMA节点包含一部分的CPU和内存。在节点内部,CPU访问内存会很快。但是如果CPU需要访问本节点之外的内存里的数据,会慢一点。

这样的设计,对于并发用户比较多的应用,是很有好处的。如果某个客户发给SQL Server一个变态的请求,那基本只会把某一个NUMA节点忙死。而其他节点还能够正常处理其他用户的请求。这可以有效避免一个客户把整台服务器搞垮掉的事情发生。但是对于那些变态的语句(语句要访问和处理的数据量大于单个NUMA节点里的内存数目),由于得到的资源比非NUMA的机器要少,跑得有可能会慢一点。一般情况下,如果执行某个语句产生的执行计划不够好,有可能导致使用超过NUMA节点内CPU数目的并行;这种情况下,跨NUMA节点的并行,由于NUMA体系结构的原因(跨NUMA节点访问内存比访问节点内内存慢很多),可能导致语句执行速度更慢。在这种情况下,我们有两种解决方案,一是优化语句,以避免产生非常大的并行执行计划,二是我们可以设置MaxDOP以限制所有语句,即使真的需要也只在NUMA节点内进行并行。


4.虽然有磁盘阵列,但是整体IO速度,不是那么强。

磁盘阵列是有很多配置选项的。如果配得不优化,最终的性能不一定就好。微软有个测试工具,叫SQLIO,可以模拟SQL Server IO的方式,进行磁盘压力测试。如果怀疑磁盘有问题,可以用它来比较一下。

 

5.对于单个的小型write操作,磁盘做得不是很快。

这是一个比较常见的问题。磁盘阵列,对于每次大批量的读写(比如copy一个大文件),一般能做得比较好。但是SQL Server日志文件的操作方式,是很特殊的。为了保证事务的ACIDSQL
Server
commit一个transaction之前,必定要确保这个transaction所对应的日志记录,已经写入了物理磁盘。而且,日志记录,是严格按照时间前后,顺序写入日志文件的。基于这种特性,日志文件所在的磁盘读写,有这样的特征:

       A. SQL对日志文件基本只做写,很少做读

       B. 同一个时间最多只有一个写请求。就算是磁盘来不及写,其队列也维护在SQL Server内部,在磁盘上不会看到disk queue length >1

       C. 每次写请求,一般都不会很大。但是只有这次写完成了,SQL Server才会发出下一次的写请求

如果磁盘阵列在配置时,没有考虑到这一类操作,那往往是体现不出磁盘阵列的优势的。我不止一次遇到过,客户服务器上的速度,还比不过我自己的PC机。不过大部分客户没有遇到问题。因为大部分类型的数据库应用,查询的操作整体会比增、删、改要多。日志文件写入还不是系统瓶颈。

如果您的应用有非常频繁增、删、改动作,那就要检测一下存放日志文件的磁盘的日志记录吞吐能力了。比较简单的方法,是对一个字段不是很多的空表,用insert语句插入1万到10万条数据。Insert语句循环的外面,千万不要套”begin tran””commit tran”。这样每个插入动作都是一个小的事务,都会触发磁盘写操作。通常情况下,哪台机器的日志记录吞吐能力高,哪个先做完。

 

另外,还有以下几个常见的原因,也能导致同一个操作在不同的机器上速度不同。

1.应用所访问的数据库里,数据量不一样,或者数据的值的分布情况不一样

2.生产服务器上还有其他工作负荷,而测试服务器是没有其他人用的

3.一台服务器应用跑在SQL Server本地,一台服务器应用跑在SQL Server远端

4.由于硬件配置不同,SQL Server在两台机器上选择了不同的执行计划

5 一台服务器SQL Server开着SQL trace,一台服务器没有开

6.两台服务器的Windows或者SQL Server,在版本,或者某些配置上有不同

 

总之,问题的原因可能性还真不少。在遇到这种情况的时候,千万不要草率地将其归结于软件问题,或者是硬件问题。找到问题的根本原因,然后再做调整。这样才能使您的服务器物有所值,发挥最大的功效。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25175503/viewspace-707993/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2011-04-21

  • 博文量
    69
  • 访问量
    78329