MySQL性能調優與架構設計(五)—— 影響MySQL Server性能的相關因素

前言

  1. 大部分人一般認爲一個數據庫應用系統的性能瓶頸,最容易出如今數據的操做方面,而數據庫應用系統的大部分數據操做都是經過數據庫管理軟件所提供的相關的接口完成。因此,數據庫管理軟件也就很天然的成爲了數據庫應用系統的性能瓶頸所在。
  2. 可是咱們的應用系統的性能瓶頸真的徹底是由於數據庫管理軟件和數據庫主機自身形成的嗎?
  3. 咱們將經過本章的內容來進行一個深刻的分析,以mysql爲例。

1、商業需求對性能的影響

(一)背景

  1. 應用系統中的每一個功能在設計初衷確定是出於爲用戶提供某種服務,或者知足用戶的某種需求,可是並非每個功能在最後都很成功,甚至有些功能的推出可能在整個系統中都是多此一舉的。
  2. 不只沒有爲用戶提升任何體驗度,也沒有爲用戶改進多少功能易用性,反而在整個系統中成爲一個累贅,帶來資源的浪費。
  3. 不合理的需求形成資源投入產出比太低。
  4. 可是需求的合理不少時候並非很容易界定,那麼到底如何證實一個需求的是否合理呢?
  5. 一個不合理的需求對性能的影響也是很大的,所以,合理的需求界定,必定程度上就是制定出投入產出比的計算規則,這個規則的制定,是須要必定的項目經驗以及項目需求的各類分析(如前期投入分析以及功能成品後期的效果統計分析)。
  6. 因此,做爲技術員,在開發過程當中要善於思考,站在一個產品經理的角度來換位思考並能給產品經理在項目需求對系統總體性能方面提出必定的建議。

(二)舉例說明

  1. 需求:一個論壇帖子總量的統計,要求實時更新。
  2. 實現方案一:html

    (1)直接執行select count(*)。
    (2)可是此sql語句在數據量愈來愈大的時候,不一樣的存儲引擎會帶來不一樣的性能問題。
    (3)myisam存儲引擎是非事務性存儲引擎,而且其內部存在內置的計數器,直接保存着代表細的總數目,若是執行select count(*)那麼將很容易就取出,即便在數據量很大的狀況下也不會出現太大的問題。
    (4)可是若是是InnoDB存儲引擎,其內部並無內置的計數器保存代表細總數量,每次執行select count(*)都會全表掃描
    (5)因而可知,當數據量在很大的一個量級的時候,加上併發很大的狀況下,很容易出現性能瓶頸。
  3. 實現方案二:mysql

    (1)方案一能夠適用於myisam存儲引擎,可是對於innodb存儲引擎就不行了。
    (2)那咱們是否能夠考慮爲這個功能單獨創建一個表,就只有一個字段一條記錄,就存放這個統計量,每次有新的帖子的時候就更新一次這個統計量,到時候直接查詢這個字段便可實現。
    (3)這種方案也可能很好的提高查詢效率,可是在咱們的系統帖子產生很快的時候,在高峯時期可能每秒就有幾十個甚至上百個帖子新增操做的時候,這個統計表可能又回出現問題。
    (4)要麼由於併發的問題形成統計結果不許確,要麼由於鎖資源爭用嚴重形成總體性能的降低。
  4. 實現方案三:web

    (1)方案一和方案二都有必定的優缺點,可是若是咱們想要在它們的缺陷處儘量的完美避開性能瓶頸呢?
    (2)這時候咱們從新考慮實時更新的需求,用戶對於這個實時更新是很容易感知的嗎?
    (3)當一個論壇的帖子數量很大了以後,到底有多少人會關注這個數量的實時變化?我想應該不會,所以,咱們對此需求是否是能夠不那麼嚴格,是否是能夠容許必定的誤差,達到準實時的標準?
    (4)基於此考慮,那麼咱們的方案三就能夠建立一個統計表,而後經過定時任務隔一段時間更新一次統計表數據,這樣既能夠解決統計表查詢的效率問題,又能夠保證不影響發帖的效率,一箭雙鵰。

(三)總結

  1. 實際上,在咱們應用的系統中還有不少相似的功能能夠優化。
  2. 好比某些場合的列表頁面參與列表的數據量達到必定的數據量級以後,徹底能夠不用準確的現實這個列表總共有多少條信息,總共分了多少頁,只須要一個估計值或者一個時間段以前的統計值。
  3. 在不少應用系統中,實時和準實時,精確與基本準確,在不少地方所帶來的性能性能消耗多是幾個性能的差異。
  4. 在系統性能優化中,應該儘可能分析出那些不實時和不徹底精確的地方,做出一些相應的調整,可能會給你們帶來意想不到的巨大性能提高。
  5. 總結可見,商業需求對性能的影響有時候也是巨大的,這時候就須要制定出合理的投入產出比計算規則從而獲得合理的需求,提高性能。

2、系統架構及實現對性能的影響

(一)背景

  1. 一個WEB應用系統,天然離不開Web應用程序(Web App)和應用程序服務器(App Server)。
  2. App Server咱們能控制的內容很少,大多都是使用已經久經考驗的成熟產品,你們能作的就只是經過一些簡單的參數調整來進行調優,不作細究。
  3. 而Web App大部分都是各自公司根據業務需求自行開發,可控性要好不少。
  4. 因此咱們應該從Web應用程序着手分析一個應用程序架構的不一樣設計對整個系統性能的影響更合適。
  5. 上一節商業需求告訴了咱們一個系統應該有什麼不該該有什麼,系統架構則決定了咱們系統的構建環境。
  6. 就像修建一棟房子同樣,在清楚了這個房子的用途以後,會先有建築設計師來畫出一張基本的構造圖,而後還須要結構設計師爲咱們設計出結構圖。
  7. 系統架構設計的過程就和結構設計師設計結構圖同樣,須要爲整個系統搭建出一個儘量最優的框架,讓整個系統可以有一個穩定高效的結構體系讓咱們實現各類商業需求。

(二)數據架構層面分析

  1. 數據層面上,咱們數據庫中存放的數據都適合在數據庫中存放嗎?
  2. 對於有些開發人員來講,數據庫是一個操做最方便的萬能存儲中心,但願什麼數據都存放在數據庫中,不管是須要持久化的數據,仍是臨時存放的過程數據,不管是純文本數據仍是多媒體的二進制數據,都喜歡所有存放到數據庫中。
  3. 其實,如今的不少數據庫爲咱們提供了太多的功能,反而讓不少並非太瞭解數據庫的人錯誤的使用了數據庫的不少並非很擅長或者對性能影響很大的功能,最後卻所有怪罪在數據庫上。
  4. 實際上,如下幾類數據都是不適合在數據庫中存放的:sql

    (1)二進制多媒體數據:
        【1】將二進制多媒體數據存放在數據庫中,一個問題是數據庫空間資源耗用很是嚴重,另外一個問題是這些數據的存儲很消耗數據庫主機的cpu資源。
        【2】這種數據主要包括圖片、音頻、視頻和其餘一些相關的二進制文件。
        【3】這些數據的處理本不是數據庫的優點,若是咱們硬要將它們塞入數據庫,確定會形成數據庫的處理資源消耗嚴重。
    (2)流水隊列數據:
        【1】咱們都知道,數據庫爲了保證事務的安全性以及可恢復性,都是須要記錄全部變動的日誌信息的。
        【2】而流水隊列數據的用途就決定了存放這種數據的表中的數據會不斷的被INSERT、UPDATE、DELETE,而每個操做都會生成與之對應的日誌信息。
        【3】在mysql中,若是是支持事務的存儲引擎(InnoDB),這個日誌的產生量將更是翻倍。
        【4】而若是咱們經過一些成熟的第三方隊列軟件來實現這個Queue數據的處理功能,性能將會成倍的提高。
    (3)超大文本數據:
        【1】對於5.0.3以前的mysql版本,varchar類型的數據最長只能存放255個字節,若是須要存儲更長的文本數據到一個字段,咱們就必須使用text類型(最大可存放64KB),甚至是更大的longtext類型(最大4G)。
        【2】而text類型數據的處理性能要遠比varchar類型數據的處理性能低下不少。
        【3】從5.0.3版本開始,varchar類型的最大長度被調整爲64KB,可是當實際數據小於255Bytes時,實際存儲空間和數據的實際長度同樣,可一旦數據長度超過了255Bytes以後,所佔用的存儲空間就是實際數據長度的兩倍。
        【4】因此,超大文本數據存放在數據庫中不只會帶來性能低下的問題,還會帶來空間佔用的浪費問題。
  5. 是否合理的利用了應用層cache機制?數據庫

    (1)對於web應用,活躍數據的數據量老是不會特別大,有些活躍數據更是不多變化。
    (2)對於這中類型的數據,咱們是否有必要每次須要的適合都去數據庫中查詢呢?
    (3)若是咱們可以將變化相對較少的部分活躍數據經過應用層的cache機制cache到內存中,對性能的提高確定是成數量級的,並且因爲是活躍數據,對系統總體性能的影響也會很大。
    (4)固然,經過cache機制成功的案例數不勝數,如何合理的經過cache技術讓系統性能獲得較大的提高也並非經過寥寥幾筆就能說明清楚的,這裏根據以往經驗列舉一下什麼樣的數據適合經過cache技術來提高系統性能:
        【1】系統各類配置及規則數據:因爲這些配置信息變更的頻率很是低,訪問機率又很高,因此很是適合使用cache。
        【2】活躍用戶的基本信息數據:
             「1」雖然咱們常常會聽到某某網站的用戶量達到成百上千萬,可是不多有系統的活躍用戶量都能達到這個量級。
             「2」也不多有用戶沒事幹去將本身的基本信息改來改去。
             「3」更爲重要的一點是用戶的基本信息在應用系統中的訪問頻率及其頻繁。
             「4」因此,用戶基本信息的cache,很容易讓整個系統的性能出現一個質的提高。
        【3】活躍用戶的個性化定製信息數據:
             「1」雖然用戶個性化定製的數據從訪問頻率來看,可能並無用戶的基本信息那麼頻繁,但相對於系統總體來講,也佔了很大的比例,並且變動規律同樣不會太多。
             「2」從Ebay的PayPal經過mysql的memory存儲引擎實現用戶個性化定製數據的成功案例咱們就能看出對這部分信息進行cache的價值。
             「3」雖然經過mysql的memory存儲引擎並不像咱們傳統意義上的cache機制,但正是對cache技術的合理利用和擴充造就了項目總體的成功。
        【4】準實時的統計信息數據:
             「1」所謂準實時的統計信息數據,實際上就是基於時間段的統計數據。
             「2」這種數據不會實時更新,也不多須要增量更新,只有當達到從新build該統計數據的時候須要作一次全量更新操做。
             「3」雖然這種數據即便經過數據庫來讀取效率可能也會很高,可是執行效率很高以後,一樣會消耗很多資源。既然數據庫資源很是珍貴,咱們爲何不放在應用相關的cache中呢?
        【5】其餘一些訪問頻繁可是變動較少的數據:
             「1」除了上述四種數據以外,在咱們面對的各類系統環境中確定還會有各類各樣的變動較少可是訪問很頻繁的數據。
             「2」只要合適,咱們均可以對他們的訪問從數據庫移到cache中。
  6. 咱們的數據層的實現都是最精簡的嗎?安全

    (1)從以往的經驗來看,一個合理的數據存取實現和一個拙劣的實現相比,在性能方面的差別常常會超出一個甚至幾個數量級。
    (2)咱們先來分析一個實例:
        【1】在咱們的網站中,如今要實現每一個用戶查看各自相冊列表,假設每一個列表10張圖片,可以在相片名稱後邊顯示該相片的留言數量。
        【2】實現方案一:
             「1」經過「SELECT id,subject,url FROM photo WHERE user_id = ? limit 10」獲得第一頁的相片相關信息;
             「2」經過第一步結果集中的10個相片的id循環運行十次"SELECT COUNT(*) FROM photo_comment WHERE photh_id = ?"來獲得每張相片的回覆數量而後再拼裝展示對象。
        【1】實現方案二:
             「1」和方案一中的第一步同樣的操做步驟;
             「2」經過程序拼裝上面獲得的10個photo的id,再經過in查詢「SELECT photo_id,count(*) FROM photo_comment WHERE photo_id in (?) GROUP BY photo_id」一次獲得10個photo的全部回覆數量,再組裝兩個結果集獲得展示對象
    (3)下面對兩種方案作一下簡單的比較:
        【1】從mysql的sql執行數量來看,方案一爲11條sql語句,方案二爲2條sql語句;
        【2】從應用程序於數據庫交互來看,方案一是11次,方案二是2次;
        【3】從數據庫IO操做來看,簡單假設每次sql爲1個IO,方案一最少11次IO,方案二小於等於11次IO,並且只有當數據很是之離散的時候纔會須要11次;
        【4】從數據庫處理的查詢複雜度來看,方案一是兩類很簡單的查詢,方案二有一條sql有group by操做,比第一種解決方案增長了排序分組操做;
        【5】從應用程序結果集處理來看,方案一11次結果集的處理,方案二2次結果集的處理,可是方案二中第二次結果集數量是第一次的10倍;
        【6】從應用程序數據處理來看,方案二比方案一多了一個拼裝photo_id的過程。
    (4)咱們從以上6點作一個性能消耗的分析:
        【1】因爲mysql對客戶端每次提交的sql無論是相同仍是不一樣,都須要進行徹底解析,這個動做主要消耗的資源是數據庫主機的CPU,那麼這裏第一種方案和第二種方案消耗的CPU的比例是11:2。sql語句的解析動做在整個sql語句執行過程當中的總體消耗的CPU比例是比較多的;
        【2】應用程序與數據庫交互消耗的資源基本上都在網絡方面,一樣是11:2;
        【3】數據庫IO操做資源消耗小於或者等於1:1;
        【4】方案二須要比方案一多消耗內存資源進行排序分組操做,因爲數據量不大,多出的消耗在語句總體消耗中佔用比例會比較小,大概不會超過20%,你們能夠針對性測試;
        【5】結果集處理次數爲11:2,可是方案二比方案一處理數量大,總體來講兩次的性能消耗區別不大;
        【6】應用程序數據處理方面所多出的這個photo_id的拼裝所消耗的資源是很是小的,甚至比應用程序與mysql作一次簡單的交互所消耗的資源還要少。
    (5)總體分析後,得出結論,從總體消耗資源來看,方案二遠遠優於方案一。
  7. 過渡依賴數據庫sql語句的功能形成數據庫操做效率低下性能優化

    (1)前面的案例是開發工程師過渡弱化SQL語句的功能形成的資源浪費案例,而這裏咱們再來分析一個徹底相反的案例:在羣組簡介頁面須要顯示羣名稱和簡介,每一個羣成員的nick_name,以及羣主的我的簽名信息。
    (2)需求中所需信息存放在如下四個表中:user,user_profile,groups,user_group
    (3)方案一:
        【1】SELECT name,description,user_type,nick_name,sign
              FROM groups,user_group,user ,user_profile
              WHERE groups.id = ?
              AND groups.id = user_group.group_id
              AND user_group.user_id = user.id
              AND user_profile.user_id = user.id
    (4)方案二:
        【1】首先取得全部須要展現的group的相關信息和全部羣組員的nick_name信息和組員類別:
        SELECT name,description,user_type,nick_name
          FROM groups,user_group,user
          WHERE groups.id = ?
          AND groups.id = user_group.group_id
          AND user_group.user_id = user.id
        【2】而後在程序中經過上面結果集中的user_type找到羣主的user_id再到user_profile表中取得羣主的簽名信息:
             SELECT sign FROM user_profile WHERE user_id = ?
    (5)你們應該可以看出二者的區別吧,兩種解決方案最大的區別在於交互次數和 SQL複雜度。
    (6)而帶來的實際影響是第一種解決方案對user_profile表有沒必要要的訪問(非羣主的profile信息),形成IO訪問的直接增長在20%左右。
    (7)而你們都知道,IO操做在數據庫應用系統中是很是昂貴的資源。尤爲是當這個功能的PV較大的時候,第一種方案形成的IO損失是至關大的。

(三)其餘架構影響

  1. 其餘比較常見的架構設計實現不當帶來的性能問題和資源浪費狀況:服務器

    (1)重複執行相同的SQL形成資源浪費
    (2)Cache系統的不合理利用致使Cache命中率低下形成數據庫訪問量的增長,同時也浪費了Cache系統的硬件資源投入;
    (3)對可擴展性的過分追求,促使系統設計的時候將對象拆得過於離散,形成系統中大量的複雜Join語句,而MySQL Server在各數據庫系統中的主要優點在於處理簡單邏輯的查詢,這與其鎖定的機制也有較大關係;
    (4)對數據庫的過分依賴,將大量更適合存放於文件系統中的數據存入了數據庫中,形成數據庫資源的浪費,影響到系統的總體性能,如各類日誌信息;
    (5)過分理想化系統的用戶體驗,使大量非核心業務消耗過多的資源,如大量不須要實時更新的數據作了實時統計計算。

3、Query 語句對系統性能的影響

  1. 前面一節咱們瞭解了系統架構的實現方式對系統性能的影響,這一節咱們將分析sql語句的差別對系統性能的影響。
  2. sql語句的優劣對性能是有影響的,可是到底有多大影響可能咱們每一個人都會有不一樣的體會,每一個sql語句在優化以前和以後的性能差別也是各不相同的,因此對性能差別到底有多大咱們這裏就不作詳細分析了。
  3. 咱們重點分析實現一樣功能的不一樣sql語句在性能方面會產生較大差別的根本緣由。
  4. 爲何獲得相同結果集的不一樣SQL語句,在執行性能上存在差別呢?這裏咱們先從sql語句在數據庫中執行並獲取所需數據的過程來進行分析。網絡

    (1)當mysql server的鏈接線程接收到Client端發送過來的sql請求以後,會通過一系列的分解Parse,進行相應的分析。
    (2)而後mysql會經過查詢優化器模塊根據該sql所涉及到的數據表的相關統計信息進行計算分析,而後再得出一個mysql認爲最合理最優化的數據訪問方式,就是咱們平時說得「執行計劃」。
    (3)再根據獲得的執行計劃經過存儲引擎接口來獲取相應數據。
    (4)最後再將存儲引擎返回的數據進行相關處理,並以Client端要求的格式做爲結果集返回給Client端的應用程序。
    (5)注意:這裏所說的統計數據,是mysql經過ANALYZE TABLE命令同志mysql對錶的相關數據作分析以後所得到的一些數據統計量。這些統計數據對mysql優化器來講很是重要,優化器所生成的執行計劃的好壞,主要就是由這些統計數據所決定的。
    (6)咱們都知道,在數據庫管理軟件中,最大的性能瓶頸就是在於磁盤IO,也就是數據存取操做上面。
    (7)而對於同一份數據,當咱們以不一樣方式去尋找某一點的數據時,所須要讀取的數據量可能會有天壤之別,所消耗的資源也天然是區別深大。
    (8)因此,當咱們須要從數據庫中查詢某個數據的時候,所消耗資源的多少主要取決於數據庫以一個什麼樣的數據讀取方式來完成咱們的查詢請求,也就是取決於sql語句的執行計劃。
    (9)而對於惟一sql語句來講,通過mysql Parse以後分解後的結構都是固定的,只要統計信息穩定,其執行計劃基本上都是比較固定的。
    (10)而不一樣寫法的sql語句,通過Mysql Parse以後分解的結構就可能會不一樣,即便優化器使用徹底同樣的統計信息來進行優化,最後所獲得的執行計劃也可能徹底不同。
    (11)而執行計劃是決定一個sql語句最終的資源消耗量的主要因素。
    (12)因此,實現功能徹底同樣的SQL語句,在性能上面可能會有差異巨大的性能消耗。
    (13)固然,若是功能同樣,並且通過 MySQL的優化器優化以後的執行計劃也徹底一致的不一樣SQL語句在資源消耗方面可能就相差很小了。固然這裏所指的消耗主要是IO資源的消耗,並不包括 CPU的消耗。
  5. 分析具體的sql語句對性能對影響,有兩種方式,一種就是explain執行計劃,一種就是經過實際執行後的profile數據的驗證。具體的詳細分析這裏不作探究,之後具體舉例探究。

4、Schema設計對系統性能的影響

(一)背景

  1. 前面,咱們已經分析了數據庫應用系統的軟環境中應用系統的架構設計和系統中與數據庫交互的sql語句對系統性能的影響。接下來,咱們再分析下系統的數據模型設計實現對系統的性能影響。更通俗的講就是數據庫的Schema設計對系統性能的影響。
  2. 在不少人看來,數據庫Schema設計是一件很是簡單的事情,就大致按照系統設計時候的相關實體對象對應成一個一個的表格基本上就能夠了。
  3. 而後爲了功能上儘量的容易擴展,再根據數據庫範式規則進行調整,作到第三範式或者第四範式,基本就算完事了。可是數據庫的Schema設計真的這麼容易嗎?
  4. 這裏,咱們暫時不討論什麼樣的Schema設計是最優的設計,而是先經過一個實際的實例來展現Schema結構的不同在性能方面所帶來的差別。

(二)示例

  1. 需求概述:一個簡單的討論區系統,須要有用戶,用戶組,組討論區這三部分基本功能
  2. 簡要分析:mysql優化

    (1)須要存放用戶數據的表;
    (2)須要存放分組信息和存放用戶與組關係的表
    (3)須要存放討論信息的表;
  3. 方案一:分別用用四個表來存放用戶,分組,用戶與組關係以及各組的討論帖子的信息。
    圖片描述
    圖片描述
    圖片描述
    圖片描述
  4. 方案二:用戶與用戶屬性表分開
    圖片描述
    圖片描述
    圖片描述
    圖片描述
  5. 兩方案比較:

    (1)咱們先來比較下兩個解決方案所設計的Schema的區別。
    (2)區別主要體如今兩點。一個區別就是group_message表中添加了author字段來存放發帖做者的暱稱,與user表的nick_name相對應,另一個就是方案二將user表和group_message表都拆分紅了兩個表,關係分別一一對應。
    (3)方案二看起來複雜一些,首先是表的數量多2個,而後是group_message中冗餘了做者的暱稱。
    (4)咱們試想一下,一個討論區系統,訪問最多的頁面會是什麼?
    (5)我想你們都會很清楚是帖子標題列表頁面。而帖子標題列表頁面最主要的信息就是都是來自 group_message表中,同時帖子標題後面的做者通常都是經過用戶名(暱稱)來展現。按照第一種解決方案來設計的 Schema,咱們就須要執行相似以下這樣的SQL語句來獲得數據:
        【1】SELECT t.id, t.subject,user.id, u.nick_name
               FROM (
               SELECT id, user_id, subject
               FROM group_message
               WHERE group_id = ?
               ORDER BY gmt_modified DESC LIMIT 20
               ) t, user u
               WHERE t.user_id = u.id
    (6)可是方案二所需執行的sql就會簡單不少:
         SELECT t.id, t.subject, t.user_id, t.author
       FROM group_message
       WHERE group_id = ?
       ORDER BY gmt_modified DESC LIMIT 20
    (7)兩個sql相比較,很明顯能夠看出方案一須要join兩個表的數據,與方案二的sql相比性能相差很大,尤爲是若是第一個再寫的差一點,性能更是很是糟糕,二者所帶來的資源消耗就更相差玄虛了。
    (8)不只僅如此,因爲第一個方案中的group_message表中還包含一個大字段「content」,該字段所存放的信息要佔整個表的絕大部分存儲空間,但在這條系統中執行最頻繁的 SQL之一中是徹底不須要該字段所存放信息的,可是因爲這個SQL又沒辦法作到不訪問group_message表的數據,因此第一條SQL在數據讀取過程當中會須要讀取大量沒有任何意義的數據。
    (9)在系統中用戶數據的讀取也是比較頻繁的,可是大多數地方所須要的用戶數據都只是用戶的幾個基本屬性,如用戶的id,暱稱,密碼,狀態,郵箱等,因此將用戶表的這幾個屬性單獨分離出來後,也會讓大量的SQL語句在運行的時候減小數據的檢索量,從而提升性能。
    (10)可能有人會以爲,在咱們將一個表分紅兩個表的時候,咱們若是要訪問被分拆出去的信息的時候,性能不是就會變差了嗎?是的,對於那些須要訪問如user的sign,msn等原來只須要一個表就能夠完成的SQL來講,如今都須要兩條SQL來完成,性能確實會 有所下降,可是因爲兩個表都是一對一的關聯關係,關聯字段的過濾性也很是高,並且這樣的查詢需求在整個系統中所佔有的比例也並不高,因此這裏所帶來的性能損失實際上要遠遠小於在其餘SQL上所節省出來的資源,因此徹底沒必要爲此擔憂

5、硬件環境對系統性能的影響

  1. 在本章以前的全部部分都是介紹的整個系統中的軟件環境對系統性能的影響,這一節咱們將從系統硬件環境來分析對數據庫系統的影響,並從數據庫服務器主機的角度來作一些針對性的優化建議。
  2. 任何一個系統的硬件環境都會對起性能起到很是關鍵的做用
  3. 而數據庫應用系統環境中,因爲數據庫自身的特色和在系統中的角色決定了他在整個系統中是最難以擴展的部分。因此在大多數環境下,數據庫服務器主機(或者主機集羣)的性能在很大程度上決定了整個應用系統的性能。
  4. 既然咱們的數據庫主機資源如此重要,確定不少讀者朋友會但願知道,數據庫服務器主機的各部分硬件到底誰最重要,各部分對總體性能的影響各自所佔的比例是多少,以便可以根據這些比例選取合適的主機機型做爲數據庫主機。可是我只能很遺憾的告訴你們,沒有任何一個定律或者法則能夠很準確的給出這個答案。
  5. 固然,你們也沒必要太沮喪。雖然沒有哪一個法則能夠準確的知道咱們到底該如何選配一個主機的各部分硬件,可是根據應用類型的不一樣,整體上仍是有一個能夠大體遵循的原則能夠參考的。
  6. 三類影響數據庫主機性能的最主要因素部件

    (1)與IO相關的磁盤和內存:
        【1】首先,數據庫主機是存取數據的地方,那麼其IO操做天然不會少,因此數據庫主機的IO性能確定是須要最優先考慮的一個因素,這一點無論是什麼類型的數據庫應用都是適用的。
        【2】不過,這裏的IO性能並不只僅只是指物理的磁盤IO,而是主機的總體IO性能,是主機整個IO系統的整體IO性能。
        【3】而IO性能自己又能夠分爲兩類,一類是每秒可提供的IO訪問次數,也就是咱們常說的IOPS數量,還有一種就是每秒的IO總流量,也就是咱們常說的IO吞吐量。
        【4】在主機中決定 IO性能部件主要由磁盤和內存所決定,固然也包括各類與IO相關的板卡。
    (2)CPU:
        【1】其次,因爲數據庫主機和普通的應用程序服務器相比,資源要相對集中不少,單臺主機上所須要進行的計算量天然也就比較多,因此數據庫主機的CPU處理能力也不能忽視。
    (3)網絡設備:
        【1】最後,因爲數據庫負責數據的存儲,與各應用程序的交互中傳遞的數據量比其餘各種服務器都要多,因此數據庫主機的網絡設備的性能也可能會成爲系統的瓶頸。
  7. 因爲上面這三類部件是影響數據庫主機性能的最主要因素,其餘部件成爲性能瓶頸的概率要小不少
  8. 因此後面咱們經過對各類類型的應用作一個簡單的分析,再針對性的給出這三類部件的基本選型建議。

    (1)典型OLTP應用系統
        【1】對於各類數據庫系統環境中你們最多見的OLTP系統
        【2】其特色是併發量大,總體數據量比較多,但每次訪問的數據比較少,且訪問的數據比較離散,活躍數據佔整體數據的比例不是太大。
        【3】對於這類系統的數據庫其實是最難維護,最難以優化的,對主機總體性能要求也是最高的。由於他不只訪問量很高,數據量也不小。
        【4】針對上面的這些特色和分析,咱們能夠對OLTP的得出一個大體的方向:
             「1」雖然系統整體數據量較大,可是系統活躍數據在數據總量中所佔的比例不大,那麼咱們能夠經過擴大內存容量來儘量多的將活躍數據cache到內存中;
             「2」  雖然IO訪問很是頻繁,可是每次訪問的數據量較少且很離散,那麼咱們對磁盤存儲的要求是IOPS表現要很好,吞吐量是次要因素;
             「3」  併發量很高,CPU每秒所要處理的請求天然也就不少,因此CPU處理能力須要比較強勁;
             「4」  雖然與客戶端的每次交互的數據量並非特別大,可是網絡交互很是頻繁,因此主機與客戶端交互的網絡設備對流量能力也要求不能太弱。
    (2)典型OLAP應用系統
        【1】用於數據分析的OLAP系統的主要特色就是數據量很是大,併發訪問很少,但每次訪問所須要檢索的數據量都比較多,並且數據訪問相對較爲集中,沒有太明顯的活躍數據概念。
        【2】基於OLAP系統的各類特色和相應的分析,針對OLAP系統硬件優化的大體策略以下:
             「1」數據量很是大,因此磁盤存儲系統的單位容量須要儘可能大一些;
             「2」單次訪問數據量較大,並且訪問數據比較集中,那麼對IO系統的性能要求是須要有儘量大的每秒IO吞吐量,因此應該選用每秒吞吐量儘量大的磁盤;
             「3」雖然IO性能要求也比較高,可是併發請求較少,因此CPU處理能力較難成爲性能瓶頸,因此CPU處理能力沒有太苛刻的要求;
             「4」雖然每次請求的訪問量很大,可是執行過程當中的數據大都不會返回給客戶端,最終返回給客戶端的數據量都較小,因此和客戶端交互的網絡設備要求並非過高;
             「5」此外,因爲OLAP系統因爲其每次運算過程較長,能夠很好的並行化,因此通常的OLAP系統都是由多臺主機構成的一個集羣,而集羣中主機與主機之間的數據交互量通常來講都是很是大的,因此在集羣中主機之間的網絡設備要求很高。
    (3)除了以上兩個典型應用以外,還有一類比較特殊的應用系統,他們的數據量不是特別大,可是訪問請求及其頻繁,並且大部分是讀請求。可能每秒須要提供上萬甚至幾萬次請求,每次請求都很是簡單,可能大部分都只有一條或者幾條比較小的記錄返回,就好比基於數據庫的 DNS服務就是這樣類型的服務。
        「1」雖然數據量小,可是訪問極其頻繁,因此能夠經過較大的內存來 cache住大部分的數據,這可以保證很是高的命中率,磁盤IO量比較小,因此磁盤也不須要特別高性能的;
        「2」併發請求很是頻繁,須要較強的CPU處理能力才能處理;
        「3」雖然應用與數據庫交互量很是大,可是每次交互數據較少,整體流量雖然也會較大,可是通常來講普通的千兆網卡已經足夠了。
  9. 在不少人看來,性能的根本決定因素是硬件性能的好壞。
  10. 但實際上,硬件性能只能在某些階段對系統性能產生根本性影響。
  11. 當咱們的CPU處理能力足夠的多,IO系統的處理能力足夠強的時候,若是咱們的應用架構和業務實現不夠優化,一個原本很簡單的實現非得繞不少個彎子來回交互屢次,那再強的硬件也沒有用,由於來回的交互老是須要消耗時間。
  12. 因此,在應用系統的硬件配置方面,咱們應該要以一個理性的眼光來看待,只有合適的纔是最好的。並非說硬件資源越好,系統性能就必定會越好。
  13. 並且,硬件系統自己老是有一個擴展極限的,若是咱們一味的但願經過升級硬件性能來解決系統的性能問題,那麼總有一天將會遇到沒法逾越的瓶頸。

總結

  1. 簡單來講,能夠經過下面三句話來簡單的歸納數據庫應用系統的性能優化:商業需求合理化,系統架構最優化,邏輯實現精簡化,硬件設施理性化。

參考連接

https://www.cnblogs.com/jesse...

相關文章
相關標籤/搜索