- 论坛徽章:
- 0
|
在我们能够开始考虑如何在一个繁忙的MySQL服务器上进行调整之前,我们最好对会影响性能的若干因素有一个了解,同时,也是最重要的,要了解这些因素是怎么影响性能的。绝大多数MySQL用户所面临的最大问题之一,恰恰是不知道如何确定瓶颈所在。
6.1.1 硬盘
在一个数据服务器中的主要矛盾,通常发生在CPU和可用的磁盘I/O性能之间;我们稍后会讨论内存的问题。即使一台普通服务器的CPU也要比磁盘快几个数量级。如果你无法尽可能快的将数据传送给CPU,CPU就得在磁盘定位数据并传送到主存期间坐等操作完成。
真正的问题在于大多数的磁盘存取操作是随机的而不是按序的:这里读2个数据块,那里读10个,那边又4个,诸如此类。这意味着即使你所用的最新型的SCSI硬盘在参数上标称有80MB/秒的吞吐量,你也很少能看到它真的能达到这么高的值。你所等待的大多数时间被用来等待磁盘定位数据。磁头在盘片间移动并获取另外一块数据的时间,被称为寻道时间(seek time),这个参数是决定现实世界中硬盘性能的主宰因素。
寻道时间的构成分为两个部份。第一个是将磁头从一个位置移动到另外一个位置所需的时间总和。当磁头到达新的位置,它还通常需要等待盘片旋转一点以能够读取所需要的信息片段。磁盘的转速,以RPM作为标称,是影响寻道时间的第二个方面。一般说来,更快的盘片转速,会带来更低的寻道时间。当为你的数据服务器采购硬盘时,通常花比10,000-RPM型号稍多一点儿的钱来购买15,000-RPM的型号,会更为划算。作为回报,更高的RPM转速的磁盘能够带来更大的传输速率,因为它们是从旋转更快的盘片上读取数据的。
综上所述,你可能遭遇的第一个瓶颈就是磁盘的I/O。硬盘很明显是系统中最慢的一个部件。就像CPU的高速缓存一样,MySQL的各种缓冲区和缓存使用主存作为磁盘数据的缓存。如果你的MySQL服务器有足够的I/O容量,而且MySQL被配置为能够更有效的使用可用内存,你就能更充分的利用CPU的计算能力。
一个对MySQL常见的报怨是它不能处理超大的表。假设做出这种报怨的人曾经用过MySQL,他们也多半也是遭遇了一个他们不知道如何修正的I/O瓶颈。MySQL可以在几百M的数据上工作的很好,但是一旦负载超过60GB,它就开始变慢。这个结论引申出来就是MySQL莫名奇妙的无法胜任工作。
当然,的确有些情形下MySQL会受限于CPU而不是I/O:这些情形并不常见。如果你经常请求MySQL在你的数据上执行一些计算操作(数学,字符串比较,等等),CPU的负载就会加重。当运行一个CHECK TABLE命令时,你就可能会发现CPU负载居高不下。另外,没有使用索引的查询毫无疑问也是耗费CPU计算能力的大户。
6.1.2 内存
为了弥补飞速的CPU和相对较慢的硬盘之间的鸿沟,我们还可以借助内存。从性能的角度来看,内存处于居中的位置-它比磁盘要快的相当多但是仍然要比CPU慢。底层的操作系统通常会使用空闲的内存来缓存从磁盘上读写的数据。这意味着你如果频繁的反复查询同一个小的MyISAM表,那么很有可能此后不用再对磁盘进行存取操作。哪怕MyISAM的记录数据不会被MySQL进行缓存(MySQL只缓存索引块),整个的MyISAM表也有可能被操作系统放在了它的磁盘缓存中。
现代的CPU比内存也显著的要快。为了弥补这种不匹配,芯片制造商设计了多级缓存系统。一个CPU普遍都会包含一级、二级甚至三级缓存。这些缓存使用了速度极快且造价昂贵的存储元件,所以其大小通常只是主存很小的一部分;一个512KB的二级缓存已经是很奢侈了。
有鉴于此,简单的增加内存到服务器中并不会提升MySQL的性能,除非操作系统能够充分利用增加的内存来缓存更多的磁盘数据块。如果你的数据库是512M,同时你已经有了1G的内存,增加内存很可能帮不上什么忙。
另外一方面,如果服务器上运行的不仅仅是MySQL服务器,那么增加内存也许会有帮助。也许所运行的Jave的应用服务器吃光了很多内存,而这些内存本可以用来缓存磁盘存取的。牢记Linux像大多数现代操作系统一样,将缓存磁盘I/O作为一个可选特性。它并不为这个特性保留任何内存。所以当可用内存吃紧的时候,MySQL会深受其害,因为MyISAM这种表引擎是期望操作系统能做一些读取缓冲工作的。
6.1.2.1 MySQL的缓冲区和缓存
通过调整MySQL所使用的内存大小,你通常能够感觉到显著的性能提升。为了有效的进行内存调整,你首先需要理解MySQL是如何使用内存的。绝大多数MySQL所分配的内存都是提供内部各种缓冲区和缓存使用的。这些缓冲区主要分为两组:全局缓冲区(global buffers)和每连接(per-connection)缓冲区。顾名思义,全局缓冲区在MySQL所有的连接(或线程)间共享的。
有两个最重要的全局缓冲区:一个是MyISAM的键缓冲区(key_buffer_size);另外一个就是InnoDB的缓冲池(innodb_buffer_pool_size)。前者是被MySQL用来缓存MySQL表经常使用的索引数据块的。MySQL借助磁盘进行扫描索引的频度越低,查询语句执行起来就越快。如果可能,考虑将键缓冲区增大,到足够容纳你所有常用的(如果不能全部都容纳的话)表的索引。通过将每张表的.MYI文件的大小做累加,你就会对所需缓存的大小得到一个的合理估算值。
MySQL并不缓存MyISAM表的记录数据-它只缓存索引。InnoDB则与此相反,它在它的缓存池中同时缓存数据和索引。回忆一下我们在第四章中提到的,InnoDB使用聚簇索引。因为它将数据和索引保存在一起,尽可能同时将索引和数据保存在缓存中也是理所当然的。
服务器硬件购买
当你要购买新的数据库服务器硬件的时候,无论是你想自行组装还是从知名厂商处购买,都有很多细节要考虑。一台售价4,000美元的IBM,HP或者Dell的品牌服务器,与你花2,300从你钟爱的“白牌”公司装配的机器有什么不同?答案有很多,而且其中有些会影响到MySQL的性能。我们看一下:
内存速度
CPU从PC3700标准的内存中检索数据的速度,要比从老式的PC133的内存中检索的速度快很多。请在你能负担的范围内尽可能购买最快速度的系统总线和与之相匹配的内存。在单位时间内,CPU花在等待数据到达上的时间越短,它就能做更多其他的工作。服务器级的硬件通常使用带有错误检校(Error Checking and Correcting ,ECC)功能的内存,以检测内存中因为老化或者辐射、宇宙射线等外部因素所导致的错误。
CPU的缓存
频繁被存取的内存会被CPU缓存在一级、二级或者三级缓存中。CPU缓存的越大越好。
多I/O通道
更为昂贵的服务器级系统通常拥有多条、独立的I/O通道,而不是使用一条共享的总线。这意味着在主存和你的硬盘控制器之间传输数据时,不会干扰到CPU和网卡之间的数据通道。再者,这也意味着CPU花费更少的时间在等待数据到达或发送上。
不幸的是,这些差别只有在系统处于相当大的负载之下的时候才会显露出来。将一台普通的白牌系统和一个服务器级系统做比较,如果只通过低负载进行性能评估,你会得到近似的分数。白牌系统没准分数还更高。而当他们处于真实的生产环境的负载下时,白牌系统性能表现就惨不忍睹了。
冗余电源
配备多个电源不会让你的服务器更快。它只能在主电源失效的情况下让你的服务器保持运行。在高性能和没性能之间选择,答案不言自明。而且,当你切换到不同供电线路的时候,你还能够抵御保险丝或者短路器故障。
热插拔硬盘
不是所有的服务器都具备供热插拔的RAID硬盘这种宝贵的特性。没有这项功能意味着你如果要从硬盘失效的错误中死里逃生,你最终还是要将机器断电以更换坏掉硬盘。避免这个缺点的唯一途径,就是寄希望于你的机器还有空间安装一个后备的(或这热备)的磁盘,然后RAID系统可以在失效的时候激活这个盘。当以"degraded"模式(缺少一个磁盘)运行RAID阵列时,你会同时面临牺牲性能或者冗余性或者两者都牺牲的风险。
与此类似,很多品牌服务器都提供了带有后备电池的RAID控制器,可以保证未写入的数据在掉电恢复的时候都能被真正写入。这也会加速性能,因为写入操作可能在写入控制器内存中的时候就被认为完成了,而不是真的要等待物理写入操作结束。不幸的是,大多数供应商的控制器内缓存都相对较小。
千兆网络或者多网络端口
服务器级的硬件通常比一般的桌面或者膝上型计算机具有更好的网络组件。比如你会看到千兆网或者双以太网接口(通常100M)。在配置复制的时候多网络端口是有帮助的,在第七章中你就会看到。
考虑在一些“小东西”省钱是非常诱人的,尤其是在你为一个群集购买好多台服务器的时候,小东西包括CPU的内置缓存有多大,或者内存的速度多少,因为这些小东西在上百台机器中的开销,累加起来也相当客观。当你构建一个单台服务器或者复制用的主服务器时,你要抵抗住这种诱惑。这是你人生中为数不多的可以通过“砸钱”来让生活愉快的机会。
另外一方面,如果你想构建另外一个Google,你的目标应该就是尽可能的买到最多数量的廉价机器,并且在以后需要的时候再添加更多。
6.1.3 网络
网络性能与MySQL的关系不大。在绝大多数部署环境中,客户端通常与服务器的距离非常近-往往就是接在同一个交换机上-所以网络延迟很低,同时可用的带宽极为充足。但是在某些不常见的情况下,网络也可能成为瓶颈。
双工不匹配是一个常见的网络配置错误,这个错误直到负载上升之前往往被忽视。当负载增加,就会明显的发现MySQL给客户端发送结果的速度非常慢。但是当你检查服务器的运行情况时,会发现CPU几乎是空闲的,硬盘也没有太大的负载。究其原因,有很多的100M网卡设备在自动感知正确配置的功能上存在问题。要确保你的服务器和交换机就半双工或全双工功能协商正确。
有些MySQL部署环境中使用网络接入存储(Network Attached Storage ,NAS),比如用一个网络文件阵列,而不是本地磁盘来存储MySQL的数据。这个想法基于一旦服务器崩溃,你可以简单的切换到另外一个服务器,而不用受到要复制数据和处理同步事宜的困扰(第八章里对此有详细的讨论)。在这种情况下,在配置上的一个重要考虑就是确保网络不要拥堵,理想的情况下,你应该要在MySQL服务器和存储服务器之间建立一个快速的专用通道。通常这意味着安装第二块网卡(NIC)通过私有网络连接你的存储服务器。
在包含一个主服务器和多个从服务器的复制环境中,非常可能产生主服务器的唯一一块网卡,被从服务器所产生的数据所堵塞的情况。这并不是MySQL的某些可怕的过错所带来。这是一个扩展性的上的问题。设想一下你有50个从服务器从主服务器中复制数据。在常规的情况下,每个从服务器使用相对较窄的带宽-比如100KB/秒。50个从服务器就会需要5MBit/秒的带宽。如果你使用的是100M的以太网,这不是个大问题。但是如果你的主服务器的每秒执行插入操作的变得更多,或者遇到包含BLOB类型的大型插入怎么办?你会遭遇每个从服务器需要800KB/秒的带宽以维持与主服务器同步的情况。这时你会在你的百兆网络中看到40Mbit/sec的流量。
说到这里你可能开始担心了。百兆每秒是理论上的最大网络带宽。实际的容量要远小于这个数值。很多网络工程师使用50%作为容量规划的经验法则。一旦他们发现网络中存在超过此上限的情况存在,他们就开始考虑将网络分解以获得更好的隔离流量。问题是,这对于我们讨论的情形没有太大的帮助。因为只有一个独立的主服务器,所有的从服务器都必须从它身上读取数据。
解决这个问题有三个可能的方案。首先,你可以通过引入第二个从服务器层来降低从主服务器的负载。然后这一层的从服务器作为主服务器为原来的50个从服务器提供复制服务。第七章中有关于多层复制体系的详细信息。
另外一个解决方案是给主服务器增加第二块网卡以将50个从服务器分隔到多个交换机。主服务器的每个网卡都要连接到不同的交换机。困难在于你需要记住哪个服务器连接到哪个交换机接口,并正确的设置从服务器的配置文件。
最后一个方案就是对主服务器和从服务器之间的数据流进行压缩。前提是数据流之前并没有被压缩过,而且主服务器也有足够的CPU计算能力,在处理高频率的插入操作之余,对50个对外发出的数据流进行压缩。随着CPU计算能力的不断攀高,这个方案也是具有可行性的。第七章对加密和压缩复制的方法也有讨论。
当你的网络连接有相对较高的延迟的时候,就会导致性能问题。这个问题通常是由服务端与客户端相距很远,或者连接链路本身具有高延迟(比如拨号或者卫星线路)的特性所造成的。你的目标应该锁定在让客户端与服务端相互之间相距(从网络的角度)尽可能的近。如果可能的话,为你最远的那些客户端设置一个从服务器。
乍一看这可能不像一个服务端性能问题,但是一个高延迟或者低带宽的网络真的会将服务端的工作拖慢。当一个客户端在一个MyISAM标上执行一个大型的SELECT操作,会在数据上获得一个读锁定。直到SELECT操作完成,服务器不会释放这个锁定,并且还会搁置其它的对表的写操作。如果请求数据的客户端碰巧在一个很远或者在一个古怪拥挤的网络上,收取所有的数据并释放锁定将要耗费很长的时间。最终的结果就是工作都阻塞在服务端,尽管此时服务端的CPU和磁盘I/O资源都很充裕。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/7114/showart_264488.html |
|