痞客邦,原本只是交大校園內的社群網站, 2003年轉變成商業化營運的公司,目前有300多萬個註冊會員數,總共累積了1億張照片,1億2千萬篇文章。由於痞客邦的服務原生於學校,而大多數的校園環境,都不會花費鉅資去買商用資料庫,痞客邦也不例外,當時,很自然地就採用了開源資料庫MySQL。

不過,痞客邦在2008年進行全站大改版,並且重新評估資料庫平臺,在多款商用資料庫和開源資料庫之間選擇,最後仍舊決定使用MySQL。痞客邦評估,一方面是因為既有人力已經具備相關經驗,另一方面也看到國外知名的大型部落格網站,例如WordPress,也是採用MySQL資料庫。再者,MySQL相關技術資源的取得也非常便利,使用時遇到任何問題,比較容易取得相關資源來解決。當時,雖然已經有人提出不同於關聯式資料庫的NoSQL資料庫,但是還沒有真正的實作案例,痞客邦也不打算冒然採用NoSQL。

值得一提的是,痞客邦雖然一直都是用MySQL資料庫,但是,部署架構卻一直隨著服務狀態調整,痞客邦研發副理林瑞男表示,痞客邦經歷多個發展階段,從最早期的主從(Master/Slave)架構,逐漸發展到現在的Active/Active架構,未來,還計畫將資料庫的主程式轉換到叢集架構MySQL Cluster,並期望藉此徹底做到資料一致性與可靠性。

 分階段部署MySQL 

階段1  Master/Slave架構讀寫分離,降低Master主機負載

痞客邦創立初期,資料庫的設計是採取主從(Master/Slave)架構,並沒有考量到高可用性。林瑞男表示,這種架構的好處是,讀取與寫入分別由不同主機負責,因此,當使用者端的資料寫入Master主機後,會進一步複寫到Slave主機,等到使用者端需要讀取資料時,就可直接由Slave主機回應,藉此達到降低Master主機負載的目標。

然而,這種架構的設計,因為只有一臺Master主機,沒有考量到高可用性,只要Master主機發生故障,就會影響到網站服務。

階段2  用Active/Standby搭配DRBD套件,確保資料一致性與可靠性

為了解決這個問題,痞客邦在2008年改版時,決定轉向高可用性架構發展,同時並採取Active/Standby做法,成為痞客邦採用MySQL以來的第二個階段部署架構。這個時期的痞客邦,將資料儲存在兩臺不同的主機上,解決了Master/Slave架構的問題,但是,礙於Active/Standby架構的限制,又產生另一個新的問題。

也就是當Active主機發生故障時,轉由Standby主機接手的過程,痞客邦當時一個叢集的資料量,大約會需要15分鐘時間,才能將資料從備援主機硬碟中,重新載入到記憶體中正常運作,期間,網站服務品質大受影響,舉凡網頁顯示速度等,都因為硬碟I/O出現瓶頸而變慢。

對痞客邦來說,資料庫的設計,除了必須考量效率運作之外,資料一致性也非常重要,尤其當伺服器主機故障時,使用者資料能否完全且正確地寫入,至為關鍵。

為了達到這兩個目標,痞客邦除了將MySQL的部署架構,轉換到Active/Standby架構後,還進一步搭配使用Linux平臺的分散式儲存模組DRBD(Distributed Replicated Block Device),也就是類似磁碟陣列的RAID 1,不過,RAID 1是在同一臺電腦內執行, DRBD則是透過網路,來確保資料一致性與可靠性。

由於Active/Standby架構搭配DRBD的做法,是將兩臺伺服器主機的網路卡,經由1G專線串接,然後把兩臺伺服器主機硬碟建置成RAID 1,當資料寫入A主機時,B主機也會同步寫入,中間沒有經過任何交換器等設備,而是經由網路專線來達到資料同步,因此,可以避免交換器故障或是交換器端頻寬滿載等問題,進而保證資料的一致性與可靠性。

階段3  Active/Active與Active/Standby架構同時並存

2009年,痞客邦又從Active/Standby架構,延伸到Active/Active架構。

林瑞男表示,雙主機平行運作架構的好處,是所有資料都同時寫入兩臺不同主機的記憶體中,當其中一臺主機故障時,另一臺主機可以及時接手,能減少資料從硬碟重新載入到記憶體中的過程,大幅提昇網站營運的系統效能。

不過,Active/Active的架構設計,是為了縮短主機切換的作業時間,因此,具有資料同時寫入的特性,這個架構的特性,無法一體適用於痞客邦,尤其是金流等,這類對資料一致性要求非常高的服務,痞客邦必須要確保資料一致性,絕對不能有同時寫入的狀況發生。

為了確保資料一致性,痞客邦一方面只對同一臺進行讀寫,再複寫到另一臺主機,讓所有的新增、修改、刪除都對映同一臺主機;另一方面,痞客邦也特別開發了應用程式,每週固定檢視兩臺主機的資料是否一致,當兩臺主機資料不一致時,就將負責讀寫的主機資料,重新複寫到另一臺主機上,進而確保兩臺主機的資料一致性。

林瑞男認為,一個好的MySQL架構設計,必須根據服務特性來調整設計。在Active/Active的架構下,如果沒有採用只對同一臺主機讀寫,再複寫到另一臺主機的做法,當一筆交易處理正在執行時,就必須把所有資料表鎖死(Globalize Lock),才能避免資料重複寫入的問題。

然而,在Active/Active的架構下,為了要做到資料一致性,必須付出的成本也非常高,以痞客邦的資料量來說,就需要固定配置一個人力,專責監控兩臺主機的資料一致性。為了盡可能近低成本,痞客邦決定只將對資料一致性要求高的部分服務,例如金流等,以Active/Standby架構來因應。

 MySQL秘技大公開 

秘技1  2種改善MySQL資料庫效能的做法

痞客邦有兩個改善MySQL效能的做法,一個是資料切割搭配專用應用程式來改善特定服務的存取效能,另一個是善用監控工具來調校資料庫效能。

對於MySQL資料庫的擴充,痞客邦的做法,是以資料切割來達到擴充目的,不過,採用資料切割這種模式,有許多問題必須事先考量,然後才能依據不同的服務屬性,搭配不同的做法,讓資料庫在有效率的情況下運作。

對於網站業者來說,頁面生成的速度,是效能監控的重要指標,一般情況下,痞客邦每天都透過系統自動產生一份報表,來檢視網站服務的回應速度,當報表中所呈現的數值,已經到達原本規畫目標,舉凡頁面生成時間、每個叢集當中的文章量、尖峰時間的QoS等,都可能驅動痞客邦進行資料切割。

由於資料切割的做法,是將資料儲存在不同的資料庫上,當資料分散儲存在不同的叢集時,如何解決跨叢集搜尋問題,才能呈現關聯式分析結果,是資料切割會面臨的挑戰。

以文章排行榜的服務為例,痞客邦為了提供最新100篇文章這個服務時,由於文章內容分布在不同叢集,一般標準做法,必須彙整各叢集資料,才能排序出最新的100篇文章,不過,這樣的做法並不是很有效率。因此,痞客邦另外開發一個程式,當有人發表文章時,就直接寫入這個資料表,讓這個資料表永遠儲存最新的100篇文章,然後將這個資料表的文章內容,作為頁面內容顯示的根據,這種做法,可以讓程式的寫法變得比較簡單,同時也能讓資料庫的運作更有效率。

此外,痞客邦也會用MySQL內建的Slow Query工具,從Log去分析Query的效率,然後決定改善效能的做法,究竟是要重新調整資料索引的設計,還是改寫Query程式。有時候,程式開發人員在寫Query程式的時候,無法預期長遠營運需求,所以,會有重新改寫Query的情況。另一方面,也會因為某個Query原本的使用頻度低,所以,沒有建立索引,但是後來變得比較常用, 就必須考慮把這個Query加入索引。

秘技2  選用InnoDB儲存引擎更能有高可用性

目前MySQL平臺的兩大儲存引擎,一個是InnoDB,另一個MyISAM。根據痞客邦的經驗,如果MySQL的部署,需要考量高可用性,資料儲存引擎搭配使用InnoDB的效果,會比MyISAM好。

因為InnoDB有Crash Safe的功能,當主機發生故障時,可保證還在處理的資料能完全寫入,而且具有一致性。InnoDB之所以能夠做到,是因為每一筆資料寫入時,InnoDB也會同步產生Log檔案,並且儲存在硬碟內,當主機發生故障,出現不正常開機時,InnoDB就會自動去檢視Log檔,然後進行資料比對,並且修復資料,來確保資料能夠完全寫入資料庫。

MyISAM的特性,則相對有風險,並且在主機故障時,可能會出現資料不一致的問題。

此外,InnoDB支援交易功能(Transaction)的特性。也是痞客邦在部署MySQL平臺時,一個非常重要的應用。Transaction這個功能,可保證每一筆交易的相關資料,能夠同步更新。當同一個資料庫中,有兩個資料表互相有關聯,當A資料表更新,B資料表也必須更新,為了保證這兩個資料表同步更新,就必須使用InnoDB的Transaction這個功能。

以新增訂單這個交易來說,當一筆訂單確認之後,庫存數量就必須減一,這種Transaction屬性只能同時成功或同時失敗,否則就會有訂單量與庫存量無法對映的問題。因應這種Transaction型態的資料處理,由於InnoDB的做法是採取Row Locking(行鎖定),MyISAM則是採取Table Locking(資料表鎖定),而且沒有支援Transaction功能,所以,當某個資料表被鎖定時,其他使用者無法對該資料表進行查詢,較不適合Transaction型態的服務或應用。

相較之下,當應用屬性需要同時大量新增或刪除時,InnoDB支援Transaction與Rollback的特性,能讓資料處理效率更加顯著。此外,InnoDB的Journalling系統,可以在當機時,只要使用Journal Replay功能就可以恢復資料。

秘技3  用Amazon雲端儲存服務分析巨量Log資料

由於痞客邦每天都會透過報表來檢視服務狀態,包括當日使用者總數與總文章量等,因此,需要依據使用者登錄紀錄等Log資料,進一步產生分析報表。然而,Log型態的資料,不僅產出量驚人,一般情況下,直接使用原始資料的機會並不高,因此,痞客邦決定把原始Log資料,儲存在Amazon的雲端儲存服務S3,然後搭配Amazon的MapReduce資料分析服務,來做Log資料的巨量分析,再將分析結果匯出後,儲存在MySQL平臺上。

痞客邦之所以會選擇用Amazon的雲端儲存服務S3,同時並搭配Amazon的MapReduce資料分析服務,來做Log資料的分析,一方面是因為這樣的做法,可以較低成本來儲存大量的Log資料,另一方面則可直接運用非結構資料分析技術MapReduce,來做Log分析。痞客邦只需要將分析結果匯出後,就可以進一步與其他資料整合,並且作為痞客邦經營方向調整的依據。

(看大圖)


相關報導請參考「開源資料庫的新價值」

熱門新聞

Advertisement