簡介
什麼是性能調校呢?一般是當用戶抱怨“太慢了”、“性能不足”、“軟硬體需要升級了”等問題時,提供較佳的性能。但不是要解決用戶所說的“這系統毀了”、“它不會工作了”等問題,這可能需要的是備援回滾、提高系統可獲得性(HA high Availability)等解決方案。但就資料庫系統而言,規劃高可獲得性的架構(如SQL Cluster、Mirroring、Log Shipping、Replication等)不會提升系統性能,還要注意是否降低了性能。
現象
而一般觀測性能問題的現象有:
系統回響速度太慢。
每秒所完成的系統輸出/入低於預期。
相同的環境,但每秒鐘所完成的批操作較先前少。
系統資源(如CPU、記憶體、硬碟或網路等)長時間處於耗盡的狀態。
通常調校的目標是以用戶的期望為依據,除非你的數學與信息基本功非常紮實,否則很難知道調校的極限在哪。因此,我們的目標往往是符合用戶的期盼即可
目標
這些落於紙上的目標應越明確越好,例如上述的情況,若目標是 “我想要調低記憶體的使用率,因為它的值太高了”就不如“我想要調低某個程式開始獲取記憶體的設定,因為它可能吃掉太多的記憶體,但實際沒有用到這么多,而其他的應用程式沒有足夠的記憶體,導致整體系統性能不佳”。後者的描述有目標,且可以比較,因為實際調整後可以觀察調低記憶體的程式執行起來是否有問題,整體的性能與沒調整前是否有差異。
除了以文檔描述基線、調校的目標外,還可以以文檔描述所用的工具,如評估性能的程式、真實應用程式的片段功能、各種資源的性能監視程式、壓力測試程式等。同時,有越詳細的步驟越好。性能調校可能是一再的錯誤嘗試,因為大部分的狀況都是撲朔迷離的,無法一眼看出問題所在,需要改改這個,看看是否比較好,再修修那個,看看結果如何。若沒有文檔記錄,你可能會在性能調校的大迷宮中打轉,做一些類似而重複的事情,但總理不出頭緒。
嘗試列出系統中各個組件合理的性能消耗,可以幫助你理清整個系統訪問中,各個組件所占的性能消耗比例,哪些部分有可以調整的空間。另外,再搭配調整該部分的成本有多高,讓你了解調整的優先權,並對系統的極限有更佳的認識。
基線
調校性能的第一個工作應該是建立性能的基線(baseline),所需的類型有:
昔日系統正常運行時的數據。
調校前系統的各種數據。
用戶希望達到的目標。
基線是用來比較的,任何性能調校的動作都應該依憑數據,不要訴諸情緒。筆者常聽到工程師說“今天的性能感覺比較差了”或是“現在系統回響比較慢了”。這種話是我們要幫用戶解決問題的起因,但不應該是工程師講的話。人的感覺非常不準,可能是心情不好,可能是對工作不滿意,對系統的包容力就比較差,感覺就不好了。
系統回響比較慢,要知道正常是多少、慢了多少、時間差是多少、數據量多少、多少人同時上線、處理量多少等。也就是要有基線,有客觀的數據,這才有好的調校基礎。而通常筆者碰到的是:工程師與用戶們忙了一天,精疲力竭後,會安慰自己“性能比較好了”。
如前文所述,一般要將用戶的期待量化,例如,用戶可以接受系統的回響時間是3~5 秒。而用戶的期待通常是來自於以下方面。
工作需求:如一定要在某個時間點前完成,一秒之內要完成多少交易量才能滿足多人訪問等。以往系統的使用經驗。一些性能數據值(benchmark):不管是廠家提供的,還是業界提出的標準值。其他用戶使用類似功能的經驗。
為什麼討論這個呢?因為期待要合理。不要第一次開車開賓士,然後誤以為全世界的汽車開起來都要像這樣。或許你會覺得這不可能發生。但事實上,若以往的系統是以Windows Form為基礎,現在一模一樣的功能,但改為以Web Form為基礎,在相同的硬體上,可能回響就比較慢。畢竟以往從SQL Server或COM+/MTS直接傳數據給編譯過的VB 前端程式呈現結果,系統架構簡單有效率且互動功能豐富。而Web版的ASP/ASP. NET應用程式要先將SQL Server或COM+/MTS的結果數據轉換成HTML,再用效率也不高的HTTP通信協定返回到前端,最後還要瀏覽器遵從HTML 或DHTML 指示符,當前繪製界面,整體系統的性能當然不如以往的程式架構。
若用戶端的機器本身很快,使用者或許還感受不到這個差異,然而筆者曾碰到的情況:使用古老的機器,但要求Web Form 長得和Win Form 一樣,並且功能還要更多,而能忍受的回響時間相同,這就難如登天了。
支出
另外,性能調校代表著成本(cost)的支出,成本可能是實質的錢,也可能是工程師的時間與精力,用戶的忍耐等待。在理想狀況下,是把系統中最貴的部分發揮到極限,能夠以最低的成本來發揮系統最大的性能。若是自己開發的程式,這往往代表著硬體採購是系統開發中最貴的部分,因此,會採取重新設計系統的解決方式,如資料庫邏輯使用方式重新切割、查詢方式大量重載、以消耗記憶體的方式減少對硬碟的訪問等。你可能要花掉數個工程師個把月的時間,才得以將架構重新規劃,程式全面重載,或許花費如此的人力成本還不如直接更新設備,但性能調校的總體成本(total cost)並不容易計算。
筆者遇到的大部分狀況是管理者會挑眼前最節約成本的事情先做。一般來說,就是要工程師著手調架構,可能是資料庫的設計,也可能是程式代碼重載,忙了個把月後聲明失敗,最後還是花錢買機器。這種僅看當前最低成本的做法有幾個弊端:
用戶苦等一兩個月,最後還是換機器,他們會覺得工程師能力不足。實際上浪費了人力成本。一陣子後,性能問題又再度浮現。
在動手調校前應該對整個系統的各個瓶頸點瞭然於胸,各花多少成本可以解決,而該瓶頸調整後,整體系統性能可以提升多少。以筆者曾調校的系統為例,整體設計是用IE呈現IIS執行ASP的結果,ASP 調用COM+,COM+訪問SQL Server。系統剛上線時,總回響時間是7秒鐘,但用戶可以接受的時間是3 秒鐘。程式中,個別的時間消耗是IE花費2秒鐘(因為前端PC老舊,而執行操作很複雜),ASP 處理時間0.5 秒鐘,COM+處理時間4秒鐘,SQL Server處理時間0.5秒鐘。
前端PC 數量太大,要升級成本太高。因此,大家都覺得先調後端吧,這時就算工程師花了九牛二虎之力,將三種伺服器的性能都提升一倍,也就是讓原來各伺服器處理時間的總和5秒鐘降為2.5秒鐘,但系統整體時間還是要4.5秒鐘。
用戶罵了一個月之後,在不準更改功能的窘境下,還是要更新前端PC,這時大家就難堪了。所以,事前的整體評估很重要,告知用戶能期待什麼?最後底線是什麼?才有可能讓大家都接受調校的結果。
性能的基線應該都是可以量化的,例如,回響時間、單位時間可執行的批處理數量、單位時間可以處理的數據量、同時上線人數等,都可以求出最大值、最小值、平均值、總數等。針對要調校的目標,先獲取數據後,才可以評估調校的方向是否正確。另外,對系統各環節的性能極限應儘可能地評估一下,不要耗了極大的功夫,才發現其實早已經把某一部分發揮到極限了,再怎么做都不可能提升多少性能,這時你可能需要變更用戶需求、系統架構或必須更換軟硬體。
有些值是當前可以算出來的,例如,直接將用戶訪問數據的T-SQL語句當前執行一遍,可以看出執行該語句的時間,在SQL Server本機上通過管理工具執行一次,在遠程網路上再執行一次,可以約略知道網路是否有影響等。但某些數據可能要特別建立一些環境來測試,例如,沒有用戶,空機的時候某個工作的執行效率如何?有多人上線時,又是如何反應?原本某個工作每秒鐘可以完成多少次,加上什麼運行程式後,每秒鐘只剩幾次等。
另外,如壓力測試時,要仿真多大的數據量,多少人同時上線等,建立這些基線的數據就較為困難,因為仿真的環境要儘量與真實相同。因為不同的數據模型,SQL Server 會建立不同的執行計畫,若是以隨機數產生的數據,往往與真正的數據類型不符,使索引判斷、選擇如何做Join等都會大不相同。
這些基線的數據應該越詳盡越好,不要泛泛地取些值就拿來比較。筆者碰過一位工程師拿著代表某大型系統執行性能的4張圖,上面標著中央處理器、主存儲器、硬碟與網路,各有著一條彎彎曲曲描述性能的線,除了記憶體的線長時間在天上之外,其餘的都不高,他就有了結論:記憶體要加大。當然,你讓不懂信息技術的路人甲看這4張圖,跟他解釋圖形的意義,問他要如何調性能,他也會說要加記憶體,因為就只有這張圖看起來和其他3張長得不一樣。
如果公司的錢用不完,這樣的調校似乎就足夠了,全部都靠擴大硬體來提升性能。但就前述的現象,可能要問的是,記憶體與硬碟快取盤交換是否頻繁,數據快取區的高速快取擊中率(cache hit ratio)是否低於90% ,以進一步確認是否為記憶體不足才拖慢整體性能。說不定是資料庫鎖定,也說不定是程式有Bug造成記憶體遺失(memory leak),或是程式本身的Bug造成性能不足等。
若真的是記憶體不足,是否還可以調校?說不定是資料庫系統的設定一開始要占用極大的快取區,所以,大部分的記憶體都被它拿走,但整體來說並沒有有效使用記憶體 。因此,哪個程式吃掉了大部分的資源?誰是主要調校的目標?什麼樣的方向或指針代表調校有效?諸此種種都應該落到文字上,如此可以整理較為清晰的思路,並有可討論的交集,否則一堆沒有共識的專家,恐怕只會眾說紛紜,皆能證明不是自己的錯,但禍首是誰卻說不出來,最後落到會而不議,議而不決的窘況。