現在不管是做什麼開發都講究高效率。開發的時候不只講究你的技術有時候一些功能的最佳化也會提高你的工作效率。現在MySQL運行的大部分環境都是在Linux上的,如何在Linux作業系統上根據MySQL進行最佳化,我們在這裡給出一些通用簡單的策略。這些方法都有助於改進MySQL的效能。
一、CPU
先從CPU開始。
你仔細檢查的話,有些伺服器上會有的一個有趣的現象:當你cat /proc/cpuinfo時,會發現CPU的頻率竟然跟它標稱的頻率不一樣:
#cat /proc/cpuinfo processor : 5 model name : Intel(R) Xeon(R) CPU E5-2620 0 @2.00GHz ... cpu MHz : 1200.000
這個是Intel E5-2620的CPU,他是2.00G * 24的CPU,但是,我們發現第5顆CPU的頻率為1.2G。
這是什麼原因列?
這些其實都源自於CPU最新的技術:節能模式。作業系統和CPU硬體配合,系統不繁忙的時候,為了節省電能和降低溫度,它會將CPU降頻。這對環保人士和抵制地球暖化來說是一個福音,但對MySQL來說,可能是一個災難。
為了確保MySQL能夠充分利用CPU的資源,建議設定CPU為最大效能模式。這個設置可以在BIOS和作業系統中設置,當然,在BIOS中設置該選項更好,更徹底。由於各種BIOS類型的區別,設定為CPU為最大效能模式千差萬別,我們這裡就不具體展示怎麼設定了。
二、記憶體
然後我們看看記憶體方面,我們有哪些可以優化的。
i)我們先來看看numa
非一致儲存存取結構 (NUMA : Non-Uniform Memory Access) 也是最新的記憶體管理技術。它和對稱多處理器結構 (SMP : Symmetric Multi-Processor) 是對應的。簡單的隊別如下:
#如圖所示,詳細的NUMA資訊我們這裡不介紹了。但我們可以直覺的看到:SMP存取記憶體的都是代價都是一樣的;但是在NUMA架構下,本地記憶體的存取和 非本地記憶體的存取代價是不一樣的。對應的根據這個特性,在作業系統上,我們可以設定進程的記憶體分配方式。目前支援的方式包括:
--interleave=nodes --membind=nodes --cpunodebind=nodes --physcpubind=cpus --localalloc --preferred=node
簡而言之,就是說,你可以指定內存在本地分配,在某幾個CPU節點分配或輪詢分配。除非是設定為--interleave=nodes輪詢分配方式,即 記憶體可以在任意NUMA節點上分配這種方式以外。其他的方式就算其他NUMA節點上還有記憶體剩餘,Linux也不會把剩餘的記憶體分配給這個進程,而是採用 SWAP的方式來取得記憶體。有經驗的系統管理員或DBA都知道SWAP導致的資料庫效能下降有多坑爹。
所以最簡單的方法,還是關掉掉這個特性。
關閉特性的方法,分別有:可以從BIOS,作業系統,啟動行程時暫時關閉這個特性。
a)由於各種BIOS類型的區別,如何關閉NUMA千差萬別,我們這裡就不具體展示怎麼設定了。
b)在作業系統中關閉,可以直接在/etc/grub.conf的kernel行最後加入numa=off,如下所示:
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-root rd_NO_LUKS.UTF-8 rd_LVM_LV=VolGroup/root rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto rd_LVM_LV=VolGroup/swap rhgb crashkernel=auto quiet KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off
另外可以設定vm.zone_reclaim_mode=0盡量回收內存。
c)啟動MySQL的時候,關閉NUMA特性:
numactl --interleave=all mysqld &
當然,最好的方式是在BIOS中關閉。
ii)我們再看vm.swappiness。
vm.swappiness是作業系統控制實體記憶體交換出去的策略。它允許的值是一個百分比的值,最小為0,最大運行100,該值預設為60。 vm.swappiness設定為0表示盡量少swap,100表示盡量將inactive的記憶體頁交換出去。
具體的說:當記憶體基本上用滿的時候,系統會根據這個參數來判斷是把記憶體中很少用到的inactive 記憶體交換出去,還是釋放資料的cache。 cache緩存著從磁碟讀出來的數據,根據程式的局部性原理,這些數據有可能在接下來又要被讀取;inactive 內存顧名思義,就是那些被應用程式映射著,但是「長時間」不用的內存。
我們可以利用vmstat看到inactive的記憶體的數量:
#vmstat -an 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free inact active si so bi bo in cs us sy id wa st 1 0 0 27522384 326928 1704644 0 0 0 153 11 10 0 0 100 0 0 0 0 0 27523300 326936 1704164 0 0 0 74 784 590 0 0 100 0 0 0 0 0 27523656 326936 1704692 0 0 8 8 439 1686 0 0 100 0 0 0 0 0 27524300 326916 1703412 0 0 4 52 198 262 0 0 100 0 0
透過/proc/meminfo 你可以看到更詳細的資訊:
#cat /proc/meminfo | grep -i inact Inactive: 326972 kB Inactive(anon): 248 kB Inactive(file): 326724 kB
这里我们对不活跃inactive内存进一步深入讨论。Linux中,内存可能处于三种状态:free,active和inactive。众所周 知,Linux Kernel在内部维护了很多LRU列表用来管理内存,比如LRU_INACTIVE_ANON, LRU_ACTIVE_ANON, LRU_INACTIVE_FILE , LRU_ACTIVE_FILE, LRU_UNEVICTABLE。其中LRU_INACTIVE_ANON, LRU_ACTIVE_ANON用来管理匿名页,LRU_INACTIVE_FILE , LRU_ACTIVE_FILE用来管理page caches页缓存。系统内核会根据内存页的访问情况,不定时的将活跃active内存被移到inactive列表中,这些inactive的内存可以被 交换到swap中去。
一般来说,MySQL,特别是InnoDB管理内存缓存,它占用的内存比较多,不经常访问的内存也会不少,这些内存如果被Linux错误的交换出去了,将 浪费很多CPU和IO资源。 InnoDB自己管理缓存,cache的文件数据来说占用了内存,对InnoDB几乎没有任何好处。
所以,我们在MySQL的服务器上最好设置vm.swappiness=0。
我们可以通过在sysctl.conf中添加一行:
echo "vm.swappiness = 0" >>/etc/sysctl.conf
并使用sysctl -p来使得该参数生效。
三、文件系统
最后,我们看一下文件系统的优化
i)我们建议在文件系统的mount参数上加上noatime,nobarrier两个选项。
用noatime mount的话,文件系统在程序访问对应的文件或者文件夹时,不会更新对应的access time。一般来说,Linux会给文件记录了三个时间,change time, modify time和access time。
我们可以通过stat来查看文件的三个时间:
stat libnids-1.16.tar.gz File: `libnids-1.16.tar.gz' Size: 72309 Blocks: 152 IO Block: 4096 regular file Device: 302h/770d Inode: 4113144 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access : 2008-05-27 15:13:03.000000000 +0800 Modify: 2004-03-10 12:25:09.000000000 +0800 Change: 2008-05-27 14:18:18.000000000 +0800
其中access time指文件最后一次被读取的时间,modify time指的是文件的文本内容最后发生变化的时间,change time指的是文件的inode最后发生变化(比如位置、用户属性、组属性等)的时间。一般来说,文件都是读多写少,而且我们也很少关心某一个文件最近什 么时间被访问了。
所以,我们建议采用noatime选项,这样文件系统不记录access time,避免浪费资源。
现在的很多文件系统会在数据提交时强制底层设备刷新cache,避免数据丢失,称之为write barriers。但是,其实我们数据库服务器底层存储设备要么采用RAID卡,RAID卡本身的电池可以掉电保护;要么采用Flash卡,它也有自我保 护机制,保证数据不会丢失。所以我们可以安全的使用nobarrier挂载文件系统。设置方法如下:
对于ext3, ext4和 reiserfs文件系统可以在mount时指定barrier=0;对于xfs可以指定nobarrier选项。
ii)文件系统上还有一个提高IO的优化*,那就是deadline。
在Flash技术之前,我们都是使用机械磁盘存储数据的,机械磁盘的寻道时间是影响它速度的最重要因素,直接导致它的每秒可做的IO(IOPS)非常有 限,为了尽量排序和合并多个请求,以达到一次寻道能够满足多次IO请求的目的,Linux文件系统设计了多种IO调度策略,已适用各种场景和存储设备。
Linux的IO调度策略包括:Deadline scheduler,Anticipatory scheduler,Completely Fair Queuing(CFQ),NOOP。每种调度策略的详细调度方式我们这里不详细描述,这里我们主要介绍CFQ和Deadline,CFQ是Linux内 核2.6.18之后的默认调度策略,它声称对每一个 IO 请求都是公平的,这种调度策略对大部分应用都是适用的。但是如果数据库有两个请求,一个请求3次IO,一个请求10000次IO,由于绝对公平,3次IO 的这个请求都需要跟其他10000个IO请求竞争,可能要等待上千个IO完成才能返回,导致它的响应时间非常慢。并且如果在处理的过程中,又有很多IO请 求陆续发送过来,部分IO请求甚至可能一直无法得到调度被“饿死”。而deadline兼顾到一个请求不会在队列中等待太久导致饿死,对数据库这种应用来 说更加适用。
实时设置,我们可以通过
echo deadline >/sys/block/sda/queue/scheduler
来将sda的调度策略设置为deadline。
我们也可以直接在/etc/grub.conf的kernel行最后添加elevator=deadline来永久生效。
总结
CPU方面
关闭电源保护模式
内存:
vm.swappiness = 0
关闭numa
文件系统:
用noatime,nobarrier挂载系统
IO调度策略修改为deadline。
MySQL优化的方式很多,优化之后你的工作效率也会大大的提升,希望本文对你有用。
相关推荐:
#以上是linux上優化mysql技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!