1、硬件層相關優化
1.1、CPU相關
在服務器的BIOS設置中,可調整下面的幾個配置,目的是發揮CPU最大性能,或者避免經典的NUMA問題(Non-Uniform Memory Access,所以使用NUMA的模式如果能盡量保證本node內的CPU只訪問本node內的內存塊,那這樣的效率就是最高的。):
1、選擇PerformancePer Watt Optimized(DAPC)模式,發揮CPU最大性能,跑DB這種通常需要高運算量的服務就不要考慮節電了;
2、關閉C1E和C States等選項,目的也是為了提升CPU效率;
3、MemoryFrequency(內存頻率)選擇Maximum Performance(最佳性能);
4、內存設置菜單中,啟用Node Interleaving,避免NUMA問題;
1.2、磁盤I/O相關
下面幾個是按照IOPS(IOPS (Input/OutputOperations Per Second),即每秒進行讀寫(I/O)操作的次數,多用於數據庫等場合,衡量隨機訪問的性能。)性能提升的幅度排序,對於磁盤I/O可優化的一些措施:
1、使用SSD或者PCIe SSD設備,至少獲得數百倍甚至萬倍的IOPS提升;
2、購置陣列卡同時配備CACHE及BBU模塊,可明顯提升IOPS(主要是指機械盤,SSD或PCIe SSD除外。同時需要定期檢查CACHE及BBU模塊的健康狀況,確保意外時不至於丟失數據);
3、有陣列卡時,設置陣列寫策略為WB,甚至FORCE WB(若有雙電保護,或對數據安全性要求不是特別高的話),嚴禁使用WT策略。並且閉陣列預讀策略,基本上是雞肋,用處不大;(如果數據直接寫磁盤,就叫做直寫,也就是write through;如果數據先寫到陣列卡的cache,這叫做回寫,也就是write back)
4、盡可能選用RAID-10,而非RAID-5;(磁盤陣列(Redundant Arrays of Independent Disks,RAID))
5、使用機械盤的話,盡可能選擇高轉速的,例如選用15KRPM,而不是7.2KRPM的盤,不差幾個錢的;
6更多的磁盤空間等於更高的速度。
7磁盤速度越快越好。
2、系統層相關優化
2.1、文件系統層優化
在文件系統層,下面幾個措施可明顯提升IOPS性能:
1、使用deadline/noop這兩種I/O調度器,千萬別用cfq(它不適合跑DB類服務);
2、使用xfs文件系統,千萬別用ext3;ext4勉強可用,但業務量很大的話,則一定要用xfs;(使用 XFS文件系統 — 一個比ext3更快的、更小的文件系統,擁有更多的日志選項,同時,MySQL在ext3上存在雙緩沖區的問題。)
3、文件系統mount參數中增加:noatime, nodiratime, nobarrier幾個選項(nobarrier是xfs文件系統特有的);
2.2、其他內核參數優化
針對關鍵內核參數設定合適的值,目的是為了減少swap的傾向,並且讓內存和磁盤I/O不會出現大幅波動,導致瞬間波峰負載:
1、將vm.swappiness設置為5-10左右即可,甚至設置為0(RHEL 7以上則慎重設置為0,除非你允許OOM kill發生),以降低使用SWAP的機會;
2、將vm.dirty_background_ratio設置為5-10,將vm.dirty_ratio設置為它的兩倍左右,以確保能持續將臟數據刷新到磁盤,避免瞬間I/O寫,產生嚴重等待(和MySQL中的innodb_max_dirty_pages_pct類似);
3、將net.ipv4.tcp_tw_recycle、net.ipv4.tcp_tw_reuse都設置為1,減少TIME_WAIT,提高TCP效率;
4、至於網傳的read_ahead_kb、nr_requests這兩個參數,我經過測試后,發現對讀寫混合為主的OLTP環境影響並不大(應該是對讀敏感的場景更有效果),不過沒准是我測試方法有問題,可自行斟酌是否調整;
其他:
1、有足夠的物理內存,能將整個InnoDB文件加載到內存里 —— 如果訪問的文件在內存里,而不是在磁盤上,InnoDB會快很多。
2、全力避免 Swap 操作 — 交換(swapping)是從磁盤讀取數據,所以會很慢。
3、將你的操作系統和數據分開,不僅僅是邏輯上要分開,物理上也要分開— 操作系統的讀寫開銷會影響數據庫的性能。
4、將臨時文件和復制日志與數據文件分開— 后台的寫操作影響數據庫從磁盤文件的讀寫操作
5、使用 64位操作系統 — 有更多的內存能用於尋址和 MySQL 使用。
6、將不用的包和后台程序從服務器上刪除 — 減少資源占用。
7、將使用 MySQL的 host 和 MySQL自身的 host 都配置在一個 host 文件中 — 這樣沒有 DNS 查找。
8、永遠不要強制殺死一個MySQL進程 — 你將損壞數據庫,並運行備份。
9、讓你的服務器只服務於MySQL— 后台處理程序和其他服務會占用數據庫的 CPU 時間。