程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 【mysql】關於硬件方面的一些優化,mysql硬件優化

【mysql】關於硬件方面的一些優化,mysql硬件優化

編輯:MySQL綜合教程

【mysql】關於硬件方面的一些優化,mysql硬件優化


一、CPU最大性能模式

cpu利用特點

  • 5.1 最高可用4個核

  • 5.5 最高可用24核

  • 5.6 最高可用64核心

  • 一次query對應一個邏輯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和操作系統中設置

二、關閉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盡量回收內存

三、關閉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

四、文件系統

建議在文件系統的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來永久生效

五、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,這樣存在掉電後丟失數據的風險。

六、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:打開寫入合並,提升寫磁盤的性能

七、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特性。

 

參考文檔: 

http://www.gentoo-wiki.info/FAQ_Linux_Memory_Management
http://bbs.gfan.com/android-4165836-1-1.html
https://wiki.archlinux.org/index.php/CPU_Frequency_Scaling_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
http://www.mysqlperformanceblog.com/2013/12/07/linux-performance-tuning-tips-mysql/
http://www.woqutech.com/?p=1200
http://mp.weixin.qq.com/s?__biz=MjM5NTg2NTU0Ng==&mid=210459025&idx=5&sn=d4c6f199b3e95b456e1cf5dd672d2e4c&scene=0#rd
http://mp.weixin.qq.com/s?__biz=MjM5NDE0MjI4MA==&mid=208777870&idx=1&sn=6efddd6283e4deb3fe55a141b0db965c&scene=1&srcid=0910kYIbazQSBqZEivwahGHB&key=dffc561732c2265104613d6540d35b8ad5c92c340ed903cbbd8218ac9ba70f5b9d36aaa09033e2f9cf0e7983792311d4&ascene=1&uin=MjM2NjkwNQ%3D%3D&devicetype=Windows+7&version=61020020&pass_ticket=JuXI39h6lA0f0sHQ0AFMc7g2Z4NJXU5U71301BBDAuw%3D
http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209406532&idx=1&sn=2e9b0cc02bdd4a02f7fd81fb2a7d78e3&scene=2&srcid=0922i4nYMVx1lj8Qsr2aVok3&from=timeline&isappinstalled=0#wechat_redirect
http://imysql.com/2015/05/24/mysql-optimization-reference-1.shtml
http://www.hellodb.net/2011/07/mysql-linux-hardware-tuning.html
http://www.hellodb.net/2011/06/mysql_multi_instance.html
http://blog.csdn.net/zjmzs/article/details/6046075

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved