| 軟體開發永續經營的生存之道 第2回
持續整合的精神在於,將軟體工程的理論進一步落實在專案執行面,大致上,會出現哪些狀況?
|
| 前一回提到持績整合所帶來的好處,但相信很多人在研究一些軟體工程方法論的書時,心中大都會浮現以下問題,或遭遇一些無法控制的狀況:
● 軟體工程方法是一回事,實做又是另外一回事?因為專案團隊的成員對方法論都不熟,不斷嘗試錯誤未能全然掌握方法的精髓,常常走許多冤枉路,才有一點點進展。 ● 軟體專案計畫派不上用場,時間上根本不足以允許你妥善規畫,可能老板的一句話就將原有的規畫全盤打破,當專案被時程壓力所限制後,所有的方法論就拋諸腦後。 ● 新方法的導入造成現行作業的衝擊,團隊成員浮現抗拒心態,造成想推也推不動。 持續整合的範疇 持續整合的範疇,可依專案組織的現況及現有可用資源,來決定需要導入的項目。一般而言,可分以下項目分別導入建置: ● 版本控管(Version Control) 於多人開發的專案團隊,版本控管的議題算是最基本,也是最重要的項目,準備一個版本控管資料庫 (Repository) 是必要的。軟體開發的生命周期過程,必然會面臨程式碼版本的分支(Branch)、貼標(Tag)、合併(Merge)、回溯(Revert)、比對(Compare)等需求。良好的版本控管機制可提供好的工具,來協助開發人員面臨這樣多變的需求,以利在短時間內能產出正確可部署的軟體版本發布。 目前坊間常見的版本控管機制,包括付費及免費、集中及分散式控管,種類甚多,評估導入的因素可依專案團隊同時使用人員的多少,開發工具是否能整合,建置成本及時間的長短等因素,來分別思考,來找出適合開發團隊使用的方案。 ● 測試自動化(Auto-Testing) 軟體測試的類型繁多,主要都是為了確保軟體品質而搭配使用,測試作業的繁複常不易在有限的專案時程內被全然落實,有時亦會為了方便行事,忽略了部分測試作業,或是避開重測,但常常事後發生異常的點,都是這些被忽略的地方。 利用人工來進行測試作業是十分累的,所以將繁雜且重要的測試工作自動化是必然的,將各項重要的測試工作及測試範圍涵蓋度的檢測,連同程式碼建構作業時以系統自動執行必要測試的項目一併處理,當出現異常錯誤時再由人工介入處理,才能將時間有效花在刀口上。 不過想到要多寫這些測試程式,相對又增加一定比重的開發時間,對開發人員勢必又造成負擔。當然也可以配合一些測試程式碼的產生工具,來快速生成測試作業時的基本所需。 ● 建構自動化(Auto-Build) 建構自動化的用意在於及早發現程式可能的錯誤,在未擴大影響範圍之前便先行處理,而持續整合的精神亦可以透過設置頻繁自動建構的方式 (例如系統每60分鐘自動執行建構作業的執行),結合自動通知機制,讓開發團隊成員可以得知目前最新版本的建構結果。 建構作業的項目,除整合前項測試外,亦可加入許多提高軟體品質的作業,例如程式碼撰寫風格的格式化,方便後續開發人員撰寫時閱讀;以及,針對程式碼內容反向生成參考文件,以利程式與文件內容一致化;或是利用靜態程式碼掃描工具,一併檢測程式隱含的效能及安全性問題而及早修正等。 ● 錯誤通報及後續追蹤處理機制的整合 軟體開發團隊必然有問題追蹤系統 (Issues Tracking System),其中錯誤問題的來源可能是日常外部單位的通報、系統自動監控的示警、軟體建構過程中發生的編譯錯誤或測試失敗。然而這些事項的分派及後續處理狀況的追蹤,理想上也必須能透過系統自動化的方式來進行,才不致於造成工作分派環節的瓶頸所在。 持續整合對專案團隊各角色的衝擊為何? 新方法及工具的導入,對既有專案團隊的影響,會歸因於所選擇導入的方式,主要的影響如下: ● 每位開發人員應盡可能不斷地將修改後,可以成功建構(build)的程式碼內容隨時交付(commit)至程式碼資料庫(Repository)中進行整合,相關動作的執行可以每日多次,頻率可以提高。 ● 開發人發必須嚴守交付可成功構建的程式碼,尤其是在每日下班前確保這個動作無誤。 ● 開發團隊必須撰寫額外的測試程式。開發人員需要針對自行開發的元件及服務,完成測試程式的撰寫;而系統設計師也必須針對跨元件或整合服務流程,進行測試程式碼的撰寫,搭配程式碼構建時的測試自動化作業,以確保程式碼品質。 ●整合構建時若出現錯誤、測試自動化過程若出現錯誤結果,亦須立即處理修改。 ●開發人員必須隨時確保自己的工作版本,與目前版本控管資料庫中的程式碼一致。 這些都是作業原則及開發紀律的要求,落實於軟體開發作業更能有效發揮持續整合的精神,執行的方式會因採用的工具不同而做法不一。嚴格說來,對於每個專案成員的現行作業方式並不會有太大的衝擊,也許需要短時間適應一些工具的使用及自動化平臺的建置,但這僅為一次性的短期影響,而且不會投入太高的成本,包括人力及軟硬體需求。 開發團隊每天進行持續整合的作業流程 對於開發人員而言,每天早上上班前會先將版本控管平臺裡最新狀態的程式內容,更新到自己的工作環境中;同時前一天每日建構版本(Daily Build)的作業是否有發出錯誤通知,需要自己立即處理的問題; 接下來隨即進行今日的開發工作進度,檢視問題追蹤系統中被指派的工作項目,進行程式碼的修改及測試。一旦開發好的元件完成自己的單位測試後即交付至版本控管平臺上,若有任何更新交付後的程式碼在自動建構作業過程中有問題,亦會即時收到通知而立即處理。 而專案經理每日亦透過建構平臺所提供的建構結果報告,了解每次建構版本的編譯及測試範圍及結果是否符合預期,當結果出現錯誤時,需及時聯繫涉及的開發人員及時進行問題處理;而在開發進行中,交付程式碼期間出現多人編輯而發生版本衝突時,需要協調相關人員進行程式碼合併作業以利順利交付。而上線版本的決定,則會依據開發進度及測試狀況,部署至其他測試環境,來提供不同的測試目的,以利進行測試。 持續整合的價值何在? 以上利用持續整合的實務做法,最重要的是從已經被壓縮的專案時程中,以系統自動化的方式擠更多的空間出來,讓專案團隊能更從容地做好原本應該完成的工作,甚至可以應對其他千奇百怪的突發狀況。 持續整合實施後,整個軟體開發的進度隨之透明化,每個專案成員隨時都可以確切掌握目前版本的進度及品質狀況,大幅降低以往專案甚多不可知的風險,而對於開發人員亦對自己所撰寫的軟體品質更具信心,確定任何時間所建構的版本,都是可被部署且執行的。 |
2011/07/14
2011/07/14
| 軟體開發永續經營的生存之道 第1回
未能有效落實標準自動化的作業程序,使得程式開發期間產生問題,解決這些狀況時,不僅占用負責人原本的工作,也影響其他工作進度 |
| 場景一:「咦?Roger,昨天加班到幾點才走呀?」
「唉,搞到很晚,程式在開發環境測試都沒問題,結果在SIT環境上build不過,查半天,才發現開發環境的某個JAR檔版本不對,搞好久……」 場景二:「Kevin很早就來了呀?昨天沒回去?」 「是呀,早上系統要上新功能,這次的需求範圍很大,約異動了一百多支程式,怕動到原有的功能,就也將原有的功能都逐一再測過,測試案例實在太多了,得花很多的時間再確認…」 場景三:「咦?Alex還沒要走呀?」 「唉,臨時被通報系統有問題,還在查問題的原因為何。奇怪,今天上版前還好好的呀,怎麼上了也就掛了,也沒改到什麼程式呀……」
軟體開發長久以來常見的痛 沒錯!致命的痛楚,常常是經年累月未明顯改善後的結果。你是否也遇過以下狀況,讓你傷透腦筋: ● 昨天才改好的程式,在整合時發現問題,原本來其他同仁的檔案內容覆蓋了,最糟的是自己也沒備份,必須從頭再來一次。 ● 新功能都已經正式發布了,需求單位才又要求要回復先前的功能,因為沒有版本控管機制,程式碼已找不回舊的版本內容。 ● 自己已經寫好的程式,在自己的開發環境測都沒問題,但丟到整合測試環境時就狀況連連,又得花上不少時間來找原因,不斷反覆測試花費了不少時間,最終還是沒測完整,一些嚴重的例外狀況或異常問題,都是在正式上線後,才逐一浮現。 ● 當程式碼更新到正式環境後,原本可用的功能卻出現異常,最糟的是開發單位並不曉得,而是等到使用者單位反應才知道。 ● 由於時程的關係,多個修改需求必須同一時間一起進行,多人同時修改相同的程式碼區段,使得版本卡住的問題影響開發順暢度,需花上許多時間調整,才可能更新成功。 ● 只要有修改程式就得重新編譯封裝測試部署,以人工不斷執行這些工作的效率不佳,而且容易因無誤而出錯。 上述問題,不外乎都是該標準自動化的作業程序未能有效落實。這些問題,導致需要花上額外的時間來緊急處理,間接又影響其他已經排定的工作,造成開發人員不斷地加班趕進度,不斷出錯,落入永無止境的無窮迴圈。 持續整合的精神所在 首次聽到持續整合(Continuous Integration,CI)的人,對這名詞應該是一頭霧水,其實就是讓軟體專案順利進行的方法,搭配一些系統自動化的工具,落實在開發、建構、測試、部署各個階段,目的在於不斷地透過持續改善的方式,整合團隊投入的資源,讓軟體品質的成熟度更高。 所以近年來在軟體工程方法往輕量化,成果導向化的方向演進後,快速開發已經是現今軟體專案的最重要訴求,才能隨時因應需求面因為劇烈環境的變化。像是敏捷開發(Agile Software Development)、測試驅動開發(TDD)、極限編程(XP)方法論的實作理念中,皆提出持續整合的重要性,可見這種觀念越來越受到重視。然而「快速」不只是開發時間要快,相關的作業程序必須要能提升效率,否則瓶頸仍然無法突破。 只要程式碼內容有異動便整合,持續進行 以往的軟體專案,都會將整合測試時程定義在開發階段的末段,所以,全部的程式碼也是在那個時間點才來進行建置及整合。尤其大型專案的程式碼異動範圍較廣,所需開發時程較長,在整合測試時所會出現的狀況就會顯得有些失控,直接影響專案時程落實的準確性。 持續整合強調的是,開發團隊一旦進行程式碼修改,即刻進行整合測試驗證,好處在於及早發現及早治療,就不會讓整合遇到的問題被延後發現。 妥善的版本控管,包括程式碼及外部函式庫 只要是多人同時運作,必然會有程式碼共同使用的管理問題,所有更新的內容,均必須集中且完整地記錄下來,隨時因應不時之需。 在軟體的發展過程中,版本的分支、合併、回溯、比對,都會因不同的現實需求而受到要求來執行,所以只要你的軟體專案不只一個人開發,就必須建置良好的版本控管平臺。一併將自己開發的程式碼及外部函式庫版本同步納入管理,就可以確保在每個環境的版本一致,避開無法預期的錯誤。 將繁複的人工作業予以標準化、自動化 早期,任何談論軟體工程方法論都會提及這樣的想法,像是單元、整合、迴歸等測試自動化,以及寫程式時即同步撰寫文件、多人平行開發撰寫程式碼、整合測試環境自動構建作業的理想,只是觀念一直沒有配合適當的工具來落實,僅限於紙上談兵的階段。 軟體工程的「工程」兩個字,應該是盡可能將作業程序自動標準化,才能確保品質。實務上卻沒有充分利用系統自動化的機制或工具,反倒是以人力密集來填補這些不斷發生的問題,時間久了當然也身心俱疲。 持續整合觀念即在於解決上述開發環境及反覆流程所發生的問題,並做到「一指定江山」,理想上是做到只要按一個按鈕,系統就會自動進行軟體建構作業,連測試、分析、作業,都一併處理完畢。這樣的概念,目前已經有協同搭配的自動化工具可以協助落實,大幅提升效率。 軟體品質要求的提升 軟體品質的提升可分兩個層面,包括機器及人文。讓機器能運作順暢的程式碼,必須靠著精準且完整的測試作業才能達成,從開發階段的單位測試及整合測試,到使用者主導的情境測試,測試的項目實在太多,必須將重複進行的測試工作透過系統來落實。否則常因為時程壓力忽略測試作業,造成軟體品質低落。 而在人文方面,程式碼本身的易讀性亦是品質關鍵之因。程式碼是不斷由人所編寫修改,而且同一程式是由多人修改的。結合自動化構建作業、同步整理程式碼撰寫風格,並以一致化規範來格式化,能讓開發人員在最短時間拿到程式碼後即刻著手修改,亦是品質要求後所能達到的成效。 專案團隊協同運作更密切順暢 專案的協同運作上,免不了會有丟球、接球的合作狀況出現,就像大隊接力,除每一棒的跑者自身腳程的鍛練外,著重在能否以最短的時間順利接棒,整體團隊花費的時間才能有效縮減。 利用持續整合中所提到的協同運作系統平臺,專案團隊可藉此集中控管所有開發內容,包括所有外部、內部引用之資源,自行開發之程式碼,所有更新歷程均明確記錄;透過自動化的流程結合人工作業,輔以即時性的訊息通知,就可以節省無謂的等待時間,在建構完畢會將過程中出現錯誤的部分,直接派送到負責工程師,以利立即處理掌握時效。 |
2011/07/14
| 網站效能分析操作心法 第7回
若能自學來提升相關專業領域的深度及廣度,也是練就好功夫的不二法門,我想提出覺得具有參考價值的幾本相關書籍,供你搭配閱讀 |
要探索系統效能調校最完整的資料來源,必然是研讀該產品原廠所提供的官方技術手冊,掌握產品特性及技術細節。然而原廠文件大都是英文居多,而且大多撰寫的方式較非以實務角度為出發點,閱讀上未免較枯燥無味。所以,我想提出有參考價值的幾本相關書籍。![]() 系統架構 以效能改善的程度來思考,架構性調整所得來的改善效益會遠比軟體開發面要來得高,但少有書專論整合性網站系統的架構規畫及效能分析,寫得好的更是少數。像筆者早期曾接觸像是《Performance Analysis for Java Web Sites》,就會覺得作者所談論的範圍相當全面,同時見樹又見林的撰寫方式,從系統架構到程式開發都有著墨,對於少有機會接觸廣度較高的專案的人,實為難得。 此書中提到許多實務面相當受用的觀念,像是與網站系統效能有關的硬體及軟體的配置,應用系統開發過程中,針對效能要求的項目如何進行測試,以及測試的標準、依據,選用的測試工具為何、到最後上線時的數據收集分析及後續調校,甚至為進行系統擴充如何執行容量規畫,都有專章說明。 最後在書末附註章節中提供的檢核表格文件,包含各式軟硬體系統的容量規畫、系統上線前的前置測試計畫,以及各式軟硬體系統之效能檢測表,對於從事網站開發的從業人員都是相當實用的參考資料。 而Apress出版的《Pro Java EE 5 Performance Management and Optimization》,所描述的內容,就完全著重在效能管理的完整規畫課題,並非只是談論遇到問題如何解決。作者強調應提前在系統開發設計階段就應列入評核標準,將效能檢測視為軟體產品開發生命周期(PLM)的其中一環,定義標準化的檢測程序,早期發現早期治療。 在軟體專案需求中的非功能面需求,必然會定義到關於系統效能所預期的標準,像是網站系統同時可上線人數、網頁回應時間、單位時間可成立訂單數等。本書從如何定義系統效能檢測作業開始,針對檢測結果優化調校應用伺服器平臺及程式碼內容,反覆驗證達到預期需求標準。而在開發設計階段初期,即考量到應使用的架構及運用技術為何,甚至在系統概念驗證(POC)階段,即確保效能達成的技術可行性,同時考慮到未來容量擴增時的架構彈性(Scalability),並在程式碼撰寫方式及品質要求上,以標準化方式進行,期望將效能問題的風險降到最低。 一旦網站系統上線至正式環境後,更不容許因為效能問題造成服務不佳甚至中斷停機等狀況發生,所面臨的課題則更加嚴峻。為落實良好的效能管理,必須在問題發生之前便能事先預防。本書也專章介紹,關於網站維運階段在各項重點工作上應注意的事項,包括效能檢測作業、異常及障礙排除、系統用量的預測及規畫,作者都提供了明確建議做法,供讀者參考。 網站系統中,作業系統本身的管理也不容忽視,其為所有服務平臺的基石,在未選用良好的作業系統及適當的調校,則直接影響到系統。像是多核處理器架構之運算效能是否有效發揮、磁碟I/O的存取單位及方式等。O’Rielly出版的《System Performance Tuning》,即談論作業系統面與硬體資源的配置,協助你揭開底層系統運作架構的神秘面紗、清楚掌握運作原理,並透過有效調校,打好底層環境基礎。 系統設計 不良的系統設計造成未來效能問題的機率甚高,討論系統設計面的專書就較常見,而Addison Wesley出版的Effective系列叢書,能針對不同技術領域提供優化設計的進階建議。較知名的像是Addison Wesley的《Effective Enterprise Java》、《Effective Java,2nd》都討論到系統設計及程式撰寫面如何優化效能。 而軟體專案在為滿足需求功能的同時,亦需同時以具效率的設計方式來實作開發,《Effective Enterprise Java》著重在J2EE平臺軟體架構設計時的實務技巧,分別針對軟體架構、資料傳遞、邏輯運算、資料狀態管理、介面呈現、系統核心及安全等層面探討,舉出共75項設計原則供讀者參考,可算是伺服器端效能改善設計上十分完整的介紹。《Effective Java,2nd》則更著重Java程式撰寫本身應秉持的原則。若要寫出高效能的程式,不但要充分了解程式語言本身的特性,另外便是以良好的演算邏輯來處理問題。這裡廣泛提及JDK套件正確的使用方式、物件設計及操作的方法,以及適當時機運用合適的資料結構及程式語法,總共提出78項建議。 網站優化 像是O’Rielly先後出版的《High Performance.Web Sites》、《Even Faster Websites》,則是主要探討網頁構成元素如何優化呈現及縮短回應時間的專書,包括程式撰寫要點及網頁伺服器配置時要求。其中《High Performance Web Sites》列出的十四項黃金法則,亦結合在網站效能檢測工具YSlow中,你可以利用這套工具找出效能問題,然後搭配書中的建議解法來改善,有助於實務應用。作者Steve Souders有鑑於新一代網站技術發展的挑戰,再撰寫《Even Faster Websites》針對JavaScript運用方式、網路回應時效、瀏覽器效能提升等三大方面,提出更進階的效能改善建議。書中對於每項提出的建議解法,都佐以實際驗證測試的圖表結果來說明,明確告知實作方式的成效顯著,並非紙上談兵。 目前網站系統使用JavaScript來進行介面設計及資料傳遞的比重大增,雖然不見得會直接影響伺服器效能,但多少也會影響用戶端網頁的反應效率。O’Rielly出版的《High Performance JavaScript – Build Faster Web Application Interfaces》,也談論如避免因介面效果的要求而忽略了效能考量,像是JavaScript執行的原理介紹、資料處理及DOM文件的操作方式、邏輯運算優化建議,以及Ajax設計時需要留意的重點,這些都值得開發人員實作時參考。 資料處理 當網站系統遇到效能瓶頸,有很高的比重都是發生在資料庫身上,無論是資料庫系統的調校或是SQL指令的優化,都不斷地被提出、討論。就資料庫系統方面的調校,像是近期碁峰出版的《Oracle DBA手記:資料庫診斷案例與效能調校實戰》,內容有別於以往的資料庫相關書籍,集結作者一線實務經驗淬練而成,值得一探究竟。 SQL指令雖然簡單,但使用不當也可以將整個資料庫系統搞掛。O’Rielly、Addison Wesley都曾出版SQL Tuning相關書籍,像是《SQL Tuning》、《SQL Performance Tuning》都是探討如何正確使用SQL指令的專書。開發人員必須建立良好資料處理的觀念,不是單純資料產出正確即可,進一步再思考是否還有更有效率的撰寫方式來提升效能。 |
2011/07/14
| 網站效能分析操作心法 第9回
CPU、記憶體及I/O存取效率會影響資料庫系統效能,而這與資料存取的方式大多脫離不了干係 |
資料庫系統效能出現問題時,追蹤到最後,常會發現是因為某個SQL指令未加以優化而造成。水能載舟亦能覆舟,如何在效能優化的考量下達成資料存取的需求?![]() 資料可攜性設計考量的迷思 在一些最佳實踐方案的設計建議,或是J2EE架構設計藍圖中,對於資料處理的邏輯設計都會強調可攜性(Portability)考量的重要。可攜性考量的主要觀點,在於將資料處理邏輯實作在商業邏輯層,而不以資料庫特有之機制來處理(像是採用Stored Procedure、Trigger等),以免未來在更換資料庫系統時,保有系統移植的平順度,不會因此而需要重新撰寫資料庫端的邏輯處理作業。這樣的思維立意甚佳,也有不少將之奉為圭臬,將資料庫提供的強大功能棄之不用,而依賴在不易處理複雜資料處理作業的持久層(Persistence Layer)軟體框架上。 透過持久層進行資料庫存取,美其名是表揚物件封裝的精神,符合軟體框架設計的理念,實則有如隔靴搔癢,無法有效掌握資料存取的方式。持久層以未被資料庫系統認定的較佳方式存取資料庫,理所當然在效能表現上必然不會比直接以撰寫SQL指令來得佳。若是需要進行多個資料表關連的查詢時,這樣的問題更會被突顯出來。 就實務上而言,資料處理效能的最佳化,勢必是直接使用資料庫系統所提供自身的執行環境及程式語言,才能將資料處理作業效率提到最高。這樣的設計少了應用伺服器與資料庫之間的資料傳輸時間,降低因連線中斷造成交易作業異常的風險。 找出問題SQL進行改善 針對SQL命令的改善作法,可以搭配資料庫系統所提供的分析工具來先了解主要造成執行效能問題的環節,像是Oracle的Explain Plan,或是MS SQL Server的執行計畫,讓我們可以分析得出SQL命令預計在執行過程中,所進行的處理步驟及可能花費的時間及成本。從這裡得出的分析結果,可以快速找出改善的點,最常見的便是出現Full Table Scan的項目,勢必得建立適當的索引來加速處理。 實務上會避免一些SQL撰寫用法,像是: ● 避免用LIKE方式查詢,會造成資料庫的Full Table Scan,成本甚鉅。 ● 進行多個資料表關連查詢時,在SQL指令中WHERE後的資料表名稱順序,建議資料量由大至小來依列排放。 ● 查詢條件中避免直接使用函式或運算結果當成是過濾條件,在指令處理上會多一些處理程序而造成成本較高。 ● 盡可能不要在同一個SQL指令中,使用多層次查詢(sub-query),若必要時,以增加條件來減少次查詢中回傳資料筆數。 批次處理程式的設計原則 若批次作業主要為查詢報表的產出,需要留意執行時間是否避開網站用量尖峰時間。若為大量資料異動作業,盡可能是每異動一小批資料即回寫乙次(commit),因為異動資料的作業在尚未commit之前,該資料是會被系統進行鎖定處理(data lock),若當時正好有其他程式需要異動同一筆資料時,則會進入等候狀態,就會造成整體處理時間過長。 妥善規畫網站後臺功能 就設計上而言,網站前臺的頁面瀏覽方式,其對資料庫存取的方法重複性較高,對應到SQL指令的語法也較能在預期的範圍內,所以SQL語法上較比較能享受到因調校後所帶來的效能改善。例如常見的動態網頁設計,會傳入不同的編號代碼來取出對應的文章內容,或是以商品編號來顯示不同商品頁面的購買資訊。以這樣的資料模型架構下,建立對應的索引鍵值,以及查詢快取的機制,都可有效發揮,明顯改善網站的資料存取效能。 而後臺系統必須同時提供CRUD多種資料操控功能,而且為求方便管理人員作業便利,會透過多種join的方式來參照多個資料表,讓使用者可以在較少的點擊數下完成所預期的資料查詢或處理作業。像是提供地址縣市鄉鎮區域的下拉連動選單,點選商品分類時同時呈現屬於該分類下的所有商品,或是查詢某特定會員基本資料時,需要同步查詢其訂單交易資料及客服記錄等。這些資料關連的操作,都遠比前臺提供給一般使用者的頁面功能,成本來得高上許多。 為求對線上資料庫的衝擊降到最低,就實務面的設計上,以下是幾點在設計時可以參考的做法: ● 盡可能不要在單一網頁,呈現過多需要透過資料表關連才能得到的資料。就使用者行為而言,不見得每次頁面呈現,都需要閱讀到頁面上的所有資訊,以額外的連結提供進一步查詢,在真正需要顯示時再進行查詢,可以省下額外處理成本。 ● 較複雜的資料存取功能,以權限控管的方式僅提供少數人員使用。一些特定的複雜操作功能可利用有效管控的方式減少使用者的使用次數及頻率,以免不當操作直接影響資料庫效能。 ● 在管理操作介面上要求輸入較多的查詢條件,才允許進行作業。像查詢功能最忌諱的是,使用者不下任何條件即送出查詢請求。對於像是訂單查詢功能,必須同時提供兩項以上之查詢條件,才允許送出處理,可以避免單次查詢時所回傳的資料量過多,而造成效能不彰。至於查詢條件要多少才允許放行,則需再考量涉及的資料量多寡而定。 ● 運用使用介面上的防呆設計,以免被不當重複執行。實務上常見到使用者因系統反應時間較長,會利用不斷重整網頁或重複按下送出,而造成主機端進行無謂的多次處理。若能套用防呆設計,可以阻擋因無意的點擊而產生的動作。像是在表單資料送出時,原送出按鍵予以失效,或是在按下送出時,利用CSS圖層方式來顯示執行中的提示,以防重複點選。 ● 統計彙整型報表,避免對線上資料庫直接操作。像是周期性報表,需要透過大量彙總運算資源的報表內容,不宜直接利用線上環境的資料庫來產生,建議另外妥善設計資料匯出的功能,提供使用者自行下載原始資料,由他們自行透過Excel等工具製作進階的圖表,可以省去龐大系統代價。 |
2011/07/14
| 網站效能分析操作心法 第8回
資料庫常是網站系統的最後防線,也容易成為所有效能問題的根源點。在設計初期,若能避開造成常犯錯誤,未來改版就能省下可觀成本 |
| 現今網站不跟資料庫扯上關係的實在少之又少,而資料庫本身的管理及設計也是常造成效能瓶頸的主因,相關主題實在太多,此篇幅不足涵蓋全數,本篇將針對資料庫設計時在實務面上較常遇到的議題進行探討。
就資料庫設計而言,資料正規化在教科書中亦視為重要課題,不外乎在強調資料重複性及一致性的維護;相對地,當正規化得愈徹底,未來資料查詢時需要進行join的頻率就會很高。但就實務而言,過度的正規化反倒是造成效能瓶頸的主因,尤其當個別資料表格內含龐大資料量時,多項資料表格進行join時,所付出的系統資源成本是相當可觀的。 資料正規化固然能解決資料面重複不一致的問題,以達到有效規畫及善用儲存空間的基本精神,但就資料存取的效能考量而言,有時適度的重複資料,反倒能減少因為頻繁join所需付出的系統成本。而重複資料可以透過其他機制來控制,或是由定期的資料維護檢核機制來處理,以磁碟空間換取時間。所以「反正規化」的做法是可接受的,尤其是在系統效能要求較高的環境下。 反正規化的想法也可以結合到非資料庫的儲存媒介,因為不見得網頁上所要呈現的所有內容都必須儲存在資料庫中,適時將部分的資料內容以檔案的方式來配置存放,亦對執行效能有加分效果。尤其是針對內容長度較大的資料,像是購物網站的商品說明內容,就可以透過此種方式設計實作。 資料庫與檔案的設計決策 若你所負責的網站系統是對Internet上的所有使用者提供服務,它的特性在於你永遠無法精準預估可能發生的流量有多大。若將所有網站上所需的資料都以資料庫的方式存取,流量低時不會有什麼問題,而流量高時就有明顯差異了。 就儲存媒介的資料存取效能而言,記憶體優於檔案,檔案勝於資料庫。這些儲存媒介的單位成本與使用時機也都不同,所以若你所規畫的網站系統是對外服務,在同一時間所造訪的人數是無法預估的,而偶爾會有尖峰時段。你可以觀察一些知名高流量的網站,會發現站上大多數的頁面會以靜態頁的方式來處理,也是想解決尖峰流量發生時不會因為系統資源的過度耗用而造成網站效能不佳。 透過以下幾點使用原則來評估,可以協助你資料設計時,去評估使用哪一種儲存媒介較佳: 1. 資料內容被前端使用的方式,是唯讀或是會被異動。若資料內容主要是做為網頁唯讀呈現(像是新聞內容、部落格網站、企業門戶網站等),僅允許由管理後臺進行資料更新,我建議這些內容可以利用檔案的方式來儲存。 2. 資料被異動的來源及頻率。異動的頻率也可視為決定儲存方式的考量點,像是企業網站的服務內容及產品訊息,異動頻率不高,就可以透過簡單的檔案方式來做為主要儲存方式;然而異動資料的來源單純,而非開放式供所有使用者可異動,則可以透過資料流程的設計來控制異動點。 3. 資料未來被管理及操作的方式。所有資料都放在資料庫,主要是方便未來進行資料分析所使用,但實務上的規畫並不會對線上資料庫進行較複雜的報表產出或資料分析,一般都是採用資料庫複寫機制(Replication)抄寫到別的資料庫中,或是將部分資料轉入到另外的系統進行後置報表產生作業,這麼做,主要在於避免線上直接查詢所造成的效能影響。 舉個實例,就內容網站而言,管理者可以透過後臺的管理介面,定義整個網站的內容分類架構,這些資料內容可以儲存到資料庫中,但前臺的網頁呈現,我建議另外產生檔案方式來提供瀏覽網頁的呈現,而不由前臺的網頁程式直接存取資料庫。 另外像是許多網站提供的個人化網頁內容,其內容呈現需要透過資料庫的運算統計得出的數字(像是未讀取的訊息數、未支付的訂單數、累積紅利點數等),在設計上應避免直接即時查詢資料庫運算得出。我建議以檔案儲存這些運算好的結果,來供前臺的快速呈現,而這些檔案內容被異動的時間點,則可以考慮定期批次整體更新,或是當資料庫異動時一併更新的方式,來達到資料異動。 資料表索引建立原則 索引的建立,不外乎是為了加速資料查詢以及排序時處理的效率,而原則主要依據查詢命令所要求的條件,將需要的查詢或排序欄位列入建立索引欄位的關鍵值。而建立為索引的欄位,必須配合前端程式存取資料的行為來建立,才能適時發揮效用。 若資料表本身會發生大量INSERT作業,則過多索引的建立反倒造成較高的效能成本,而且相關資料表必須定期維護,所以要評估資料表存取的方式來建立適當的索引,才不致於造成反效果。而資料表的Join關聯欄位,也是建立索引的重要對象,尤其是被join的資料表含有較大量的資料時,對明顯提升join時比對運算的效能有利。 資料空間的有效管理 資料表在經過長時間不斷插入及刪除動作後,像是購物網站的購物車內容,對該資料表的索引結構與實體磁碟結構的排列及對應位置,會造成不一致的狀況,甚至會有部分空間未能有效運用的狀況,占用較實際資料量為高的磁碟空間,造成索引存取效能低落的現象。 若資料表的資料異動頻率甚高,資料量亦居高不下(一般而言,是同一個資料表超過十萬筆以上的資料量),索引結構的重整,便是系統日常維運時所需重視的定期維護作業。可以透過資料庫系統提供的重建索引命令(rebuild index),或是透過索引移除、再重新建立的方式進行,亦可達到重整索引的效果。 而資料表本身的空間亦會因而無法有效運用,造成空間碎塊(Defragment)。利用資料庫本身的空間壓縮(Shrink)機制,可有效整理出未使用空間以提高空間使用率,而這個動作已成為資料庫備份之前的必要程序,甚至在建立資料庫時就設定成自動壓縮,以保持資料庫的壓縮比在一定的使用水平。 資料量分散移轉作業 網站系統運作一段時間之後,部分功能可能會因為資料量的成長而發生效能上的問題,針對資料量較大的資料表,可以考慮將存取頻率較低的部分,分散到另外的資料表,以有效保持原本資料表的資料存取效能。像是購物網站前臺,若提供會員查詢近半年的訂單資料,所以在訂單主檔的資料表便只保留時間範圍內的資料,其他可移至其他資料表。 不過這是土法煉鋼法,必須自行額外觀察資料的成長量,定出合適的時間範圍區段。若你的資料庫系統支援區段資料表(partitioning table)的機制,這部分的作業就單純許多,僅需要設置該資料表即可,未來該資料表便會依設置進行實體檔案空間的分散配置,以利一定品質的存取效能。就虛擬而言,上述做法仍然是針對同一個資料表進行操作,而實體資料檔案則會依設定時的定義進行切割。好處則是應用程式不需要針對不同的資料表進行存取。 |
●研讀了不少軟體工程的書,像UP、Agile、XP、Scrum等觀念都很棒,但真的專案在進行時,還是不知道要如何套用進來?