1. 程式人生 > >DBA很忙—MySQL的效能優化及自動化運維實踐

DBA很忙—MySQL的效能優化及自動化運維實踐


DBA的日常工作

首先,我們來看看DBA的具體工作,我覺得 DBA 真的很忙:備份和恢復、監控狀態、叢集搭建與擴容、資料遷移和高可用,這是我們 DBA 的功能。

瞭解這些功能以後要對體系結構有更加深入的瞭解,你不知道怎麼處理這些故障和投訴的事情。

所以我們要去了解快取/執行緒、SQL優化、儲存引擎以及SQL審計以及鎖與實務、體系結構更深一點,就去研究核心原理和原始碼定製,DBA有這麼多工作,他們就像一個小怪獸一樣等著我們去解決。

今天我站在更加全面的角度跟大家分享一下我覺得我在這一年多DBA工作當中的經驗,希望可以給大家帶來啟發和幫助。

1. MySQL的效能優化

效能優化就是我想讓我的MySQL跑的更快、更順暢。在我們開始MySQL效能優化之前,我想提出MySQL效能優化的三個關鍵點。Why?What?How?為什麼我們要做效能優化?

我們的運維來反映我們的資料庫,正常情況下是1秒,後來變成10秒,我們就要啟動優化的動作。原本他的訪問時間是1秒,我們想優化成0.01秒就要開啟優化。

第二就是What?哪裡是導致我們資料庫效能變差的原因一。需要找到這個關鍵點。當我們找到這個問題以後,我們就需要有的放矢地進行優化。MySQL優化之前我們要明確的3W關鍵點。

1.1 MySQL優化基本流程

其實對於開展MySQL的優化有這樣的一個基本流程。

第一步我們首先要登陸到作業系統,通過作業系統的命令,比如說作業系統的基本命令,去看我們作業系統有什麼資源的佔用率比較高,就是出現了資源短板,短板的意思就是這個資源的佔用率或者是使用率特別高,我們要密切關注。

比如說像CPU的負載特別高,已經超過了我們的核數,或者是使用率特別高,已經達到了80%以上,這就引起我們的關注了。

確定這個短板之後,我們就要確認哪個程序使用我們這個資源,使得它的使用率或者是佔用率特別高。

一般情況下跟我們相關就是MySQL這一層,比方說使用CPU的70%以上,我們就要去檢查一下這個 MySQL 出現什麼問題。

再進一步往裡推進,如果我們發現MySQL裡面是執行某一條大MySQL的時候,發現整個伺服器或者是整個資料庫就在那裡,可能就是語句問題。

我們就要進一步通過 MySQL 的監控或者是日誌資訊去排查MySQL的問題。這個是很重要的發現哪個資源出現問題然後進行排查。

我們登陸系統就不會發現有CPU、IO、網路等等都很正常。在這種情況下怎麼辦?在這種情況下可以分三種判斷。

可能我們登陸MySQL的時候整個系統就在那裡了,這個情況還是作業系統的問題,我們需要通過作業系統去查是哪個資源的問題。

第二就是資料庫例項問題,資料庫例項問題跟資料庫配置引數相關,也就是說我們配置引數可能存在一些不合理的設定需要我們去優化。

第三就是會話,我們登陸MySQL裡面,一開始很正常,後來我們發現這個例項慢下來了,可能就是MySQL語句有問題,我們需要看MySQL的執行計劃到具體哪一步比較慢,拖慢了整個流程。

我們發現數據庫效能出現問題,都可以沿著這個流程走下去,從而定位出問題。

1.2 優化的幾個關鍵點

我們通過剛才的基本流程,可以確定出 MySQL 需要優化的幾個關鍵點。

第一是應用訪問的優化,因為有應用需要訪問我們的資料庫,有請求的傳送、資料的儲存和網路的互動等等,會導致資料庫效能會發生比較慢的地方。

二是伺服器硬體選型,不知道大家DBA對伺服器有沒有自主權,如果有自主權的情況下,我是覺得我們應該按照 MySQL 的特性來選擇伺服器的硬體。

比方說我們可能要考慮到資料和日誌的儲存機理不同,要選擇不同的型別去優化它。

第三個就是作業系統的優化。就是我們部署配置資料庫之前,要對作業系統有什麼優化?能夠讓我們的資料庫有優化。

最後一個是資料庫優化。資料庫優化過程其實是一個全域性角度優化的過程,不僅僅是是針對資料庫本身優化的流程。

1.2.1 應用訪問優化

我們根據每個關鍵點稍微開展一下。比方說應用訪問的優化:

首先第一步就是減少資料的訪問。因為減少資料的訪問其實就是減少磁碟的訪問。我們知道資料訪問磁盤獲得資料的速度很慢,如果我們是器械磁碟,因為器械磁碟是通過器械旋轉來獲得資料。

我們應該把活躍資料和記憶體資料放在記憶體裡面,這樣可以使我們的資料庫效能提升1-1000倍。它的優化成本很低。

第二步是減少返回更多的資料,其實減少返回更多的資料終結就是減少了網路的傳輸,有很多大的系統,網路傳輸是一個很重要的瓶頸。

假設我們的資料庫伺服器跟我們應用伺服器的距離是20公里的話,因為光線資料庫是20公里,一個光的請求是0.2毫秒。如果我們減少更少的資料請求的話,那這個時間就會變短很多。所以說如果我們發現數據庫的效能有問題,我們可以去看是否網路上存在問題或者是通過P命令看時間是否會變得長。

第三是減少互動次數,每個互動假設還是按照20公里來說,一個互動的時間就是0.2毫秒,2個互動就是0.4毫秒。如果有1萬個操作的話,就是1萬乘0.4毫秒,那就變得整個互動時間變短了很多。

但是也有它的複雜性或者是不宜擴充套件的局面。從應用層就降低了優化。這個成本也是很低的。

伺服器硬體選型。我們公司的DBA對於伺服器的應用選型沒有太多的話語權,移動公司都是集團公司通過集採來選擇的。在採集的時候我們不可能規定這幾臺伺服器是用在資料庫,這幾個資料庫用在服務系統。

所以我們在選擇伺服器選型時候DBA是沒有辦法參與進去的。這個大家可以看一下,我們採用的伺服器是惠普的DL360G9,CPU:是2核×e5-2650V4,記憶體是8×32G,硬碟是6×1.2TSAS,網絡卡是4×10GE+4×1GE+1IPMI。這是我們移動雲的一些伺服器的選型。

這裡特別說一下,如果我們DBA對於伺服器有自主權的話,我們可以把資料放到SSD盤,把日誌放到SAS上,這就是伺服器硬體選型需要主要的地方。

1.2.2 作業系統層面的優化

第一就是毋庸置疑,我們推薦使用Linux作業系統,一些開源主流的是我們做的。像一些商業版Linux這些就是我們在用的。

要使用這個SWAP值,如果要去做的話,我們應該最大程度去使用物理,我們儘量不去使用虛擬記憶體,而使用實體記憶體。

因為實體記憶體的訪問速度肯定比去訪問磁碟要快得多。所以我們就把這個值設成了10。有的同學可能就會說為什麼不把這個值設成0,就直接全部訪問實體記憶體就好了。

如果把它設為0的話,可能就會出現記憶體溢位的現象,就是OOM。這不是我們DBA想看到的情況。所以我們一般把這個值設成10。

第三就是關閉NUMA特性,我們公司一般是單例項的情況,所以這個時候NUMA的特性要關注,NUMA特性就是假設我們一個伺服器上有兩個CPU,分佈在伺服器左右兩邊,同時有四塊記憶體,把同一側CPU作為一個NUMA節點,就是在物理位置分佈同一側CPU訪問同一側記憶體,距離比較近,速度更快。

我們儘量同一側CPU訪問同一側記憶體。這跟我們資料庫的特性是相違背的。因為我們資料庫希望它一般部署了資料庫的伺服器就不會布其他的應用系統資源了。

所以我們希望資料庫是獨佔資料庫資源。所以在這種情況下我們要儘量關閉這個NUMA特性。

第四就是網絡卡優化。我們採用多個物理網絡卡通過做bond繫結成虛擬網絡卡,就是一些雙網絡卡做成Bond或者調整網路引數。

第五就是磁碟排程設定,一般會有幾個演算法,比如說NOOP演算法、CFQ或者是Deadline演算法,比如說這NOOP演算法用在我們資料庫上有什麼問題?就會有餓死讀操作的方式存在,如果兩個寫操作,第一個寫操作進來不需要等這個結束以後第二個寫操作就可以開展了。

如果是讀操作的話,第二個讀操作就一定要在在前一個完成。如果有幾毫秒的時間裡面,進來一堆寫操作,後面的獨操作就會餓死的,這個不符合我們資料庫演算法調動的方式。

另外就是CFQ演算法,CFQ演算法不適合我們的資料庫伺服器,MySQL是單操作伺服器。所以我們這個演算法也不適合我們使用。一般情況下資料伺服器會使用Deadline的演算法,程式會呼叫這個時候的IO請求去解決這個請求。這種Deadline演算法更加適合資料庫,因為這個Deadline的演算法更加適合。

最後一個是檔案系統的推薦,我們移動雲的資料庫系統就是Xfs或者是Ext4或者是Noatime或者是nobarrier,這些都會有影響。這是資料庫系統的優化。

1.2.3 資料庫例項的優化

我列了幾個引數我們在標準化的時候需要規範和配置的。這裡不一一揭示了。這些引數大家都可以找到,重點看一下。其實這些引數很重要。因為它決定了我們例項的效能。某一些引數配置不合理,我們例項的效能就會受到很大的影響。

1.2.4 SQL語句的優化

這裡有編寫高效SQL語句的原則,這個原則我們DBA要知道,DBA要通知業務方的研發,讓他們也知道。有很多業務側進來都是業務寫的,他沒有經驗的話,就會寫出一些有問題的語句,所以最後就變成我們DBA要去嚴查。所以最開始要把這些思想貫徹給業務研發,讓他們按照這個流程去編寫SQL的設計。

1.3 索引的設計

這裡說的是覆蓋索引,比如說有了這個覆蓋索引我們的查詢,查詢的欄位都是在這個索引內,還有我們查詢的後面的欄位也是索引,還有我們一些排序位置也是覆蓋索引,就是這一系列全部都是中了索引的情況所以就叫覆蓋索引。也列舉了一些不能使用索引的情況。比如說不要給選擇率低的欄位選擇索引,如果通過索引掃描記錄數超過30%就變成全表掃描了。還有Like額查詢條件列最左以萬用字元%開始,兩個獨立索引,其中一個用於索引一個用於排序。以上就是對於MySQL效能優化的步驟。

2. 自動化運維實踐

所謂自動化運維實踐就是相當於給我們DBA提供小工具或者是小幫手,幫助我們開啟,而不是他們糾纏著我們。我們移動雲自動化運維實踐。我們移動雲的體量就是幾百上千臺數據庫的體量,如果我們面對幾臺或者是十幾臺的資料庫的時候,有沒有這個自動化其實無所謂,因為你做自動化反而更加麻煩。如果你已經有大的量的時候就是平臺化就是在自動化的資料庫上進行拓展。

就是我們在部署安裝的時候要定一些標準化安裝部署。我們的目錄方案,版本以及部署流程有標準文件去遵循。比如說一次部署打包多次應用,我們需要再一個節點上打包標準包打包起來就一步完成了,那這個標準化的安裝部署就給後面自動化的安裝部署打了一定的基礎。

自動化的資料備份,資料備份是我們DBA非常重要的一個工作。所以我們公司也是建立合理有效以及規範的自動化備份的規範。比方說我們的常規備份,我們是每週一次全備,變更前後,有一個業務變更了,在這之前要做一個全備,萬一業務變更哪裡出現問題我就可以及時回退。這個是自動化使用的場景。我們使用的是innobackup工具+自動化備份指令碼呼叫+Cronntab定時來做。

第三點就是自動化日常監控,監控是DBA的第三隻眼睛,如果建立實時有效的監控非常有效。我們公司是採用監控是採用Zabbix監控工具,像確定一些告警閾值這種,一旦超過了這個閾值就可以給我們DBA傳送簡訊和郵件,這就是自動化的日常監控。

第四個就是自動化深度巡檢,這個就是補充了監控所不能達到的地方。比方說如果我們需要掃描或者是看一些大表的情況或者是看一些沒有建索引表的情況,它的輸出很複雜,是一張表或者是幾張表,所以我們就需要深度的巡檢來完成。深度的巡檢我們公司也是採用開發巡檢指令碼,通過Ansible統一推送,巡檢報告自動生成。也就是說可以很明確的呈現出這個巡檢的結果供DBA去看和去檢查。

第五點就是自動化的故障切換。自動化故障切換是發生在單節點發生故障。比如說變更操作,一些Keepalive部署配置,切換指令碼,VRRP協議來實現的。也是通過編寫一些指令碼,那這個指令碼可能會定期去檢查我們的資料庫節點的執行狀況。比如說這個VIP有沒有在這個節點或者是程序在不在?一旦發生異常就會自動切換這個節點。

當第六點就是自動化節點擴容。當發生單節點故障的時候我們需要部署一個新的節點的時候就需要啟動自動化的節點擴容,編寫指令碼來做。

第七點是自動化安全審計,就是異常訪問,異常操作可審計追溯。部署安全審計外掛,這個安全審計的外掛+啟用安全審計日誌,+日誌自動化或者是分析提煉。所以要不要開啟這個外掛根據各位公司對於安全審計方面的要求以及對於效能的要求從兩者取一個平衡。因為我們還是很看中這個安全事件,所以我們開啟了這個安全審計外掛,開啟這個外掛以後還需要配置檔案做一個配置。以什麼樣的方式存或者是多大?這些引數都可以在配置檔案裡面進行配置。

第八點是自動化密碼審計。這個自動化密碼審計也是一個外掛就是我們安裝了強密碼審查的日誌,這個外掛的工作原理就是設定了規則,我們需要日誌要多少位或者是多少位的大小寫或者是特殊字元的要求。我們設定密碼的時候必須符合這個強密碼驗證的要求。這個也是進行實時校驗的。也就是說我們當設一個數據庫使用者的密碼如果不符合這個強密碼的需求就不會給他通過,防止一些比較容易破解的弱密碼。

第九點就是自動化日誌分析工具。我們的日誌分析其實挺重要的,如果出現問題就需要這個日誌分析,沒有問題正常的時候也需要日誌分析工具的,因為它能夠發生潛在的優化建議,我們採用一個Percona為工具Pt-query-digest,我們只需要看DBA的慢日誌又可以發現哪些內容存在問題。

第十點是自動化資料校驗。通過我們自動化驗校修復工具來做,也是設了Crontab的任務讓它定期執行。

第十一點是自動化資料清理,因為資料庫每天每週都在備份,我們就需要機制定期清理備份檔案。我們也是採用指令碼去開發和定時看,如果超過兩個月的備份檔案我們就把它刪掉。如果檔案都在兩個月就不用管他。超過兩個月就清除它。

第十二點是自動化日誌切分。如果資料庫跑的時間比較長,慢日誌或者是錯誤日誌比較大,就需要定時檢測日誌檔案,大於某值則自動切分,否則不處理。

以上就是我們移動雲在資料庫運維的沉澱和積累。不像騰訊或者是阿里那麼大的體量和經驗。但是以上是我們探索出來的一些經驗,希望可以給各位帶來啟發或者是幫助。