1. 程式人生 > >資料庫優化案例——————某知名零售企業ERP系統

資料庫優化案例——————某知名零售企業ERP系統

--------------部落格地址---------------------------------------------------------------------------------------

廢話不多說,直接開整-----------------------------------------------------------------------------------------

使用者現象

  系統慢!儲存個單據要好幾分鐘,很多操作都超時,尤其到下午4點左右各種超時,收款什麼的都收不了,

  查個報表一個小時,下班了還沒查完,經常因為系統慢而加班,

  業務部門已經怨聲載道,這個事情已經上報公司高層IT部分壓力非常大!

系統環境

  首先我們來看一下這個系統配置及現狀,為什麼說這個客戶經典?往下看就知道了...

  先來看看系統配置 :

  

   伺服器的配置是:8路 24 core 做了超執行緒 384個邏輯CPU,記憶體1T,磁碟全閃

   

     SQL用了2012版本,補丁已經最新,而且伺服器配置全部能夠識別

    沒錯。相當牛逼得配置!

     

  資料庫的大小在1.2個T

  咋一看也許資料量太大了,導致效能的問題!可又一想這麼強力的伺服器也不至於那麼慢呀,難道是程式碼的問題?難道需要分庫分表?

資料庫指標

  那麼我們再看一下資料庫的一些表象:

  每秒請求數量:

  

  使用者連線數:

  

  語句執行情況:

  

  

  等待情況:

  

  

  等待時間:

  

   CPU指標:

  

  記憶體一些指標:

  

  

  磁碟佇列:

  

 -------------------還很多指標就不一一展示了------------------

   看到這些基本的指標,除了慢你能看出什麼?問題出在哪裡?怎麼樣快速解決?能有一個優化的步驟呈現在眼前麼?

分析

  系統是真的很慢,慢語句數量很多系統阻塞也很嚴重,確實和客戶反映的慢可以吻合。那為什麼這麼慢?什麼原因導致的?

  我總結一般效能慢常和6大因素有關:

  1.   業務壓力
  2.   硬體
  3.   環境
  4.   程式碼
  5.   資料庫內部執行因素
  6.   架構

 奉上一幅草圖

  

系統壓力:訪問壓力(也是我們常說的併發)其實並不大,使用者連線數也沒想像的那麼多

  硬體:在記憶體和磁碟IO確實存在壓力

  環境 :伺服器和資料庫版本什麼的沒什麼問題,具體配置一會兒再看。

  程式碼 :最不想分析程式碼,我們留到最後

  資料庫內部執行因素:從各種指標來分析,系統語句等待時間太長,導致語句完成慢,而等待主要有兩部分:

  1.  硬體資源確實有壓力
  2.  語句之前的阻塞太嚴重了,"LCK_M_",而且等待時間過長,竟然平均達到幾百秒

  再分析...這麼強的硬體,並不大的訪問壓力,竟然造成瓶頸?語句寫的爛?程式實現的不好?缺索引?環境配置不對?

  下面我們來看看....

優化階段一(常規優化)

  很多時候系統慢要究其原因,難道上線時候就這麼慢?那不可能,廠商根本無法交付的!那麼問題來了,什麼時候開始慢的?對系統做過哪些調整?

  簡單的調研開始...

  我靠!!!廠商完全不配合,工程師對系統及其不熟悉,一問三不知,最近做什麼改動也說不清,使用者也不知道。廠商給的結論:繼續加硬體....更強的IO....資料分離減小資料量!

  協調廠商完全協調不動,基本沒戲了!

  既然是資料庫問題,那我們就資料庫下手吧!從一名資料庫從業人員來說,看到這樣的系統一定要先解決大面積等待問題!個人經驗來看很多系統大面積等待解決系統會有個很大的提升和改善!

  配合一些常規的調優手段階段一開始了,主要給系統大面積建立影響高開銷大的索引,調整系統引數,優化tempDB等....具體不細說了,前面系列文章中都有!

  預期:

  一般系統上面一輪優化會有明顯的改善,我認為這一輪以後系統會明顯變快,語句執行環境合適,索引什麼的合理資源消耗自然就少,記憶體和IO壓力也會有所減少。

  結果:

  系統記憶體,IO壓力趨於平穩,慢語句數量有所減少,但依然很多,阻塞依然存在,超過2分鐘的語句依然很多。

  優化前

  

  優化後

  

  優化前

  

  優化後

  

優化階段二(針對語句)

   再次分析解決大面積語句阻塞的系統,發現現在的情況,主要有如下幾個:

  1. 記憶體某些時候還是存在波動,但整體IO 記憶體已經不是瓶頸。
  2. 系統中有SLEEPING的程式阻塞時間長
  3. 部分功能語句依然慢,消耗的資源很高。

  再次對系統調研:

  1. 執行的慢語句是什麼業務,是業務功能?還是報表?還是介面?
  2. 系統中頻繁且較慢的語句。
  3. 系統中阻塞的操作是什麼。  

  調研後,我遇到了最常見也是最大的問題: 語句慢由於程式!在HIS的優化案例中就是因為程式大量使用自定義函式,我們沒法改,我們巧妙的繞過。那麼這次我們如何繞過?

  一:報表

分析中發現程式系統中消耗最多資源的主要是報表。

  報表通過一系列複雜的查詢插入到物理臨時表,啥叫物理臨時表? 就是非#temp 而是真真正正的插入到表中,用完在delete!

  插入在刪除,中間還有跟業務表關聯操作,導致報表也會阻塞業務!

  插入刪除的資料量是多少? 你們猜一下??

  千萬級別....

  二:介面

  介面程式中頻繁呼叫業務資料併發更新頻繁....導致業務受阻...

  三:問題程式碼

  程式碼的問題主要有兩個:

  1.程式碼較複雜,需要細緻優化。

  2.程式中存在連線洩露,簡單理解成程式報錯後事務不能有效處理,導致事務未提交阻塞系統

  

  針對第一部分報表,語句更是複雜至極...這東西不是短期就可以優化的,考慮分出去

  針對第二部分介面,修改介面檢視,包括寫法優化、新增索引、呼叫頻率等;

  針對第三部分業務語句進行細緻優化,查詢提示,計劃嚮導、重編譯等等手段...

優化階段三(報表分離)

  經過前兩個階段的優化一般系都會明顯好轉,只剩報表沒有處理,和一部分高消耗的頻繁介面查詢,這部分我們採用報表分離的方式去解決。

  這裡面我們遇到一個問題,報表要寫物理表!用2012 自帶的AlwaysOn是沒有辦法實現的(輔助節點只能讀)

  使用釋出訂閱,又不能同時滿足資料安全和業務連續的要求,客戶又不滿意。

  我們想到是否可以把寫入物理表變成寫入#temp 臨時表? 軟體廠商給出的結論是:不可能....

     那這裡面我們使用了第三方的產品Moebius叢集(這裡真的不是廣告....)

  如何實現:  

  多活叢集,幾個節點資料實時一致,這樣的基本知識就不普及了...叢集介紹也免了

  首先程式只有一個連線字串沒法把報表指向到輔助伺服器,我們只能通過Moebius叢集的前端排程引擎,定製規則把報表所使用的儲存過程定點指向到第二臺伺服器,解決了程式不能分離的問題。

  其次Moebius叢集可以實現兩個節點都可寫,以滿足輔助節點報表查詢寫入物理表的需要。

  再次臨時表的寫入量太大,千萬級別資料同步也是問題,這裡好就好在程式中寫入的物理臨時表都是以“Temp_” 開頭並以GUID型別結尾。我們在這裡設定了只要這樣的表寫入不會反向同步給主節點,這樣根據規則控制雙向同步滿足了報表的要求,最終實現了報表的分離。

  報表快了? 當然沒有,只是分離不可能快,但是好處有兩個:

  1.   OLAP和OLTP分離事務阻塞得到解決
  2.   報表伺服器和業務伺服器可以根據自身的業務特別進行單獨的個性化設定
  3.   根據報表的要求我們配置高速IO的硬體

  預期:

  語句已經優化,阻塞情況也被解決,CPU、記憶體、磁碟壓力也沒有了,系統肯定快起來了!

  結果:

  系統快起來了!

  最終業務系統節點全天24小時的慢語句數量:(雖然還有慢語句存在,畢竟是TB級別的資料量,不影響業務執行客戶完全可以接受!)

  

--------------部落格地址---------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------

  總結 : 系統慢往往我們要全面分析,本文提供的維度:

  1.   業務壓力
  2.   硬體
  3.   環境
  4.   程式碼
  5.   資料庫內部執行因素
  6.   架構

    往往優化真的不是簡單的調一調語句,加一加硬體,全面地分析是根本解決效能問題的首要任務。

  當然不是所有的優化都可以徹底解決,如本文中報表的改善是通過讀寫分離的方式實現,很多時候在ERP系統中報表的處理方式都是如此,報表如果細緻優化,那需要多長時間呀!也許都是重寫了。

  本文的優化過程主要是:全面分析系統問題——〉巨集觀層面解決(環境、資料庫內部執行因素、硬體壓力)——〉低效程式碼調整——〉架構方案實現(穩定、安全、高效)——〉最終系統順暢 無壓力

  當然此案例中客戶的資料量已經到了可以做資料分離,分割槽分表的階段,但分享本案例的原因也在於,不要認為上TB的資料一定就要分庫分表的各種拆分,在效能調優的簡單付出中依然可以收穫更大的收益,真心希望看官們在選擇分庫分表付出的極大代價之前可以找專業的人全面分析一下,仔細評估你的系統到底是什麼瓶頸!

 ----------------------------------------------------------------------------------------------------

注:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文連結!
若您覺得這篇文章還不錯請點選下右下角的推薦,非常感謝!

如果您也遇到類似問題歡迎新增微信技術交流