RELATEED CONSULTING
相關咨詢
選擇下列産品馬上(shàng)在線溝通(tōng)
服務時(shí)間(jiān):9:00-18:00
你(nǐ)可(kě)能遇到了下面的問題
關閉右側工具欄
高(gāo)性能Web應用打造攻略:擴展過程中20個(gè)最大(dà)的絆腳石
  • 作(zuò)者:admin
  • 發表時(shí)間(jiān):2013-09-07 09:48:43
  • 來(lái)源:未知

Sean Hull是Heavyweight Internet Group的創始人(rén)兼高(gāo)級顧問,擁有(yǒu)20年以上(shàng)技(jì)術(shù)顧問相關經驗,曾為(wèi)多(duō)家(jiā)知名機構提供咨詢,其中包括The Hollywood Reporter、Billboard、NBC Universal、Zagats、Rent the Runway及ideeli,這些(xiē)高(gāo)速增長的公司每個(gè)月處理(lǐ)接近1億的獨立訪客。Hull在Amazon EC2部署和(hé)Linux及MySQL性能上(shàng)有(yǒu)着豐富的經驗。巨大(dà)流量的處理(lǐ)需涉及多(duō)個(gè)方面,其中包括網站(zhàn)擴展性、業務連續性、安全及架構挑戰等。近日,Hull分享了高(gāo)性能Web應用打造的經驗,剖析了擴展之路上(shàng)20個(gè)最大(dà)的絆腳石。以下為(wèi)譯文:

1.  二階段提交

通(tōng)常情況下,當數(shù)據庫中的數(shù)據發生(shēng)改變時(shí),它需要同時(shí)被寫入內(nèi)存和(hé)硬盤。當一個(gè)提交發生(shēng)時(shí),傳統數(shù)據庫需要負責數(shù)據在真實存儲媒質上(shàng)的持久化。牢記,內(nèi)存的數(shù)據在崩潰或者重啓後都會(huì)消失。即使數(shù)據已經在數(shù)據庫中緩存,數(shù)據庫仍然需要将其持久化到磁盤上(shàng),MySQL的二進制(zhì)日志(zhì)及Oracle的redo日志(zhì)都符合這個(gè)要求。

通(tōng)過MySQL集群或者類似DRBD(Distributed Replicated Block Device)或者Amazon Multi-AZ(Multi-Availability Zone)的分布式文件系統,提交并不僅僅是在本地發生(shēng),同時(shí)也在遠端。二階段提交意味着需要從遠端得(de)到反饋,鑒于網絡及一些(xiē)其它的延時(shí),提交速度可(kě)能會(huì)被毫秒(miǎo)級的降低(dī),仿佛高(gāo)速公路上(shàng)的所有(yǒu)汽車(chē)都因重載變慢。如有(yǒu)考慮使用Multi-AZ或者讀備份,不妨查看Amazon RDS(Relational Database Service)與MySQL的比較。

同步複制(zhì)同樣會(huì)出現這些(xiē)問題,因此MySQL解決方案是半同步的,這也可(kě)以看做(zuò)是在二階段提交上(shàng)的一些(xiē)讓步。

2.  緩存不足

在所有(yǒu)層中緩存的作(zuò)用都至關重要,那(nà)麽什麽地方最需要使用緩存:浏覽器(qì)、頁面、對象還(hái)是數(shù)據庫存?下面不妨統統試一下。

浏覽器(qì)緩存似乎遙不可(kě)及,除非你(nǐ)清楚浏覽器(qì)是從Web Server中取出指令及其渲染的頁面。因此,如果包含的對象有(yǒu)一個(gè)比較長的生(shēng)命周期,浏覽器(qì)将會(huì)緩存他們,不需要再次進行(xíng)讀取。這不僅會(huì)加快用戶的浏覽速度,同樣會(huì)有(yǒu)益于Server對網站(zhàn)的托管,因為(wèi)會(huì)切實的減少(shǎo)用戶的二次讀取。

猛戳這裏查看更多(duō)浏覽器(qì)緩存相關,确保設置了期滿頭文件及緩存控制(zhì)。

頁面緩存需要使用類似Varnish的技(jì)術(shù),可(kě)以将它看成一個(gè)迷你(nǐ)的高(gāo)速、低(dī)開(kāi)銷Web Server。它不可(kě)以支撐類似Apache可(kě)以的複雜頁面,但(dàn)是它可(kě)以讓非常簡單的頁面更快。因此位于Apache之前,用于減少(shǎo)負載,讓Apache可(kě)以處理(lǐ)更加複雜的頁面。就像交通(tōng)警察,在專注更複雜的機動車(chē)前,先給自行(xíng)車(chē)放行(xíng)。

對象緩存由類似memcache的組件完成,可(kě)以把它當做(zuò)是應用程序的便利貼。做(zuò)數(shù)據庫查詢時(shí)會(huì)先訪問緩存尋求數(shù)據,如果發現了所需的數(shù)據,那(nà)麽結果返回的時(shí)間(jiān)将比訪問數(shù)據庫快10-100倍,這樣就可(kě)以快速的構建頁面,從而在眨眼間(jiān)為(wèi)用戶呈現。如果它沒有(yǒu)發現所需的數(shù)據,或者隻發現了一部分,那(nà)麽将會(huì)建立數(shù)據庫請(qǐng)求并将返回的數(shù)據放于緩存中,讓更多(duō)的後來(lái)者受益。

3.  緩慢的磁盤I/O、RAID 5、多(duō)租戶存儲

數(shù)據庫中的一切都受到存儲的限制(zhì),這裏既包含了空(kōng)間(jiān)問題,也受設備讀寫的速度掣肘。

如果你(nǐ)使用實體(tǐ)服務器(qì),那(nà)麽一定要當心RAID 5,獨立磁盤冗餘陣列的一種,數(shù)據保護和(hé)奇偶性将嚴重的影(yǐng)響寫操作(zuò)。同時(shí),如果其中一個(gè)磁盤損壞,那(nà)麽這個(gè)陣列在磁盤重建時(shí)将變得(de)非常緩慢。

這個(gè)方案一般使用RAID 10,它将為(wèi)你(nǐ)提供獨立的鏡像集。這導緻沒有(yǒu)奇偶校(xiào)驗計(jì)算(suàn),從而不會(huì)影(yǐng)響重建時(shí)的速度。

雲環境可(kě)能會(huì)涉及到類似于Amazon EBS(Elastic Block Store,一個(gè)類似于SAN的虛拟化磁盤)的技(jì)術(shù)。鑒于其基于網絡,你(nǐ)必須與其它租戶競争存儲的讀寫。因為(wèi)每個(gè)存儲能支撐的讀寫速度是固定的,所以你(nǐ)的鄰居可(kě)能會(huì)影(yǐng)響到你(nǐ)網站(zhàn)及應用程序的讀寫速度。

最近,Amazon又公布了一個(gè)重量級産品Provisioned IOPS(每秒(miǎo)I/O操作(zuò))。對于技(jì)術(shù)專家(jiā)來(lái)說看起來(lái)非常不錯,但(dàn)是對于其它人(rén)來(lái)說毫無價值。盡管如此,其依然重要,這意味着你(nǐ)可(kě)以鎖定你(nǐ)數(shù)據庫所需的磁盤性能。如果你(nǐ)想在Amazon上(shàng)托管數(shù)據庫,那(nà)麽不妨多(duō)關注一下這個(gè)。

4.  串行(xíng)處理(lǐ)

在超市結賬時(shí),如果有(yǒu)10個(gè)收銀台開(kāi)放,那(nà)麽從事的是并行(xíng)處理(lǐ)。如果每個(gè)收銀台都在休息,隻有(yǒu)一個(gè)登記處開(kāi)放,那(nà)麽從事的是串行(xíng)操作(zuò)。那(nà)麽結賬的隊伍将變得(de)非常長,不僅是結賬人(rén)的心情受到影(yǐng)響,購物者也同樣如此。這點經常發生(shēng)在線路不夠的大(dà)橋收費站(zhàn)以及許多(duō)人(rén)一起離場(chǎng)的體(tǐ)育場(chǎng)所。

網絡應用需要嚴格的避免串行(xíng),因等待API調用而産生(shēng)的阻塞,所有(yǒu)的後端節點都在等待一個(gè)搜索服務器(qì),隻要你(nǐ)應用程序的某處形成一個(gè)線就代表了串行(xíng)化的發生(shēng),那(nà)麽必須不惜一切代價去清除它。

5.  缺少(shǎo)Feature Flag

在給業務部門(mén)建立應用時(shí),開(kāi)發者一般從特性和(hé)功能入手。Feature Flag将至關重要,它讓人(rén)們可(kě)以通(tōng)過後端配置文件或管理(lǐ)員UI頁面關閉或者打開(kāi)特性。

為(wèi)什麽他們如此重要?如果你(nǐ)有(yǒu)早上(shàng)4點的救火(huǒ)經驗,那(nà)麽你(nǐ)将明(míng)白啓動應急計(jì)劃的必要性。你(nǐ)需要可(kě)以關閉評級、評論以及應用程序其它的一些(xiē)特性,這将不會(huì)導緻整個(gè)系統崩潰。更重要的是,在新特性發布時(shí),有(yǒu)些(xiē)時(shí)候問題并不明(míng)顯,直到一群互聯網用戶同時(shí)湧入。Feature Flag讓你(nǐ)可(kě)以選擇性的關閉一些(xiē)功能,而不是關掉整個(gè)網站(zhàn)。

6.  單一的數(shù)據庫副本

你(nǐ)必須使用一個(gè)以上(shàng)的讀副本或者MySQL從節點,這允許在主節點出問題時(shí)的快速故障轉移。

擁有(yǒu)數(shù)據庫的多(duō)個(gè)副本意味着橫向擴展。如果你(nǐ)有(yǒu)兩個(gè),你(nǐ)就會(huì)看到3-4個(gè)會(huì)對你(nǐ)基礎設施的提升。

7. 使用數(shù)據庫進行(xíng)排隊

MySQL數(shù)據庫非常适合儲存表格、數(shù)據以及他們之間(jiān)的關系,不幸的是,它并不适合處理(lǐ)應用程序的隊列。盡管如此,許多(duō)開(kāi)發者都習慣使用一個(gè)表格來(lái)達到這個(gè)目的。比如,讓你(nǐ)的應用程序包含一些(xiē)作(zuò)業表格,或者一個(gè)狀态列,擁有(yǒu)一些(xiē)類似“in-process”、“in-queue” 及“finished”的值。

因為(wèi)鎖競争、scan及 poll進程将造成更多(duō)的工作(zuò),這些(xiē)解決方案會(huì)帶來(lái)一些(xiē)擴展性問題,它們将會(huì)顯著的降低(dī)數(shù)據庫速度。幸運的是這裏存在很(hěn)多(duō)有(yǒu)效的開(kāi)源解決方案,比如RabbitMQ及Amazon的SQS。

8.  使用一個(gè)做(zuò)全文查詢的數(shù)據庫

頁面搜索是掣肘應用程序的另一個(gè)方面,盡管MySQL一段時(shí)間(jiān)也支撐了full-text索引。但(dàn)是它們隻對MyISAM表格有(yǒu)效,其它類型表格都不買賬,一直困擾着開(kāi)發者。

一個(gè)解決方案是使用類似Solr的專業搜索引擎,這些(xiē)技(jì)術(shù)擁有(yǒu)許多(duō)很(hěn)好的庫去支撐你(nǐ)的編程語言,同時(shí)會(huì)提供一個(gè)更快的搜索速度。這些(xiē)方案同樣易于擴展,并且不會(huì)讓你(nǐ)的數(shù)據庫成為(wèi)累贅。

替代方案是Sphinx SE,一個(gè)MySQL存儲引擎,将Sphinx服務器(qì)整合進數(shù)據庫。此外,MySQL 5.6版本中還(hái)使用了InnoDB做(zuò)全文搜索的默認搜索引擎。

9.  對象關系模型

ORM,就像毒藥一樣,一旦進行(xíng)使用,就很(hěn)難擺脫。有(yǒu)利的一面是ORM有(yǒu)益于快速原型,并且允許非專家(jiā)級MySQL開(kāi)發者使用對象或者內(nèi)存模式進行(xíng)讀寫訪問。如果你(nǐ)不進行(xíng)擴展,那(nà)麽他們的速度将非常快,并讓功能的快速交付得(de)到保障。

然後DBA(數(shù)據庫管理(lǐ)員)會(huì)因為(wèi)緩慢且醜陋的查詢來(lái)到開(kāi)發團隊并且說:“這個(gè)查詢在應用程序什麽地方,我們需要進行(xíng)修複,它需要被重寫。”開(kāi)發團隊則會(huì)說:“我們也不知道(dào)!”從而會(huì)收到來(lái)自運營組一些(xiē)質疑的眼神。

有(yǒu)能力對bad sql進行(xíng)跟蹤并将其指出是非常重要的。DBA團隊需要一定的指引找到bad sql的源頭。如果查詢是來(lái)自ORM,他們并不具備這些(xiē)指引。這樣你(nǐ)的團隊将面對一個(gè)巨大(dà)的技(jì)術(shù)負債,同樣也是個(gè)非常難以解決的挑戰。

10.  缺少(shǎo)Instrumentation

Instrumentation(儀表盤)為(wèi)應用程序提供了碼表和(hé)油表,這是汽車(chē)不可(kě)缺少(shǎo)的兩個(gè)部分。他們提供了應用程序的內(nèi)部工作(zuò)信息:他們記錄了時(shí)間(jiān)信息,并且提供了應用程序耗時(shí)最多(duō)的環節。

一個(gè)非常人(rén)氣的網絡解決方案就是New Relic,它提供了一個(gè)非常全面的可(kě)視(shì)化界面,針對各個(gè)領域工作(zuò)者——項目經理(lǐ)、開(kāi)發者、運營團隊,甚至是業務部門(mén)都可(kě)以從圖中發現問題所在。當然,現在已經有(yǒu)很(hěn)多(duō)的開(kāi)源Instrumentation。

11.  缺少(shǎo)代碼倉庫及版本管理(lǐ)

盡管現在這個(gè)問題已非常少(shǎo)見,但(dàn)是還(hái)有(yǒu)有(yǒu)些(xiē)互聯網公司在沒有(yǒu)版本控制(zhì)下去建立應用程序。當然那(nà)些(xiē)使用了的人(rén),很(hěn)清楚它将給團隊帶來(lái)的日常優勢和(hé)組織控制(zhì)。

如果你(nǐ)沒有(yǒu)使用,随着應用程序變得(de)更加複雜,你(nǐ)将被卷入技(jì)術(shù)負債的漩渦,為(wèi)應用不同部分添加員工将變得(de)異常困難。

一旦你(nǐ)使用版本控制(zhì),确保囊括了所有(yǒu)的組件,包含配置文件以及其它要素。而丢失部署時(shí)需要用到的部分,将帶來(lái)額外的風險。

12.  單點故障

如果你(nǐ)的數(shù)據隻存在一個(gè)主數(shù)據庫上(shàng),這就是一個(gè)單點故障。如果你(nǐ)的服務器(qì)位于一個(gè)單獨的磁盤上(shàng),這也是個(gè)單點故障。單點故障可(kě)以比作(zuò)“阿基裏斯之踵”技(jì)術(shù)用語。

不惜任何代價,單點故障都要在應用程序中移除。麻煩的是如何去認識單點故障,即使是選擇單一的雲供應商都可(kě)以稱為(wèi)單點故障,如果擁有(yǒu)多(duō)個(gè)供應商,或者使用Amazon不同的部分,那(nà)麽AirBNB的服務将幸免Amazon 2012年10月的部分宕機。

13.  缺乏隻浏覽模式

如果你(nǐ)深夜在Yelp、Facebook或者是Tumblr上(shàng)發布評論,你(nǐ)可(kě)能就會(huì)收到這樣的信息:“該特性不可(kě)用,請(qǐng)稍後再試”。稍後可(kě)能是50或者60分鍾,也許可(kě)能還(hái)需多(duō)試幾次。對于非技(jì)術(shù)用戶,他們仍然感覺網站(zhàn)在正常運行(xíng),隻是奇怪了一點而已。

實際情況是,應用程序隻允許你(nǐ)去浏覽網站(zhàn),但(dàn)是不可(kě)以做(zuò)任何改變。可(kě)能是主數(shù)據庫或者是一些(xiē)存儲組件不可(kě)用了。

隻浏覽模式可(kě)以通(tōng)過保留主數(shù)據庫的多(duō)個(gè)讀備份來(lái)實現,使用MySQL副本或者是Amazon讀副本類似途徑。這樣就可(kě)以在沒有(yǒu)主數(shù)據庫情況下,保留網站(zhàn)全部浏覽功能正常,這一點非常重要。

14.  脆弱的溝通(tōng)

在擴展上(shàng)談溝通(tōng)可(kě)能非常奇怪,但(dàn)是應用程序技(jì)術(shù)層不可(kě)能因為(wèi)團隊間(jiān)社交和(hé)文化上(shàng)的差異分離。

強大(dà)的通(tōng)信線路是必要的,隊員必須要知道(dào)在錯誤發生(shēng)時(shí)将找誰。好的交流需要自信及知識淵博的領導,廣泛的聽(tīng)取意見并加以改善。

15.  缺少(shǎo)文檔

當Web應用程序包含許多(duō)層時(shí),文檔至關重要。開(kāi)發者需要給程序、功能、頁面做(zuò)文檔,讓後來(lái)者看代碼時(shí)可(kě)以清晰的發現所需的提示及見解。當有(yǒu)程序發生(shēng)故障時(shí),運營程序需要在配置文件上(shàng)添加評論去表明(míng)更改曆史。業務流程及關系同樣應該出現在公司的wiki裏,讓人(rén)們發現自己問題的解決方案。

文檔可(kě)以在各個(gè)層次起到幫助作(zuò)用,每個(gè)人(rén)都應該擁抱這個(gè)愛(ài)好。

16  缺少(shǎo)應急演習

應急通(tōng)常情況下總會(huì)被忽視(shì),團隊可(kě)能會(huì)有(yǒu)“我們覆蓋的地方都有(yǒu)備份”這類的說辭。不錯備份、恢複的途徑很(hěn)通(tōng)吃(chī),關鍵是确保備份的文件萬無一失。一旦在故障轉移時(shí)發現備份有(yǒu)缺失,那(nà)麽你(nǐ)不願意發生(shēng)的事情必然發生(shēng)。

應急演習讓事情發生(shēng)之前有(yǒu)了相應的經驗,公司應該将此作(zuò)為(wèi)運營團隊工作(zuò)的一部分,每年都需要進行(xíng)幾次。在雲時(shí)代,應急演習已經變得(de)比以前輕松許多(duō)。為(wèi)保證所有(yǒu)組件都被備份而啓動服務器(qì)是非常值得(de)的,在這個(gè)過程中你(nǐ)将學到這項操作(zuò)該持續多(duō)長時(shí)間(jiān),以及困難所在的地方,更知道(dào)需要小(xiǎo)心些(xiē)什麽。

17.  缺少(shǎo)監視(shì)和(hé)指标

監視(shì)有(yǒu)着與版本控制(zhì)同樣的重要性:非常基本,缺少(shǎo)它工作(zuò)将無法進行(xíng);然而确實有(yǒu)一些(xiē)網站(zhàn)沒有(yǒu)監視(shì),或者是監視(shì)力度不夠——有(yǒu)些(xiē)服務器(qì)或者是核心組件并未被監視(shì)。

不間(jiān)斷的收集系統及服務器(qì)數(shù)據,同時(shí),應用程序和(hé)業務級别的可(kě)用性也同等重要。如果你(nǐ)不想親自動手,不妨考慮一個(gè)Web服務方案。

18.  莽撞的運營

你(nǐ)騎着馬在街(jiē)道(dào)上(shàng)飛奔,明(míng)着帶槍進入酒吧(ba),你(nǐ)認為(wèi)這是在交朋友(yǒu)?肯定不是,你(nǐ)在暴力的脅迫别人(rén)遵循,所有(yǒu)人(rén)都不會(huì)有(yǒu)歸屬感。強大(dà)的信心是好的,但(dàn)是團隊的合作(zuò)是不可(kě)缺少(shǎo)的,團隊的智慧高(gāo)于任何個(gè)人(rén)。

團隊需要不斷的對改變做(zuò)交流,用管理(lǐ)的角度進行(xíng),準備好應對失敗等等。采取小(xiǎo)心及規避風險的态度,永遠都有(yǒu)備用計(jì)劃,你(nǐ)應該有(yǒu)能力撤銷所有(yǒu)改變,并且認真對待破壞性的改變,以及那(nà)些(xiē)不可(kě)恢複的地方。

19.  日益增長的技(jì)術(shù)負債

随着應用不斷的增長,隊伍需要花(huā)越來(lái)越多(duō)的時(shí)間(jiān)在老代碼的維護和(hé)支持上(shàng),消除漏洞及缺陷。因此,花(huā)在新特性上(shàng)的時(shí)間(jiān)将越來(lái)越少(shǎo)。必須謹慎的維護好新特性與技(jì)術(shù)負債上(shàng)投入時(shí)間(jiān)的平衡。如果你(nǐ)發現你(nǐ)的技(jì)術(shù)負債增加,可(kě)能就是橫下決心重寫的時(shí)候了。重寫可(kě)能會(huì)影(yǐng)響到短(duǎn)期新特性及客戶特性的開(kāi)發,但(dàn)是從長遠的角度上(shàng)看是非常好的。

技(jì)術(shù)負債并不總是能被輕易的認知,在你(nǐ)建立特性或者是修複bug時(shí),你(nǐ)更習慣于聚焦局部的細節,非常容易失去全局觀,這也是為(wèi)什麽全面人(rén)才更益于Web擴展的原因。

20.  不足的日志(zhì)

日志(zhì)直接影(yǐng)響到度量及監視(shì)。你(nǐ)在尋找故障和(hé)排錯時(shí)肯定希望得(de)到更多(duō)的日志(zhì),但(dàn)是在一個(gè)不間(jiān)斷運行(xíng)的情況下,你(nǐ)同樣會(huì)需要一些(xiē)關鍵服務的日志(zhì)。服務器(qì)系統日志(zhì)、Apache及MySQL日志(zhì)、緩存日志(zhì)等,這些(xiē)都需要被保存。而在日志(zhì)太多(duō)時(shí),你(nǐ)總是會(huì)減少(shǎo)一些(xiē)地方的日志(zhì),或者裁剪及循環日志(zhì)文件,從而丢棄舊(jiù)的。