數據庫優化之降龍十八掌

   

技術老鐵們,工做累了,咱們就一塊兒來放鬆一下!老張我呢是個金庸迷,在金庸小說中,降龍十八掌無愧巔峯外功,它的威力之大可想而知。而今兒,老張要給你們介紹18招式,來優化咱們的 MySQL 數據庫,讓它跑起來更快,更穩定!mysql


以前老有學生問我,張老師該如何優化咱們的 MySQL 數據庫呢?這個問題太泛泛了,不是很具體!由於數據庫的優化要從多個角度去考慮,經過不一樣的維度模型去排查問題。老師整理了下思路,大概能夠從18個角度,大體四個方向去給你們一些建議。linux


第一掌----亢龍有悔web

要想保證數據庫可以高效,穩定地運行在服務器上面,咱們首先要保證有充足的內存,只有內存足夠大了,咱們才能緩存住那些咱們常常訪問的熱數據,一些 update 語句的操做固然也能夠在內存中優先完成。可是咱們要考慮內存使用黃金分割法則,因爲不一樣業務的存在,對內存的需求固然也就不同了。sql

舉個列子來講,用戶常常訪問的熱數據,對於內存的分配就要儘量達到達到數據庫內存的 70-80% 左右。衆所周知,咱們知道 MySQL 數據庫內存主要靠 innodb_buffer_pool,redo log buffer,double write buffer,binlog cache 等組成。若是服務器上面只跑着 MySQL 一個應用,那大概 innodb_buffer_pool 能夠分配到物理內存的 50-80% 左右。mongodb

TIPS:咱們要根據實際物理內存的大小,具體是什麼業務類型,去考慮數據庫內存的分配。數據庫


第二掌----飛龍在天windows

要優化 MySQL 數據庫,首先要很瞭解對手,隨着版本的升級,MySQL 用到的 CPU 核數就越多,自從 MySQL 5.6 以後可使用到 64 個核。MySQL 鏈接特色的是這樣,每一個鏈接對應一個線程,每一個 sql/ 查詢只能使用到一個 cpu 核心,因此須要越多的 CPU,而且更快的 CPU。這樣纔能有利於提升數據庫性能,提升咱們數據庫的併發能力!緩存

TIPS:使用多核 CPU。
安全


第三掌----見龍在田服務器

衆所周知,IO 對數據庫來講,一直都是瓶頸,而且有可能未來一段時間還會是。因此對存儲介質的要求就很是高,對於 IO 系統比較高的狀況下,建議咱們要使用更快的存儲設備 SSD 固態硬盤可提升上百倍的數據讀寫性能或者是 PCIE-SSD 固態硬盤可提升上千倍的數據讀寫能力。像如今的一些電商網站,在搞店慶或者促銷活動的時候,都須要藉助此設備,來知足大量用戶的影響請求。

TIPS:建議上高轉速硬件設備,SSD 或者 PCIE-SSD


第四掌----鴻漸於陸

自從 web2.0 時×××啓,基本全部的,咱們使用的軟件都是基於 linux 平臺自主研發的。咱們知道,MySQL 數據庫也是跑在 linux 操做系統上面的。在官方建議估計最推薦的是 Solaris,但從實際生產中的角度來看 CentOS 和 REHL 都是不錯的選擇,我的建議推薦使用 CentOS, 若是非要使用 REHL,建議 版本爲6之後的,這裏就不推薦使用在 windows 下跑 MySQL 數據庫了,雖然隨着 MySQL 版本提高,對 windows 有了相關的優化,可是對於高併發,高負載的環境來講,依舊不建議使用。

TIPS:推薦使用 CentOS,或者 REHL 操做系統類型


第五掌----潛龍勿用

操做系統層面的優化,咱們要考慮個可能你們會比較忽略的問題,首先就是 swappiness 的問題。swappiness 的值大小對如何使用 swap 分區有着密切的聯繫。有兩個極限值,一個爲 0,另外一個爲 100,查看可執行 cat /proc/sys/vm/swappiness。

0 表明:最大限度地使用物理內存,而後纔是 swap 分區,這種行爲有可能致使系統內存溢出,從而致使mysql被意外kill掉。不建議這樣去設置。

100則爲:積極地使用使用 swap 分區,而且把內存上面的數據及時搬到 swap 分區裏。

TIPS:這裏比較建議使用默認 60 就能夠。


第六掌----利涉大川

與 swappiness 對應的,另外一個操做系統層面的優化,還有一個小細節點就是 IO 調度。這裏有 cfq,noop 和 deadline,系統默認使用 cfq,這裏老師建議使用 deadline。查看方法:

cat /sys/block/sda/queue/scheduler/ 

TIPS:deadline 能夠調整讀寫時間,避免寫完沒有被讀取的餓死場景。


第七掌----突如其來

Oracle 11g 以後多了一個 result_cache,來緩存數據結果集。MySQL 裏面經過 innodb_buffer_pool 裏面有個 query cache 來緩存靜態結果集。咱們都但願熱數據都保存在內存裏面,咱們讀取數據快速便捷,數據庫的緩存率也很高!但數據庫中的 query cache 裏面的數據一但發生更改,此緩存區毫無心義,就會變成雞肋。並且若是開啓 Query Cache,更新與寫入都要去檢查 query cache 反而增長了寫入的開銷。

TIPS:建議關閉 query cache


第八掌----震驚百里

對於磁盤陣列,咱們再熟悉不過了,可是對於陣列卡的 cache 策略,咱們又該如何選擇呢。首先對於qps,tps,業務高的系統,必定要配置陣列卡,配 cache 模塊,和 BBU 模塊(用於提供後備電量)。

cache 策略有兩種,一種爲:write through(WT);另外一種爲:write back;

我的強烈建議使用 write back(WB)。WT含義,數據直接寫入磁盤,WB含義:數據先寫陣列卡的cache,再由cache寫入磁盤,這樣對於寫入的性能有所提升。而且對於加速redo log ,binlog, data file都有好處。

TIPS:強烈建議陣列卡的 cache 策略使用 write back。


第九掌----或躍在淵

前面也涉及到了,儘量大的給 innodb_buffer_pool 分配空間,在服務器只跑數據庫一個應用前提下大概爲物理內存 50-80%。

TIPS:建議應用與數據庫分開部署在服務器上面,後期好排查問題。


第十掌----雙龍取水

MySQL 數據庫的一些核心參數,咱們要在內心銘記。好比雙一的含義,直接影響日誌的刷新機制。影響redo log buffer 的刷新機制

innodb_flush_log_at_trx_commit  = 1(最安全)

innodb_flush_log_at_trx_commit  = 2 (性能通常)

innodb_flush_log_at_trx_commit  = 0 (性能最好)。

影響binlog cache的刷新機制~sync_binlog=0,當事務提交以後,MySQL 不作 fsync 之類的磁盤同步指令刷新 binlog_cache 中的信息到磁盤,而讓 Filesystem 自行決定何時來作同步,或者 cache滿了以後才同步到磁盤。sync_binlog=n當每進行 n 次事務提交以後,MySQL 將進行一次 fsync 之類的磁盤同步指令來將 binlog_cache 中的數據強制寫入磁盤。爲了確保安全性,咱們能夠將sync_binlog=1。爲了得到最佳性能咱們能夠將sync_binlog=0。

TIPS:對於不一樣業務的公司,保障的點不同,全部咱們要考慮好,是業務最重要,仍是數據最重要!而後分別去設置不一樣的參數value


第十一掌----魚躍於淵

MySQL 數據庫區別於其餘數據庫最主要就是插件式存儲引擎,最爲著名就是 myisam 還有 innodb。它們都有各自的特色,這裏強烈建議使用 innodb 存儲引擎表,不管是對於事務的支持,仍是在線 DDL 語句快速操做,它都是目前最優秀的存儲引擎!MySQL 5.5 以後默認使用的存儲引擎都是 innodb

TIPS:生產環境中,若是還有 myisam 這種存儲引擎的表,建議所有作 myisam-->innodb 存儲引擎的轉換!不過 MySQL 5.7以後,系統表也都是 innodb 了!


第十二掌----時乘六龍

文件系統強烈推薦使用 xfs,不要再使用 ext3,ext4 之類的,由於 xfs 這種文件系統也是 B-tree 結構最接近於數據庫的樹狀結構。


第十三掌----密雲不雨

生產環境中,常常會出現對大表進行 delete,或者 update 這類的操做。數據碎片隨之產生,咱們要常常去整理主要業務表的碎片,讓查詢檢索更快。能夠經過 pt-ioprofile 監控與磁盤交互最爲緊密的表,而後經過 alter table 或者導入導出數據的方法對錶進行碎片整理。儘量回收表空間


第十四掌----損則有孚

利用天兔(lepus)或者 zabbix 作好對數據庫的監控。監控事項能夠從服務器的狀態,內存的使用狀況,cpu的負載。數據庫中每秒的增刪改查信息,架構中的延遲和複製狀態信息去做爲監控的核心點。


第十五掌----龍戰於野

配合開發人員合理地設計表結構,秉着越簡單越好的原則,去選擇合適字段的數據類型。對於ipv4,時間類型的字段,咱們徹底能夠經過整型int來存取!經過函數轉換就能夠了!

ip涉及到兩個函數:inet_aton和inet_ntoa

時間類型的兩個函數:from_unixtime和unix_timestamp

第十六掌----事務隔離級別的選擇

mysql數據庫中,有四種事務隔離級別。它們分別是Read Uncommitted(RU),Read Committed(RC),Repeatable Read(RR)Serializable(SR)。對於交易類型系統的網站,對於事務要求比較高,咱們建議使用RR這種隔離級別。


第十七掌----羝羊觸藩

更改文件句柄  ulimit –n 默認1024 過小

進程數限制  ulimit –u   根據不一樣版原本決定

禁掉NUMA  numctl –interleave=all


第十八掌----神龍擺尾

作過數據庫的同窗們,能夠常常會遇到too many connections這樣的問題,對於這樣的問題,咱們必定要作好配置數據庫內部併發的狀況。innodb_thread_concurrency 這個參數來決定innodb的併發狀況。默認的大小是0。在mysql5.7版本中,增長了thread pool,鏈接複用的存在,能夠取默認值就ok。可是5.7以前的版本,就須要考量一下取值了,我的建議mysql5.6版本中設置爲36。mysql5.6以前能夠8-32。


降龍十八掌已經打完,但願對於數據庫愛好者,從事數據庫工做中的同窗來講有幫助。讓咱們天天學習一點點,把本身的內功練得愈來愈深厚,打出屬於本身的武功。讓咱們的數據庫飛起來!


本文出自 「張甦的博客」 博客,請務必保留此出處http://sumongodb.blog.51cto.com/4979448/1949024

相關文章
相關標籤/搜索