總結的一些MySQL數據庫優化技巧

一個成熟的數據庫架構並非一開始設計就具有高可用、高伸縮等特性的,它是隨着用戶量的增長,基礎架構才逐漸完善。這篇文章主要談談MySQL數據庫在發展週期中所面臨的問題及優化方案,暫且拋開前端應用不說,大體分爲如下五個階段:前端

階段一:數據庫表設計

項目立項後,開發部門根據產品部門需求開發項目。
開發工程師在開發項目初期會對錶結構設計。對於數據庫來講,表結構設計很重要,若是設計不當,會直接影響到用戶訪問網站速度,用戶體驗很差!這種狀況具體影響因素有不少,例如慢查詢(低效的查詢語句)、沒有適當創建索引、數據庫堵塞(鎖)等。固然,有測試部門的團隊,會作產品測試,找Bug。
因爲開發工程師重視點不一樣,初期不會考慮太多數據庫設計是否合理,而是儘快完成功能實現和交付。等項目上線有必定訪問量後,隱藏的問題就會暴露,這時再去修改就不是這麼容易的事了!mysql

階段二:數據庫部署

是時候運維工程師出場了,項目上線。
項目初期訪問量通常是寥寥無幾,此階段Web+數據庫單臺部署足以應對在1000左右的QPS(每秒查詢率)。考慮到單點故障,應作到高可用性,可採用MySQL主從複製+Keepalived實現雙機熱備。主流HA軟件有:Keepalived(推薦)、Heartbeat。linux

階段三:數據庫性能優化

若是將MySQL部署到普通的X86服務器上,在不通過任何優化狀況下,MySQL理論值正常能夠處理1500左右QPS,通過優化後,有可能會提高到2000左右QPS。不然,訪問量當達到1500左右併發鏈接時,數據庫處理性能可能響應就會慢,並且硬件資源還比較富裕,這時就該考慮性能優化問題了。那麼怎樣能讓數據庫發揮最大性能呢?主要從硬件配置、數據庫配置、架構方面着手,具體分爲如下:web

3.1 硬件配置

若是有條件必定要SSD固態硬盤代替SAS機械硬盤,將RAID級別調整爲RAID1+0,相對於RAID1和RAID5有更好的讀寫性能,畢竟數據庫的壓力主要來自磁盤I/O方面。
Linux內核有一個特性,會從物理內存中劃分出緩存區(系統緩存和數據緩存)來存放熱數據,經過文件系統延遲寫入機制,等知足條件時(如緩存區大小到達必定百分比或者執行sync命令)纔會同步到磁盤。也就是說物理內存越大,分配緩存區越大,緩存數據越多。固然,服務器故障會丟失必定的緩存數據。建議物理內存至少富裕50%以上。redis

3.2 數據庫配置優化

MySQL應用最普遍的有兩種存儲引擎:一個是MyISAM,不支持事務處理,讀性能處理快,表級別鎖。另外一個是InnoDB,支持事務處理(ACID屬性),設計目標是爲大數據處理,行級別鎖。
表鎖:開銷小,鎖定粒度大,發生死鎖機率高,相對併發也低。
行鎖:開銷大,鎖定粒度小,發生死鎖機率低,相對併發也高。
爲何會出現表鎖和行鎖呢?主要爲保證數據完整性。舉個例子,一個用戶在操做一張表,其餘用戶也想操做這張表,那麼就要等第一個用戶操做完,其餘用戶才能操做,表鎖和行鎖就是這個做用。不然多個用戶同時操做一張表,確定會數據產生衝突或者異常。
根據這些方面看,使用InnoDB存儲引擎是最好的選擇,也是MySQL5.5+版本默認存儲引擎。每一個存儲引擎相關運行參數比較多,如下列出可能影響數據庫性能的參數。
公共參數默認值:算法


MyISAM參數默認值:sql


InnoDB參數默認值:數據庫


3.3 系統內核參數優化

大多數MySQL都部署在linux系統上,因此操做系統的一些參數也會影響到MySQL性能,如下對Linux內核參數進行適當優化緩存


階段四:數據庫架構擴展

隨着業務量愈來愈大,單臺數據庫服務器性能已沒法知足業務需求,該考慮增長服務器擴展架構了。主要思想是分解單臺數據庫負載,突破磁盤I/O性能,熱數據存放緩存中,下降磁盤I/O訪問頻率。性能優化

4.1 增長緩存

給數據庫增長緩存系統,把熱數據緩存到內存中,若是緩存中有請求的數據就再也不去請求MySQL,減小數據庫負載。緩存實現有本地緩存和分佈式緩存,本地緩存是將數據緩存到本地服務器內存中或者文件中。分佈式緩存能夠緩存海量數據,擴展性好,主流的分佈式緩存系統:memcached、redis,memcached性能穩定,數據緩存在內存中,速度很快,QPS理論可達8w左右。若是想數據持久化就選擇用redis,性能不低於memcached。
工做過程:

4.2 主從複製與讀寫分離

在生產環境中,業務系統一般讀多寫少,可部署一主多從架構,主數據庫負責寫操做,並作雙機熱備,多臺從數據庫作負載均衡,負責讀操做。主流的負載均衡器:LVS、HAProxy、Nginx。
怎麼來實現讀寫分離呢?大多數企業是在代碼層面實現讀寫分離,效率高。另外一個種方式經過代理程序實現讀寫分離,企業中應用較少,會增長中間件消耗。主流中間件代理系統有MyCat、Atlas等。
在這種MySQL主從複製拓撲架構中,分散單臺負載,大大提升數據庫併發能力。若是一臺從服務器能處理1500 QPS,那麼3臺就能處理4500 QPS,並且容易橫向擴展。
有時,面對大量寫操做的應用時,單臺寫性能達不到業務需求。就能夠作雙向複製(雙主),但有個問題得注意:兩臺主服務器若是都對外提供讀寫操做,就可能遇到數據不一致現象,產生這個緣由是程序有同時操做兩臺數據庫概率,同時的更新操做會形成兩臺數據庫數據發生衝突或者不一致。
可設置每一個表ID字段自增惟一:auto_increment_increment和auto_increment_offset,也能夠寫算法生成隨機惟一。
官方近兩年推出的MGR(多主複製)集羣也能夠考慮下。

4.3 分庫

分庫是根據業務將數據庫中相關的表分離到不一樣的數據庫中,例如web、bbs、blog等庫。若是業務量很大,還可將分離後的數據庫作主從複製架構,進一步避免單庫壓力過大。

4.4 分表

數據量的日劇增長,數據庫中某個表有幾百萬條數據,致使查詢和插入耗時太長,怎麼能解決單表壓力呢?你應該考慮把這個表拆分紅多個小表,來減輕單個表的壓力,提升處理效率,此方式稱爲分表。
分表技術比較麻煩,要修改程序代碼裏的SQL語句,還要手動去建立其餘表,也能夠用merge存儲引擎實現分表,相對簡單許多。分表後,程序是對一個總表進行操做,這個總表不存放數據,只有一些分表的關係,以及更新數據的方式,總表會根據不一樣的查詢,將壓力分到不一樣的小表上,所以提升併發能力和磁盤I/O性能。
分表分爲垂直拆分和水平拆分:
垂直拆分:把原來的一個不少字段的表拆分多個表,解決表的寬度問題。你能夠把不經常使用的字段單獨放到一個表中,也能夠把大字段獨立放一個表中,或者把關聯密切的字段放一個表中。
水平拆分:把原來一個表拆分紅多個表,每一個表的結構都同樣,解決單表數據量大的問題。

4.5 分區

分區就是把一張表的數據根據表結構中的字段(如range、list、hash等)分紅多個區塊,這些區塊能夠在一個磁盤上,也能夠在不一樣的磁盤上,分區後,表面上仍是一張表,但數據散列在多個位置,這樣一來,多塊硬盤同時處理不一樣的請求,從而提升磁盤I/O讀寫性能。
注:增長緩存、分庫、分表和分區主要由程序猿或DBA來實現。

階段五:數據庫維護

數據庫維護是數據庫工程師或運維工程師的工做,包括系統監控、性能分析、性能調優、數據庫備份和恢復等主要工做。

5.1 性能狀態關鍵指標


5.2 開啓慢查詢日誌

MySQL開啓慢查詢日誌,分析出哪條SQL語句比較慢,支持動態開啓:

5.3 數據庫備份

備份數據庫是最基本的工做,也是最重要的,不然後果很嚴重,你懂得!高頻率的備份策略,選用一個穩定快速的工具相當重要。數據庫大小在2G之內,建議使用官方的邏輯備份工具mysqldump。超過2G以上,建議使用percona公司的物理備份工具xtrabackup,不然慢的跟蝸牛似得。這兩個工具都支持InnoDB存儲引擎下熱備,不影響業務讀寫操做。

5.4 數據庫修復

有時候MySQL服務器忽然斷電、異常關閉,會致使表損壞,沒法讀取表數據。這時就能夠用到MySQL自帶的兩個工具進行修復,myisamchk和mysqlcheck。前者只能修復MyISAM表,而且中止數據庫,後者MyISAM和InnoDB均可以,在線修復。
注意:修復前最好先備份數據庫。

5.5 MySQL服務器性能分析


重點關注:
id:CPU利用率百分比,平均小於60%正常,但已經比較繁忙了。
wa:CPU等待磁盤IO響應時間,通常大於5說明磁盤讀寫量大。

KB_read/s、KB_wrtn/s 每秒讀寫數據量,主要根據磁盤每秒最高讀寫速度評估。

r/s、w/s:每秒讀寫請求次數,能夠理解爲IOPS(每秒輸入輸出量),是衡量磁盤性能的主要指標之一。
await:IO平均每秒響應時間,通常大於5說明磁盤響應慢,超過自身性能。
util:磁盤利用率百分比,平均小於60%正常,但已經比較繁忙了。

小結

因爲關係型數據庫初衷設計限制,在大數據處理時會顯得力不從心。所以NoSQL(非關係型數據庫)火起來了,天生勵志,具有分佈式、高性能、高可靠等特性,彌補了關係型數據庫某方面先天性不足,很是適合存儲非結構化數據。主流NoSQL數據庫有:MongoDB、HBase、Cassandra等。

單純數據庫層面優化效果提高並很少明顯,主要仍是要根據業務場景選擇合適的數據庫!

相關文章
相關標籤/搜索