如何搭建千萬級別使用者的應用系統

desaco發表於2016-01-22

基本情況

l AWS覆蓋全世界12個國家區域

1. 每個區域都對應著世界上的一個物理位置,每個位置都有彈性計算雲提供多個可用區域(Availability Zones),這些區域包含北美、南美、歐洲、中東、非洲、亞太等地區。

2. 每個可用區域(AZ)實質上是單個資料中心,儘管它可由多個資料中心構造。

3. 每個可用區域都擁有很強的隔離性,他們各自擁有獨立的電源和網路。

4. 可用區域之間只能通過低延遲網路互相連線,它們可以相距515英里,但網路的速度相當快以至於你的應用程式像在同一個資料中心。

5. 每個區域至少有2個可用區域,可用區域總共有32個。

6. 藉助若干可用區域即可構建一個高可用的架構供你的應用使用。

7. 在即將到來的2016年將會增加至少9個可用區域和4個區域。

 

l AWS在世界上擁有53個邊緣位置

1. 這些邊緣位置被用於Amazon的內容分發網路CDNRoute53CloudFront以及AmazonDNS管理伺服器。

2. 邊緣位置使使用者可以在世界的任何角落低延遲地訪問網頁。

l 構建塊服務

1. AWS已經使用多個可用區域構架了大量服務供使用,這些服務內部擁有高可用性和容錯性。以下是可供使用的服務列表

2. 你可以在你的應用中直接使用這些服務,它們是收費的,但使用它們你可以不必自己考慮高可用性。

3. 每個可用區域都提供很多服務,包括CloudFront, Route 53, S3, DynamoDB, 彈性負載均衡, EFS, Lambda, SQS, SNS, SES, SWF

4. 即使這些服務只存在於一個單一的可用區域,通過使用這些服務任然可以構建一個高可用架構。

一個使用者

l 在這種情況下,你是作為僅有的使用者,你僅僅只想讓web應用跑起來。

l 你的架構看起來像下面幾點:

 

1. 執行在單獨的例項上,可能是t2.micro型。例項型別包括了CPU、記憶體、儲存和網路的不同組合,通過選擇這些不同例項型別組成一個適合你的web應用的資源。

2. 在單獨的例項上執行整個web棧,例如web應用程式、資料庫以及各種管理系統等。

3. 使用AmazonRoute53作為DNS服務。

4. 在此例項上新增一個的彈性IP

5. 在一段時間內執行的良好。

縱向擴充套件

l 你需要一個更大的容器放置你的應用,最簡單的擴充套件方法是選擇一個更大的例項型別,例如c4.8xlarge或者m3.2xlarge

l 這種方法稱為縱向擴充套件。

l 需要做的僅僅是選擇一個新型例項取代原來的例項,應用跑起來即可以更加強大。

l 提供多種不同的硬體配置混搭選擇,可以選擇一個244G記憶體的系統(2TBRAM即將到來),也可以選擇40CPU核心的系統,可以組成I/0密集型例項、CPU密集型例項以及高儲存型例項。

l Amazon的一些服務使用可配置的IOPS選項來保證效能,你可以使用小一點的例項去跑你的應用,對於需要擴充套件的服務獨立使用Amazon的可擴充套件服務,例如DynamoDB

l 縱向擴充套件有一個很大的問題:它不具備failover功能,同時也不具備冗餘性。就像把所有雞蛋都放在同一個籃子裡,一旦例項發生故障你的web也會宕掉。

l 一個單獨的例項最終能做到的也就這些,想要更加強大需要其他的措施。

10+使用者

l 將單個主機分為多個主機

1. Web應用使用一臺主機。

2. 資料庫使用一臺主機,你可以在上面跑任意資料庫,只要負責資料庫的管理。

3. 將主機分離成多個主機可以讓web應用和資料庫各自獨立對自己進行擴充套件,例如在某種情況下可能你需要的資料庫比web應用更大的規模。

l 或者你可以不自己搭建資料庫轉而使用Amazon的資料庫服務

1. 你是一個DBA嗎?你真的想要擔心資料備份的問題嗎?擔心高可用?擔心資料庫補丁?擔心作業系統?

2. 使用Amazon資料庫服務有一大優勢,你只要簡單一點選即可完成多可用區域的資料庫的安裝,而且你不必擔心這些可用區域之間的資料備份或其他類似的事情,這些資料庫具備高可用性高可靠性。

l 正如你所想,Amazon有幾種型別的完全託管資料庫服務供出售:

1. Amazon RDS(Relational Database Service),可供選擇的資料庫型別相當多,包括Microsoft SQL Server, Oracle, MySQL, PostgreSQL, MariaDB, Amazon Aurora.

2. Amazon DynamoDB,一個NoSQL資料庫。

3. Amazon Redshift,一個PB級的資料倉儲系統。

l 更多Amazon 特性

1. 擁有自動擴充套件儲存到64TB的能力,你不再需要限定你的資料儲存。

2. 多大15個讀副本。

3. 持續增量備份到S3

4. 多達6路備份到3個可用區域,有助於處理故障。

5. MySQL相容。

l 用SQL資料庫取代NoSQL資料庫

1. 建議使用SQL資料庫。

2. SQL資料庫相關技術完善。

3. 存在大量開源原始碼、社群、支援團隊、書籍和工具。

4. 千萬使用者級別系統的還不足以拖垮SQL資料庫,除非你的資料非常巨大。

5. 具有清晰的擴充套件模式。

l 什麼時候你才需要使用NoSQL資料庫

1. 如果你一年需要儲存超過5TB的資料,或者你有一個令人難以置信的資料密集任務。

2. 你的應用具有超低延遲需求。

3. 你的應用需要一個非常高的吞吐量,需要在資料的讀寫I/O上進行優化。

4. 你的應用沒有任何關係型資料。

100+使用者

l 在web層進行主機分離。

l 使用Amazon RDS儲存資料,它把資料庫的所有工作都攬下了。

l 上面兩點做好即可。

 

1000+使用者

l 現在你構建的應用存在可用性問題,你的web應用將會宕掉如果你web服務的主機宕掉了。

l 你需要在另外一個可用區域上搭建另外一個web例項,由於可用區域之間擁有毫秒級別的低延遲,他們看起來就像互相挨著。

l 同樣,你需要在另外一個可用區域上搭建一個RDS資料庫slave,組成主備資料庫,一旦主資料庫發生故障你的web應用將會自動切換到slave備資料庫。由於你的應用總是使用相同的端,failover不會帶給應用任何改變。

l 在兩個可用區域中分佈著兩個web主機例項,使用彈性負載均衡器(ELB)將使用者訪問分流到兩個web主機例項。

l 彈性負載均衡器(ELB

1. ELB是一個高可用的負載均衡器,它存在於所有的可用區域中,對於你的應用來說它是一個DNS服務,只需要把他放到Route53即可,它就會在你的web主機例項中進行負載分發。

2. ELB有健康檢查機制,這個機制保證流量不會分發到宕掉的主機上。

3. 不用採取任何措施即可完成擴充套件,當它發現額外流量時它將在後臺通過橫向和縱向擴充套件,隨著你的應用不斷擴充套件,它也會自動不斷擴充套件,而且這些都是系統自動完成的,你不必對ELB做任何管理。

10000100000使用者

l 前面例子中說到ELB後面掛載兩個web主機例項,而實際上你可以在ELB後面掛載上千個主機例項,這就叫橫向擴充套件。

l 新增更多的讀副本到資料庫中,或者新增到RDS中,但需要保持副本的同步。

l 通過轉移一些流量到web層伺服器減輕web應用的壓力,例如從你的web應用中將靜態內容抽離出來放到Amazon S3Amazon CloudFront上,CloudFrontAmazonCDN,它會將你的靜態內容儲存在全世界的53個邊緣地區,通過這些措施提高效能和效率。

l Amazon S3是一個物件倉庫。

1. 它不像EBS,它不是搭載在EC2例項上的儲存裝置,它是一個物件儲存而不是塊儲存。

2. 對於靜態內容如JavaScriptcss、圖片、視訊等存放在Amazon S3上再合適不過,這些內容沒必要放到EC2例項上。

3. 高耐用性,119的可靠性。

4. 無限制的可擴充套件,只要你想可以往裡面扔儘可能多的資料,使用者在S3上儲存了PB級別的資料。

5. 支援最大5TB的物件儲存。

6. 支援加密,你可以使用Amazon的加密,或者你自己的加密,又或者第三方的加密服務。

l Amazon CloudFront對你的內容提供快取

1. 它將內容快取在邊緣地區以便供你的使用者低延遲訪問。

2. 如果沒有CDN,將導致你的使用者更高延遲地訪問你的內容,你的伺服器也會因為處理web層的請求而處於更高的負載。

3. 例如有個客戶需要應對60Gbps的訪問流量,CloudFront將一切都處理了,web層甚至都不知道有這麼大的訪問流量存在。

l 你還可以通過轉移session狀態減輕你的web層的負載

1. 將session狀態儲存到ElastiCacheDynamoDB

2. 這個方法也讓你的系統在未來可以自動擴充套件。

l 你也可以將資料庫的一些資料快取在ElastiCache減輕應用負載

1. 資料庫沒有必要處理所有獲取資料的請求,快取服務可以處理這些請求從而讓寶貴的資料庫資源處理更加重要的操作。

l Amazon DynamoDB——全託管的NoSQL資料庫

1. 根據你自己想要的吞吐量,定製你想要的讀寫效能。

2. 支援高效能。

3. 具備分散式和容錯性,它部署在多個可用區域中。

4. 它以kv結構儲存,且支援JSON格式。

5. 支援最大400k大的檔案。

l Amazon Elasticache ——全託管的MemcachedRedis

1. 維護管理一個memcached叢集並不會讓你賺更多的錢,所以讓Amazon來做。

2. Elasticache叢集會自動幫你擴充套件,它是一個具備自我修復特性的基礎設施,如果某些節點宕掉了其它的新節點即會自動啟動。

l 你也可以轉移動態內容到CloudFront減輕負載

1. 眾所周知CloudFront能處理靜態內容,例如檔案,但除此之外它還還能處理某些動態內容,這個話題不再進行深入的探討,可以看看這個連結

自動擴充套件

l 對於黑色星期五,假如你不用做任何擴充套件就足夠處理這些峰值流量,那麼你是在浪費錢。如果需求和計算能力相匹配自然是最好的,而這由自動擴充套件幫你實現,它會自動調整計算叢集的大小。

l 作為使用者,你可以決定叢集的最小例項數和最大例項數,通過例項池中設定最小和最大例項數即可。

l 雲監控是一種嵌入應用的管理服務

1. 雲監控的事件觸發擴充套件。

2. 你準備擴充套件CPU的數量嗎?你準備優化延遲嗎?準備擴充套件頻寬嗎?

3. 你也可以自定義一些指標到雲監控上,如果你想要指定應用針對某些指標自動擴充套件,只需將這些指標放到雲監控上,告訴根據雲監控根據這些指標分別擴充套件哪些資源。

500000+使用者

l 前面的配置可以自動擴充套件群組新增到web層,在兩個可用區域裡自動擴充套件群組,也可以在三個可用區域裡擴充套件,在不同可用區域中的多例項模式不經可以確保可擴充套件性,同時也保證了可用性。

l 論題中的案例每個可用區域只有3web層例項,其實它可以擴充套件成上千個例項,而你可以設定例項池中最小例項數為10最大例項數為1000

l ElastiCache用於承擔資料庫中熱點資料的讀負載。

l DynamoDB用於Session資料的負載。

l 你需要增加監控、指標以及日誌。

1. 主機級別指標,檢視自動擴充套件的叢集中的某一CPU引數,快速定位到問題的位置。

2. 整體級別指標,檢視彈性負載均衡的指標判斷整個例項叢集的整體效能。

3. 日誌分析,使用CloudWatch日誌檢視應用有什麼問題,可以使用CloudTrail對這些日誌進行分析管理。

4. 外部站點監控,使用第三方服務例如New RelicPingdom監控作為終端使用者看到了什麼情況。

l 你需要知道你的使用者的反饋,他們是不是訪問延遲很慢,他們在訪問你的web應用時是不是出現了錯誤。

l 從你的系統結構中儘可能多地排出效能指標,這有助於自動擴充套件的決策,你可不希望你的系統CPU使用率才20%

自動化運維

l 隨著基礎設施越來越大,它擴充套件到了上千個例項,我們有讀副本,我們有水平橫線擴充套件,對於這些我們需要一些自動化運維措施去對他們進行管理,我們可不希望對著每個例項一個一個單獨地管理。

l 自動化運維工具分為兩個層級

1. DIY層,包括Amazon EC2AWS CloudFormation

2. 更高層次的服務,包括AWS Elastic BeanstalkAWS OpsWorks

l AWS Elastic Beanstalk,為你的應用自動管理基礎設施,很方便。

l AWS OpsWorks,應用程式管理服務,用於部署和操作不同形態規模的應用程式,它還能做到持續整合。

l AWS CloudFormation

1. 提供了最大的靈活性,它提供了你的應用棧的模板,它可以構建你的整個應用棧,或者僅僅是應用棧中的某個元件。

2. 如果你要更新你的應用棧你只要更新CloudFormation模板,它將更新你的整個應用。

3. 它擁有大量的控制,但缺乏便利性。

l AWS CodeDeploy,部署你的程式到整個EC2例項叢集

1. 可以部署一到上千個例項。

2. Code Deploy可以指向一個自動擴充套件配置。

3. 可連同ChefPuppet一起使用。

解耦基礎設施

l 使用SOA/微服務,從你的應用抽離出不同服務,就像前面你將web層與資料庫層分離出來那樣,再分別建立這些服務。

l 這些獨立出來的服務就可以根據自己需要擴充套件,它給你係統的擴充套件帶來了靈活性,同時也保證了高可用性。

l SOAAmazon搭建架構關鍵的組成部分。

l 鬆耦合解放了你

1. 你可以對某些服務單獨地擴充套件和讓它失效。

2. 如果一個工作節點從SQS拉取資料失敗,沒有沒關係?沒有,只要重啟另外一個工作節點即可,所有操作都有可能發生故障,所以一定要搭建一個可以處理故障的架構,提供failover功能。

3. 將所有模組設定成黑盒。

4. 把互動設計成鬆耦合方式。

5. 優先考慮內建了冗餘性和可擴充套件性的服務,而不是靠自己構建實現。

不要重複發明輪子

l 只需把你區別於已有任務的部分作為你的業務邏輯。

l Amazon的很多服務本身具備容錯能力,因為他們跨多個可用區域,例如:佇列、郵件、轉碼、搜尋、資料庫、監控、效能指標採集、日誌處理、計算等服務,沒有必要自己搭建。

l SQS:佇列服務

1. Amazon提供的第一個服務。

2. 它是跨可用區域的所以擁有容錯性。

3. 它具備可擴充套件性、安全性、簡單性。

4. 佇列可以幫助你的基礎設施上的不同元件之間傳遞訊息。

5. 以圖片管理系統為例,圖片收集系統和圖片處理系統是兩個不同的系統,他們各自都可以獨立地擴充套件,他們之間具備鬆耦合特性,攝取照片然後扔進佇列裡面,圖片處理系統可以拉取佇列裡面的圖片再對其進行其他處理。

l AWS Lambda,用於程式碼部署和服務管理。

1. 提供解耦你的應用程式的工具。

2. 在前面圖片系統的例子中,Lambda可以響應S3的事件,就像S3中某檔案被增加時Lambda相關函式會被自動觸發去處理一些邏輯。

3. 已經在EC2上整合,供應用擴充套件。

百萬級別使用者

l 當使用者數量達到百萬級別時,這就要求前面提到的所有方案都要綜合考慮。

1. 擴充套件多為可用區域。

2. 在所有層之間使用彈性負載均衡,不僅在web層使用,而且還要在應用層、資料層以及應用包含的其他所有層都必須使用彈性負載均衡。

3. 自動伸縮能力。

4. 面向服務的架構體系。

5. 巧妙使用S3CloudFront部署一部分內容。

6. 在資料庫前面引入快取。

7. 將涉及狀態的物件移除出Web層。

l 使用Amazon SES傳送郵件。

l 使用CloudWatch監控。

 

千萬級別使用者

l 當我們的系統變得越來越大,我們會在資料層遇到一些問題,你可能會遇到競爭寫主庫的資料庫問題,這也就意味著你最多隻能傳送這麼多寫流量到一臺伺服器上。

l 你如何解決此問題?

1. Federation,根據你的應用功能把資料庫分成多個庫。

2. Sharding,分表分片,使用多個伺服器分片。

3. 把部分資料遷移到其他型別的資料庫上,例如NoSQLgraph等。

l Federation——根據應用功能切分成多個庫

1. 例如,建立一個論壇資料庫、一個使用者資料庫、一個產品資料庫,你可能之前就是一個資料庫包含這所有型別的資料,所以現在要將他們拆分開。

2. 按照功能分離出來的資料庫可以各自獨立進行擴充套件。

3. 缺點:不能做跨資料庫查詢。

l Sharding——將資料分割到多主機上

1. 應用層變得更加複雜,擴充套件能力更強。

2. 例如,對於使用者資料庫,三分之一的使用者被髮送到一個分片上,三分之一發到另一個分片上,最後三分之一發到第三個分片。

l 將資料遷移到其他型別的資料庫上

1. 考慮NoSQL資料庫。

2. 如果你的資料不要求複雜的join操作,比如說排行榜,日誌資料,臨時資料,熱表,後設資料/查詢表等等,滿足這些情況可以考慮遷移到NoSQL資料庫上。

3. 這意味著他們可以各自單獨擴充套件。

11000000使用者

l 擴充套件是一個迭代的過程,當你的系統變得越來越大,你總有更多的事情需要你解決。

l 調整你的應用架構。

l 更多的SOA特性和功能。

l 從多可用區域到多區域。

l 自定義解決方案去解決你的特定問題,當使用者量到達十億級別時自定義解決方案是必要的。

l 深入分析你的整個應用棧。

回顧

l 使用多可用區域的基礎設施提升可靠性。

l 使用自帶擴充套件能力的服務,比如ELBS3SQSSNSDynamoDB等等。

l 每一層級都建立冗餘,可擴充套件性和冗餘性不是兩個分開單獨的概念,經常需要同時考慮兩者。

l 剛開始使用傳統關係型資料庫。

l 在你的基礎設施的裡面和外面都考慮緩衝資料。

l 在你的基礎設施中使用自動化工具。

l 確保你的應用有良好的指標取樣、系統監控、日誌記錄,確保收集你的使用者訪問你的應用過程中產生的問題。

l 將各個層分拆成獨立的SOA服務,讓這些服務能保持最大的獨立性,可以各自進行擴充套件,及時發生故障也不波及其他。

l 一旦做了足夠的準備及可使用自動擴充套件功能。

l 不重複發明輪子,儘量使用託管服務而不是自己構建,除非非要不可。

必要的情況下轉向NoSQL資料庫。

相關文章