做爲DBA,有時會被挑戰相似這樣的問題:數據庫
面對諸如上面的這些質疑,DBA應該如何面對?緩存
身爲DBA該如何評估現有資源使用狀況?服務器
若是現有數據庫資源確實沒法支撐,又該本着什麼原則進行改造呢?架構
本文是針對上面問題的一些經驗總結,供你們參考。app
面對這樣的問題,首先要進行評估工做,可遵循下面的步驟:運維
針對系統運行現狀,創建性能基線。將業務指標與性能指標創建起對應關係。這裏所說的性能指標包括CPU、MEM、DISK、NET等。在諸多資源中,確定存在不均衡的狀況,短板的資源最有可能成爲業務增加後的瓶頸。在具體操做上,可首先肯定一個業務高峯時間段,經過監控平臺或監控工具收集系統各資源的使用狀況。而後依據收集的信息,分析可能的性能短板在哪裏。分佈式
對於DBA來講,對本身掌管系統的性能使用狀況要了然於胸。經過對業務的瞭解,將業務指標映射到性能指標上,就能夠很容易地推斷出現有系統可承載的最大業務量。此外,對於可能影響承載業務增加的短板,也會有比較清晰的認識。工具
通常來講,數據庫類的應用是重資源消耗類的應用。對CPU、MEM、DISK、NET等,均有較大的消耗。但因爲不一樣硬件發展水平不均衡,各數據庫資源消耗特色也不一樣,所以須要具體問題具體分析。oop
下面談談我對硬件發展及與數據庫關係的一點我的觀點:性能
相對於其餘硬件而言,CPU技術發展較快。隨着CPU主頻提升及多核CPU技術的發展,CPU提供的計算能力每每不會成爲系統的性能瓶頸。但咱們須要注意的是,有些數據庫是沒法徹底利用CPU的能力(例如MySQL就是這樣)。此時,爲了充分利用CPU的資源,能夠考慮諸如"多實例混跑"的方案,提升CPU利用率。
隨着內存技術的發揮,內存的價格愈來愈便宜。如今咱們在生產環境中,能夠見到12八、256GB,甚至TB級的內存也不罕見。通常來講,數據庫一般會利用內存做爲緩衝區,大內存的配置對數據庫的性能有着比較明顯的提高。此外,數據庫自身技術也在適應着大內存的場景,一般採用的策略是劃分子池。將管理的單位進一步細分,例如Oracle中的Sub Pool、MySQL中的多instance buffer pool。
隨着GigE、10GbE、InfiniBand技術的飛速發展,低延遲、高帶寬的服務品質給數據庫乃至整個IT系統帶來了不少變化。常見的應用領域有:
加速分佈式數據庫,例如Oracle RAC。
加速大數據處理,例如提高Hadoop MapReduce處理。
存儲架構的變革,從Scale-Up向Scale-Out演變。
容災方案,主備策略…
DISK
相對於其餘硬件技術發展而言,傳統的機械式磁盤是相對而言發展最慢的,其每每也是最容易成爲數據庫的性能瓶頸。隨着閃存技術的橫空出世,爲存儲技術帶來的一種變革。下面咱們來看看主要性能指標的對比:
從上述指標來看,使用閃存技術後,存儲能力大大提升,消除了系統最大的瓶頸。這也是爲何不少DBA都在不一樣場合,大力推薦使用閃存,其對於數據庫性能的提高會帶來質的飛躍。但與此同時,咱們也應該注意到,傳統關係型數據庫是按照磁盤IO模型設計的,沒有考慮到閃存技術,如今屬於軟件落後於硬件的階段;相對而言,閃存技術對於非關係型模型更有優點。
不少基於傳統設計的優化理論發生了變化,例如: 索引聚簇因子的問題。這一點是須要咱們在考慮數據庫優化時,主要注意的。此外,NoSQL的性能優點由於傳統數據庫結合閃存技術,而變得不明顯。須要在架構選擇時加以分析。
根據業務特徵,創建業務壓力模型。簡單理解就是將業務模擬抽象出來,便於後面進行壓力放大測試。要作到這一步,須要對業務有着充分的瞭解和評估。
下面經過一個小例子說明一下:
這個表格模擬了某個類電商的業務,其包含的主要模塊及模塊中的主要操做。針對不一樣的操做其交易複雜度不一樣 (交易複雜度可理解爲執行SQL語句的個數)。根據不一樣的讀寫狀況,區分是數據讀仍是數據寫。在估算了業務總量(交易量)的狀況下,很容易推算出數據操做的量。經過這種方式將業務壓力模型轉化爲數據壓力模型。此處的難點在於對業務邏輯的抽象能力及對模塊業務量的比例評估。
有了上述概覽的表格後,針對每一種業務操做,可細化其操做。最終將其抽象成SQL語句及對應的訪問特徵。其僞代碼可描述爲
可依據上述僞代碼,編制壓力測試代碼。經過一些工具調用測試代碼,產生模擬測試的壓力。例如我常用的oradbtest/mydbtest(原阿里樓方鑫的一個測試工具)或sysbench等,都是不錯的壓力測試工具。
建議企業根據自身狀況,整理出本身的業務壓力模型。這在系統改造、升級、擴容評估、新硬件選型等多種場合都頗有用處。它要比廠商提供的相似TPCC測試報告,更有意義。據我瞭解,不少規模較大的公司都有比較成熟的壓力模型。
要想考察現有數據庫可否承載增加後的業務壓力,最好的方式就是模擬壓力測試。觀察在近似真實的壓力下,數據庫的表現。重點觀察,數據庫的承載力變化、主要性能瓶頸等。一般能夠有兩種方式,一種是從真實環境導流(並可根據須要放大流量,可利用相似TCPCOPY等工具);一種是根據前面整理的業務壓力模型,經過壓力工具模擬壓力。前者適用於已有項目的擴容評估、系統改造評估等,後者適用於新上項目原型方案評估、性能基準測試等場景。
上述模擬壓力測試結果中,暴露出的性能瓶頸點,就是咱們後面須要着重改進、優化的方向。
針對上面的評估結果,來肯定後面的改進、優化方案。可遵循以下一些步驟:
根據上面的評測結果,分析性能瓶頸點。針對不一樣瓶頸點,可採起不一樣的一些策略。有時候性能測試時全流程的,對於一個複雜系統來講,要明肯定位到性能瓶頸點比較困難。此時,可藉助一些APM工具,量化整個訪問路徑,協助找到瓶頸。也能夠相似上面的作法,作好抽象工做,只對數據庫端施加壓力,觀察數據庫行爲,判讀數據庫是否爲瓶頸。如判斷就是數據庫的承載能力不夠,可按照不一樣層次進行考慮。
在整個評估數據庫承載能力中,這一步驟是最複雜的、也是最難的一部分。要區分清楚是不是數據庫承載能力不足,仍是其餘組件的問題。即便明確是數據庫的問題,也要分清楚是總體or局部的問題;是單一業務功能慢,仍是總體都比較慢;是偶爾會慢,仍是一直都很慢等等。這些問題的界定有助於後面明確問題層次,採起不一樣的策略進行解決。
針對數據庫承載能力不足,我將常見出現問題進行了層次劃分,可簡單分爲語句級、對象級、數據庫級、數據庫架構級、應用架構級、業務架構級。不一樣層次採起的方式也有所不一樣,下面分別描述一下。
如性能核心問題,只是某條SQL語句的問題,可有針對性地進行優化。這種方式是侵入性比較小的一種優化方式,其影響範圍也比較小。下面對比常見的語句級優化方法。說明一下,下面方法已經排除了諸如統計信息不許確等其餘因素,僅從SQL語句自己優化方式考慮。
經過改寫語句,達到調整執行計劃,提升運行效率的目的。這種方式的缺點是須要研發人員修改原代碼,而後再進行部署上線的過程。此外,有些使用O/R Mapping工具產生的SQL,沒法直接修改語句,也沒法使用此方法。
不少種數據庫都提供了提示(Hint)的功能。經過這種方式來指定語句的執行過程。這種方式一樣須要修改源代碼,經歷部署上線的過程。此外,這種修改方式還存在適應性較差的問題。由於其指定了特有的執行過程,隨着數據規模、數據特徵的變化,固化的執行過程可能不是最佳方式了。這種方式其實是放棄了優化器可能產生的最優路徑。
在Oracle中還內置了一些功能,它們能夠固化某一條語句的執行方式,從本質上來說,其原理和上面使用Hint差很少。其缺點也相似上面。
有時也可經過調整某些參數,進而改變語句的執行計劃。可是這種方式要注意適用範圍,不要在全局使用,避免影響較多的語句。在會話級使用也要控制範圍,避免產生較大影響。
如性能核心問題,在SQL層面沒法解決,須要考慮對象層面的調整。這種狀況要比較慎重,須要充分評估可能帶來的風險及收益。一個對象的結構修改,能夠涉及到數百條、甚至數千條和此相關語句的執行計劃變動。如不作充分測試的狀況下,很難保證不出問題。若是是Oracle數據庫,可考慮使用SPA評估一下。其餘數據庫的話,可提早手工收集一下相關語句,模擬修改後重放上述語句,評估性能變化。
1)影響因素
在對象級進行調整,除了考慮對其餘語句的性能影響外,還須要考慮其餘因素。常見的如下這些:
常見的例如索引。經過添加索引,每每能夠起到加速查詢的目的;可是增長索引,會致使數據DML成本的增長。
常見的例如全局分區索引。全局分區索引在進行分區維護動做後,會致使索引失效,須要自動或手動進行維護索引動做。
常見的索引,索引結構是數據庫中真實佔據空間的結構。在以往的一些案例中,甚至出現過索引總大小超過表大小的狀況,所以新增時要評估其空間使用。
2)全生命週期管理
這裏還有另一個很重要的概念——「對象全生命週期管理」,簡單來講就是對象的生老病死。在不少系統中,對象重新建開始,數據不斷增長、膨脹,當數據規模達到必定量級後,各類性能問題就出現了。對一個百萬級的表和億萬級的表,其查詢性能確定不能同日而語。所以,在對象設計初期,就要考慮相關的歸檔、清理、轉儲、壓縮策略,將存儲空間的評估與生命週期管理一塊兒考慮。
不少性能問題,在作了數據清理後都迎刃而解。但數據清理每每是須要代價的,必須在設計之初就考慮這個問題。在作數據庫評審的時候,除了常規的結構評審、語句評審外,也要考慮這部分因素。
到了這個層面,問題每每已經比較嚴重了。通常狀況下,數據庫的初始配置都是基於其上面運行系統的負載類型進行專門配置的。若是運行一段時間後,出現性能問題,經評估是屬於全局性問題的,能夠考慮進行數據庫級別的調整。可是這種配置每每代價也比較大,例如須要專門的停機窗口操做等。並且這種操做的風險性也比較大,有可能會帶來不少不肯定因素,所以要慎而又慎。
如性能核心問題,沒法在上述層面解決,可能就須要調整數據庫架構。常見的例如採起讀寫分離的訪問方式、分庫分表存儲方式等。這種對應用的侵入性很強了,有些狀況下甚至不亞於重構整個系統。
例如,隨着業務的發展,系統的數據量或訪問量超出了預期,經過單一數據庫沒法知足空間或性能要求。此時,可能就須要考慮採用一種分庫分表策略,來知足這部分的需求。但其改造難度,每每比從新開發一套系統還要大。
好比,咱們可能須要一個數據中間層,來屏蔽後面的分庫分表細節。這個中間層可能須要完成語句解析、訪問路由、數據聚合、事務處理等一系列功能。即便使用了中間層產品,對於應用來講,數據庫的功能也會相對「弱化」,應用級代碼不得不進行不少的調整來適應這種變化。此外,如何把一個線上正在運行的系統,順利平穩地遷移到新的結構下,這無疑又是一個給飛馳的跑車換輪胎的問題等等。
若是項目在運行中,出現了數據庫架構級的調整,頗有可能說明在前期項目設計規劃階段出現了失誤,或者對項目的業務預期出現了誤差。所以,這兩點必定在初始階段進行充分的評估,並在設計上保留有充分的「彈性」。
有些狀況下,單純依靠數據庫是沒法解決的,須要綜合考慮整個應用架構。在整個系統架構中,數據庫每每處於系統的最末端,其擴展性是最差的。所以,在應用架構設計初期,就應該本着儘可能不要對數據庫產生壓力的原則進行設計。或者即便有大的壓力,系統能夠採起自動降級等方式保證數據庫的平穩運行。
常見的例如增長緩存、經過MQ實現削峯填谷等。經過增長緩存,能夠大幅度減小對數據庫的訪問壓力,提升總體系統的吞吐能力。引入MQ,則能夠將對數據庫的壓力以「穩態」的形式,向數據庫持續施壓,而不至於被某個異常高峯壓死。
最後一種狀況是從業務角度進行一些調整。這每每是一種妥協,經過作適當的減法保證系統的總體運行。甚至不排除犧牲一部分用戶體驗等方式,來知足大部分用戶的可用性。這就須要咱們的架構師對系統能提供的能力要很清楚,對業務也要有充分的瞭解。對於承載什麼樣的業務,及爲了承載業務所須要花費的代價成本有充分的認知,才能夠作出一些取捨。
這裏要避免一些誤區,認爲技術是「萬能」的。技術能夠解決必定的問題,但不能解決全部問題,或者解決全部問題的成本代價是難以接受的。這個時候,從業務角度稍做調整,就能夠達到「退一步海闊天空」的結果。
做者:韓鋒
來源:宜信技術學院