擴充性專家 Sean Hull 整理了幾項對於系統擴充性(Scalability)與效能(Performance)的致命傷,如果你的系統或程式想要有好的擴充性,請避免這幾種狀況。

不要用 RAID 5 與 Multi-tenant EBS

硬碟是伺服器中一個很基本的硬體設備,而它與伺服器的整體效能息息相關,縱使現在記憶體價格低廉,你可以在伺服器上裝載非常大容量的記憶體,藉以提升系統的執行速度,但無可避免的,系統還是常常需要從硬碟讀取資料或將資料再寫回硬碟中儲存,因此硬碟在伺服器的效能(performance)與可擴充性(scalability)上扮演舉足輕重的角色。

磁碟陣列是一般伺服器中常用的資料儲存方式,透過這樣的方式可以提高儲存的讀寫速度、增加資料的可靠度。磁碟陣列分為好多種,但不是每一種都那麼適合你的伺服器來使用,像一般常聽到的 RAID 5 磁碟陣列就有一些問題。

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 5 有這些問題,那該怎麼辦呢?答案是可以改用 RAID 10(也稱作 RAID 1+0),它總共是使用四顆硬碟,先做兩組 RAID 1(鏡射),然後再合起來做 RAID 0(分割)。

RAID_10

RAID 10 對於資料的讀取與寫入都有不錯的效能表現,而在可靠度上也比較沒有問題。

什麼是 Multi-tentant?

在雲端的架構中,通常很多用戶會共享伺服器(server)、網路(network)與儲存(storage),就像公寓中的每個住戶都會共享大樓中的公共設施一樣,這樣的概念就是 multi-tentant(中文應該是翻譯成「多重租戶」)。

亞馬遜(Amazon)的 EBS(elastic block storage)拓展了這個概念,提供一個共享的網路儲存系統,雖然很方便,但是瓶頸到後來就會發生在同一區段的網路用戶,要搶奪有限儲存資源的問題。

一般的伺服器通常都會出現這類的問題,不過 Amazon 宣稱它們已經使用了鮮為人知的 Provisioned IOPS 技術克服了這個問題,詳細的內容,可以參考 Amazon EBS 的網頁

避免使用 MySQL 實作佇列(Queuing)

MySQL 資料庫在許多的應用上是一個好用的工具,但它不適用於實作應用程式的佇列。在你的資料庫中,是否有類似儲存工作的表格(table)?而這個表格的狀態欄位(status column)所儲存的值大概是像「等待」(queued)、「執行」(working)與「完成」(completed)等,如果你發現你的資料庫中有這樣的表格,那麼你其實很可能就是使用資料庫來實作佇列。

rabbiymq

由於資料鎖定與搜尋的問題,這樣的儲存方式是不適當的。如果需要佇列的功能,其實可以改用 RabbitMQ 這個資料庫,它就像 Amazon 的 SQS ,非常適合用於佇列的情況。

避免使用 MySQL 實作全文搜尋(Full-Text Searching)

Oracle 資料庫本身就有全文搜尋的功能,那位什麼 MySQL 中不能按照一樣的方式使用呢?其實 MySQL 本身也是有這樣的功能,但是在許多只有老舊 MyISAM 儲存引擎(storage engine)的 MySQL 資料庫中,使用全文搜尋會產生一些問題,另外它也不是很有效率。

solr_logo_rgb

比較好的方式是使用 Apache Solr,他是專門設計用來搜尋的資料庫平台,提供各種語言的 API 給開發者使用,最棒的是它很好擴充,資源不足時,只需要增加伺服器就可以了。

有些人對於開發中(bleeding edge)的東西比較感興趣,新的 MySQL 5.6 中,Innodb 雖然有全文搜尋的功能,但還是有一些問題存在,這也就是說現在如果你想使用全文搜尋的功能,還是改用 Solr 或是 Sphinx 配合 MySQL Sphinx SE plugin 會比較好。

使用快取(Cache)

快取是一個可以增進應用程式與系統效率的方式,這個方式可以應用在很多地方,包含伺服器上與使用者端。

Memcached

在你的應用程式與資料庫之間使用 Memcached 快取,可以有效減少不必要且重複的資料庫查詢,那些查詢過的資料將會放在記憶體中儲存,當下一次需要時就可以直接提供,省去後續的資料庫查詢動作。

Varnish Cache

在網頁伺服器與使用者之間使用 Varnish Cache 快取伺服器,它可以安裝在任何使用 HTTP 通訊協定的網頁伺服器上,其作用類似代理伺服器的功能,它的執行效能很高,可以減輕網頁伺服器的負載,並加速伺服器回應使用者 request 的速度,根據 Varnish Cache 官方的說法,它可以加速 300 至 1000 倍的反應時間,加速的程度會因為伺服器架構的不同而有不同的加速倍率。

下面這個是 Varnish Cache 的一段說明影片,透過這段影片可以更了解 Varnish Cache 的作用。


瀏覽器快取(Browser Caching)

瀏覽器的快取也是很重要的功能,但是通常你無法控制使用者的瀏覽器,你能做的大概只有設定適當的 expires 標頭,決定哪些網頁內容應該被瀏覽器存進快取中。

在 Apache 網頁伺服器中,可以藉由 mod_expires 模組來對一些靜態資料在瀏覽器快取中存放的時間,例如圖片、CSS 或 JavaScript 檔案都可以利用這樣的方式設定。設定方式可參考 Tsung’s Blog

繼續閱讀:提高系統與程式擴充性(Scalability)與效能(Performance)的十個方法(二)