擴充性專家 Sean Hull 整理了幾項對於系統擴充性(Scalability)與效能(Performance)的致命傷,如果你的系統或程式想要有好的擴充性,請避免這幾種狀況。
硬碟是伺服器中一個很基本的硬體設備,而它與伺服器的整體效能息息相關,縱使現在記憶體價格低廉,你可以在伺服器上裝載非常大容量的記憶體,藉以提升系統的執行速度,但無可避免的,系統還是常常需要從硬碟讀取資料或將資料再寫回硬碟中儲存,因此硬碟在伺服器的效能(performance)與可擴充性(scalability)上扮演舉足輕重的角色。
磁碟陣列是一般伺服器中常用的資料儲存方式,透過這樣的方式可以提高儲存的讀寫速度、增加資料的可靠度。磁碟陣列分為好多種,但不是每一種都那麼適合你的伺服器來使用,像一般常聽到的 RAID 5 磁碟陣列就有一些問題。
RAID 5 這種磁碟陣列本來是設計讓你可以使用較少的硬碟,得到較大的儲存空間,這樣的設計其實主要是用於硬碟插槽不足的伺服器,但有些人不了解它效能有多差,所以造成誤用的狀況,如果在作為資料庫的伺服器中使用 RAID 5,其效能影響更是嚴重。
RAID 5 不是對儲存的資料進行備份,而是把資料和相對應的奇偶校驗訊息儲存到組成 RAID 5 的各個磁碟上,並且奇偶校驗訊息和相對應的資料分別儲存於不同的磁碟上。當 RAID 5 的一個磁碟資料發生損壞後,可以利用剩下的資料和相應的奇偶校驗訊息去恢復被損壞的資料。
RAID 5 可以理解為是 RAID 0 與 RAID 1 的折衷方案。RAID 5 可以為系統提供資料安全保障,但保障程度要比鏡像低而磁碟空間利用率要比鏡像高。RAID 5 具有和 RAID 0 相近似的資料讀取速度,但是因為多了一個奇偶校驗訊息,寫入資料的速度相當的慢。
在 RAID 5 的磁碟陣列中,每次的硬碟寫入時都會對效能有影響,此外如果你的硬碟陣列中有一顆硬碟壞掉了,這時候雖然 RAID 5 還是在運作,但它會變得很慢(感覺像當掉一樣),這對於效能的影響就很大了。另外如果要重新建立 RAID 5 磁碟陣列也非常耗時,如果在重建完成之前,又有另一顆硬碟損壞了,那資料就沒救了。
RAID 5 有這些問題,那該怎麼辦呢?答案是可以改用 RAID 10(也稱作 RAID 1+0),它總共是使用四顆硬碟,先做兩組 RAID 1(鏡射),然後再合起來做 RAID 0(分割)。
RAID 10 對於資料的讀取與寫入都有不錯的效能表現,而在可靠度上也比較沒有問題。
在雲端的架構中,通常很多用戶會共享伺服器(server)、網路(network)與儲存(storage),就像公寓中的每個住戶都會共享大樓中的公共設施一樣,這樣的概念就是 multi-tentant(中文應該是翻譯成「多重租戶」)。
亞馬遜(Amazon)的 EBS(elastic block storage)拓展了這個概念,提供一個共享的網路儲存系統,雖然很方便,但是瓶頸到後來就會發生在同一區段的網路用戶,要搶奪有限儲存資源的問題。
一般的伺服器通常都會出現這類的問題,不過 Amazon 宣稱它們已經使用了鮮為人知的 Provisioned IOPS 技術克服了這個問題,詳細的內容,可以參考 Amazon EBS 的網頁。
MySQL 資料庫在許多的應用上是一個好用的工具,但它不適用於實作應用程式的佇列。在你的資料庫中,是否有類似儲存工作的表格(table)?而這個表格的狀態欄位(status column)所儲存的值大概是像「等待」(queued)、「執行」(working)與「完成」(completed)等,如果你發現你的資料庫中有這樣的表格,那麼你其實很可能就是使用資料庫來實作佇列。
由於資料鎖定與搜尋的問題,這樣的儲存方式是不適當的。如果需要佇列的功能,其實可以改用 RabbitMQ 這個資料庫,它就像 Amazon 的 SQS ,非常適合用於佇列的情況。
Oracle 資料庫本身就有全文搜尋的功能,那位什麼 MySQL 中不能按照一樣的方式使用呢?其實 MySQL 本身也是有這樣的功能,但是在許多只有老舊 MyISAM 儲存引擎(storage engine)的 MySQL 資料庫中,使用全文搜尋會產生一些問題,另外它也不是很有效率。
比較好的方式是使用 Apache Solr,他是專門設計用來搜尋的資料庫平台,提供各種語言的 API 給開發者使用,最棒的是它很好擴充,資源不足時,只需要增加伺服器就可以了。
有些人對於開發中(bleeding edge)的東西比較感興趣,新的 MySQL 5.6 中,Innodb 雖然有全文搜尋的功能,但還是有一些問題存在,這也就是說現在如果你想使用全文搜尋的功能,還是改用 Solr 或是 Sphinx 配合 MySQL Sphinx SE plugin 會比較好。
快取是一個可以增進應用程式與系統效率的方式,這個方式可以應用在很多地方,包含伺服器上與使用者端。
在你的應用程式與資料庫之間使用 Memcached 快取,可以有效減少不必要且重複的資料庫查詢,那些查詢過的資料將會放在記憶體中儲存,當下一次需要時就可以直接提供,省去後續的資料庫查詢動作。
在網頁伺服器與使用者之間使用 Varnish Cache 快取伺服器,它可以安裝在任何使用 HTTP 通訊協定的網頁伺服器上,其作用類似代理伺服器的功能,它的執行效能很高,可以減輕網頁伺服器的負載,並加速伺服器回應使用者 request 的速度,根據 Varnish Cache 官方的說法,它可以加速 300 至 1000 倍的反應時間,加速的程度會因為伺服器架構的不同而有不同的加速倍率。
下面這個是 Varnish Cache 的一段說明影片,透過這段影片可以更了解 Varnish Cache 的作用。
瀏覽器的快取也是很重要的功能,但是通常你無法控制使用者的瀏覽器,你能做的大概只有設定適當的 expires
標頭,決定哪些網頁內容應該被瀏覽器存進快取中。
在 Apache 網頁伺服器中,可以藉由 mod_expires
模組來對一些靜態資料在瀏覽器快取中存放的時間,例如圖片、CSS 或 JavaScript 檔案都可以利用這樣的方式設定。設定方式可參考 Tsung’s Blog。