1、CPU最大性能模式
cpu利用特色
-
5.1 最高可用4個核node
-
5.5 最高可用24核mysql
-
5.6 最高可用64核心算法
-
一次query對應一個邏輯CPUsql
你仔細檢查的話,有些服務器上會有的一個有趣的現象:你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和操做系統中設置bash
2、關閉numa
非一致存儲訪問結構 (NUMA : Non-Uniform Memory Access) 也是最新的內存管理技術。它和對稱多處理器結構 (SMP : Symmetric Multi-Processor) 是對應的。簡單的隊別如圖:服務器
可是咱們能夠直觀的看到:SMP訪問內存的都是代價都是同樣的;可是在NUMA架構下,本地內存的訪問和非本地內存的訪問代價是不同的。對應的根據這個特性,操做系統上,咱們能夠設置進程的內存分配方式。目前支持的方式包括:架構
--interleave=nodes --membind=nodes --cpunodebind=nodes --physcpubind=cpus --localalloc --preferred=node
簡而言之,就是說,你能夠指定內存在本地分配,在某幾個CPU節點分配或者輪詢分配。除非是設置爲--interleave=nodes輪詢分配方式,即內存能夠在任意NUMA節點上分配這種方式之外。
其餘的方式就算其餘NUMA節點上還有內存剩餘,Linux也不會把剩餘的內存分配給這個進程,而是採用SWAP的方式來得到內存。有經驗的系統管理員或者DBA都知道SWAP致使的數據庫性能降低 ,因此最簡單的方法,仍是關閉掉這個特性
關閉特性的方法,分別有:
-
能夠從BIOS設置關閉
-
啓動MySQL的時候,關閉NUMA特性 numactl --interleave=all mysqld &
-
OS內核,啓動時設置numa=off
-
在操做系統中關閉,能夠直接在/etc/grub.conf的kernel行最後添加numa=off,以下所示
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-root rd_NO_LUKS LANG=en_US.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儘可能回收內存
3、關閉vm.swappiness
vm.swappiness是操做系統控制物理內存交換出去的策略。它容許的值是一個百分比的值,最小爲0,最大運行100,該值默認爲60
vm.swappiness設置爲0表示儘可能少swap,100表示儘可能將inactive的內存頁交換出去。
當內存基本用滿的時候,系統會根據這個參數來判斷是把內存中不多用到的inactive 內存交換出去,仍是釋放數據的cache。cache中緩存着從磁盤讀出來的數據,根據程序的局部性原理,這些數據有可能在接下來又要被讀取;inactive 內存顧名思義,就是那些被應用程序映射着,可是「長時間」不用的內存。
咱們能夠查看inactive的內存的數量:
[root@locahost ~]# 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 0 0 61432 1533944 1553788 3190400 0 0 9 216 0 0 5 2 88 4 0 0 0 61432 1533564 1553900 3190568 0 0 0 120 616 349 2 1 97 1 0 1 0 61432 1533068 1553844 3191096 0 0 0 5748 1604 455 1 1 95 3 0 2 1 61432 1531952 1553812 3191984 0 0 172 700 1033 416 2 1 74 23 0 [root@locahost ~]# cat /proc/meminfo | grep -i inact Inactive: 1557236 kB Inactive(anon): 279888 kB Inactive(file): 1277348 kB
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
4、文件系統
建議在文件系統的mount參數上加上noatime,nobarrier兩個選項
用noatime mount的話,文件系統在程序訪問對應的文件或者文件夾時,不會更新對應的access time。通常來講,Linux會給文件記錄了三個時間,change time, modify time和access time。
咱們能夠經過stat來查看文件的三個時間:
[root@localhost ~]# stat mysql-test.sh File: `mysql-test.sh' Size: 970 Blocks: 8 IO Block: 4096 regular file Device: ca01h/51713d Inode: 33883111 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2015-12-16 19:55:58.962535495 +0800 Modify: 2015-12-11 09:15:38.410196493 +0800 Change: 2015-12-11 09:15:38.493196460 +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選項
文件系統上還有一個提升IO的優化萬能鑰匙,那就是deadline
在Flash技術以前,咱們都是使用機械磁盤存儲數據的,機械磁盤的尋道時間是影響它速度的最重要因素,直接致使它的每秒可作的IO(IOPS)很是有限,爲了儘可能排序和合並多個請求,以達到一次尋道可以知足屢次IO請求的目的,Linux文件系統設計了多種IO調度策略,已適用各類場景和存儲設備。
Linux的IO調度策略包括:Deadline scheduler,Anticipatory scheduler,Completely Fair Queuing(CFQ),NOOP
CFQ是Linux內核2.6.18以後的默認調度策略,它聲稱對每個 IO 請求都是公平的,這種調度策略對大部分應用都是適用的。可是若是數據庫有兩個請求,一個請求3次IO,一個請求10000次IO,因爲絕對公平,3次IO的這個請求都須要跟其餘10000個IO請求競爭,可能要等待上千個IO完成才能返回,致使它的響應時間很是慢。而且若是在處理的過程當中,又有不少IO請求陸續發送過來,部分IO請求甚至可能一直沒法獲得調度被「餓死」。而deadline兼顧到一個請求不會在隊列中等待過久致使餓死,對數據庫這種應用來講更加適用
CFQ與Deadline,NOOP性能差別很小,可是一旦有大的連續IO,CFQ可能會形成小IO的響應延時增長,因此數據庫環境建議修改成deadline算法,表現更穩定。咱們的環境統一使用deadline算法。
IO調度算法都是基於磁盤設計,因此減小磁頭移動是最重要的考慮因素之一,可是使用Flash存儲設備以後,再也不須要考慮磁頭移動的問題,可使用NOOP算法。NOOP的含義就是NonOperation,意味着不會作任何的IO優化,徹底按照請求來FIFO的方式來處理IO。
減小預讀:/sys/block/sdb/queue/read_ahead_kb,默認128,調整爲16
增大隊列:/sys/block/sdb/queue/nr_requests,默認128,調整爲512
實時設置,咱們能夠經過
echo deadline >/sys/block/sda/queue/scheduler
咱們也能夠直接在/etc/grub.conf的kernel行最後添加elevator=deadline來永久生效
5、RAID優化
關閉讀cache:RAID卡上的cache容量有限,咱們選擇direct方式讀取數據,從而忽略讀cache。
關閉預讀:RAID卡的預讀功能對於隨機IO幾乎沒有任何提高,因此將預讀功能關閉。
關閉磁盤cache:通常狀況下,若是使用RAID,系統會默認關閉磁盤的cache,也能夠用命令強制關閉。
以上設置均可以經過RAID卡的命令行來完成
開啓BBWC
RAID卡都有寫cache(Battery Backed Write Cache),寫cache對IO性能的提高很是明顯,由於掉電會丟失數據,因此必須由電池提供支持。電池會按期充放電,通常爲90天左右,當發現電量低於某個閥值時,會將寫cache策略從writeback置爲writethrough,至關於寫cache會失效,這時若是系統有大量的IO操做,可能會明顯感受到IO響應速度變慢。目前,新的RAID卡內置了flash存儲,掉電後會將寫cache的數據寫入flash中,這樣就能夠保證數據永不丟失,但依然須要電池的支持。
解決方案有兩種:1.人工觸發充放電,能夠選擇在業務低谷時作,下降對應用的影響;2.設置寫cache策略爲force write back,即便電池失效,也保持寫cache策略爲writeback,這樣存在掉電後丟失數據的風險。
6、Flashcache
建立flashcache:flashcache_create -b 4k cachedev /dev/sdc /dev/sdb
指定flashcache的block大小與Percona的page大小相同。
Flashcache參數設置:
flashcache.fast_remove = 1:打開fast remove特性,關閉機器時,無需將cache中的髒塊寫入磁盤 flashcache.reclaim_policy = 1:髒塊刷出策略,0:FIFO,1:LRU flashcache.dirty_thresh_pct = 90:flashcache上每一個hash set上的髒塊閥值 flashcache.cache_all = 1:cache全部內容,能夠用黑名單過濾 flashecache.write_merge = 1:打開寫入合併,提高寫磁盤的性能
7、IOPS
磁盤尋道能力(磁盤I/O),以目前高轉速SCSI硬盤(7200轉/秒)爲例,這種硬盤理論上每秒尋道7200次,這是物理特性決定的,沒有辦法改變。 MySQL每秒鐘都在進行大量、複雜的查詢操做,對磁盤的讀寫量可想而知。因此,一般認爲磁盤I/O是制約MySQL性能的最大因素之一,對於日均訪問量 在100萬PV以上的Discuz!論壇,因爲磁盤I/O的制約,MySQL的性能會很是低下!解決這一制約因素能夠考慮如下幾種解決方案: 使用RAID-0+1磁盤陣列,注意不要嘗試使用RAID-5,MySQL在RAID-5磁盤陣列上的效率不會像你期待的那樣快
innodb_page_size:若是使用fusionio,4K的性能最好;使用SAS磁盤,設置爲8K。若是全表掃描不少,能夠設置爲16K。比較小的page size,能夠提高cache的命中率。 innodb_adaptive_checkpoint:若是使用fusionio,設置爲3,提升刷新頻率到0.1秒;使用SAS磁盤,設置爲2,採用estimate方式刷新髒頁。 innodb_io_capacity:根據IOPS能力設置,使用fuionio能夠設置10000以上。 innodb_flush_neighbor_pages = 0:針對fusionio或者SSD,由於隨機IO足夠好,因此關閉此功能。 innodb_flush_method=ALL_O_DIRECT:公版的MySQL只能將數據庫文件讀寫設置爲DirectIO,對於Percona能夠將log和數據文件設置爲direct方式讀寫。可是我不肯定這個參數對於innodb_flush_log_at_trx_commit的影響, innodb_read_io_threads = 1:設置預讀線程設置爲1,由於線性預讀的效果並不明顯,因此無需設置更大。 innodb_write_io_threads = 16:設置寫線程數量爲16,提高寫的能力。 innodb_fast_checksum = 1:開啓Fast checksum特性。