深刻淺出計算機組成原理學習筆記:第五十一講

1、原理篇總結回顧

今天是原理篇的最後一篇。過去50講,咱們一塊兒看了抽象概念上的計算機指令,看了這些指令怎麼拆解成一個個簡單的電路,以及CPU是怎麼經過一個一個的電路組成的。咱們還一塊兒看了高速緩存、內存、SSD硬盤和機械硬盤,以及這些組件又是怎麼經過總線和CPU連在一塊兒相互通訊的。數據庫

把計算機這一系列組件組合起來,咱們就拿到了一臺完整的計算機。如今咱們天天在用的我的PC、智能手機,乃至雲上的服務器,都是這樣一臺計算機。緩存

只有一臺計算機要解決的三個問題

可是,一臺計算機在數據中裏是不夠的。由於若是隻有一臺計算機,咱們會遇到三個核心問題。bash

第一個核心問題,叫做 垂直擴展和水平擴展的選擇問題,服務器

第二問題叫做 如何保持高可用性(High?Availability),網絡

第三個問題叫做 一致性問題(Consistency)。架構

圍繞這三個問題,其實就是咱們今天要講的主題,分佈式計算。固然,短短的一講確定講不完這麼大一個主題。分佈式計算拿出來單開一個專欄也綽綽有餘。咱們今天這裏講的目標,負載均衡

是讓你能理解水平擴展、高可用性這兩個核心問題。對於分佈式系統帶來的一致性問題,咱們會留在咱們的實戰篇裏面,再用案例來爲你們分析。運維

2、從硬件升級到水平擴展

從技術開發的角度來說,想要在2019年創業真的很幸福。異步

一、創業初期

只要在AWS或者阿里雲這樣的雲服務上註冊一個帳號,一個月花上一兩百塊錢,你就能夠有一臺在數據中內心面的服務器了。並且這臺服務器,能夠直接提供給世界各國人民訪問。若是你想要作海外市場,你能夠把這個服務器放在美國、歐洲、東南亞,任何一個你想要去的市場的數據中內心,而後把本身的網站部署在這臺服務器裏面就能夠了。分佈式

固然,這臺服務器就是咱們在第34講裏說的虛擬機。不過由於只是個業餘時間的小項目,一開始這臺服務器的配置也不會過高。我以我如今公司所用的Google Cloud爲例。最低的配置差很少是1個CPU核心、3.75G內存以及一塊10G的SSD系統盤。這樣一臺服務器每月的價格差很少是28美圓。

二、訪問量上來後到底選擇水平擴展仍是垂直擴展

幸運的是,你的網站很受你們歡迎,訪問量也上來了。這個時候,這臺單核心的服務器的性能有點不夠用了。這個時候,你須要升級你的服務器。因而,你就會面臨兩個選擇。

第一個選擇是升級如今這臺服務器的硬件,變成2個CPU核⼼、7.5G內存。這樣的選擇咱們稱之爲 垂直擴展(Scale Up)。

第二個選擇則是咱們再租一臺和以前同樣的服務器。因而,咱們有了2臺1個CPU核心、3.75G內存的服務器。這樣的選擇咱們稱之爲 水平擴展(Scale Out)。

一、成本上來比沒什麼差別

從成本上看起來沒有什麼差別。2核心、7.5G內存的服務器,成本是56.61美圓,而2臺1核心、3.75G內存的服務器價格,成本是57美圓,這之間的價格差別不到1%。

不過,垂直擴展和水平擴展看似是兩個不一樣的選擇,可是隨着流量不斷增長。到最後,只會變成一個選擇。那就是既會垂直擴展,又會水平擴展,而且最終依靠水平擴展,來支撐Google、Facebook、阿里、騰訊這樣體量的互聯網服務。

二、垂直擴展的優點

垂直擴展背後的邏輯和優點都很簡單。通常來講,垂直擴展一般不須要咱們去改造程序,也就是說,咱們 沒有研發成本。那爲何咱們最終仍是要用水平擴展呢?你能夠先本身想想。

三、那爲何選擇了水平擴展了

一、選擇水平擴展的緣由

緣由其實很簡單,由於咱們沒有辦法不停地去作垂直擴展。咱們在Google Cloud上如今可以買到的性能最好的服務器,是96個CPU核心、1.4TB的內存。若是咱們的訪問量逐漸增長,一臺96核心的服務器也支撐不了了,那麼咱們就沒有辦法再去作垂直擴展了。這個時候,咱們就不得不採用水平擴展的方案了。

96個CPU核心看起來是個很強大的服務器,可是你算一算就知道,其實它的計算資源並無多少。你如今多半在用一臺4核心,或者至少也是2核心的CPU。96個CPU也就是30~50臺⽇常使用的開發機的計算性能。而咱們今天在互聯網上遇到的問題,是天天數億的訪問量,靠30~50臺我的電腦的計算能裏想要要撐這樣的計算需求,可謂是天方夜譚了。

二、水平擴展須要咱們在軟件層面進行改善

然而,一旦開始採用水平擴展,咱們就會面臨在軟件層面改造的問題了。也就是咱們須要開始進行 分佈式計算了。咱們須要引如 負載均衡(Load?Balancer)這樣的組件,來進行流量分配。咱們須要拆分應用服務器和數據庫服務器,來進行垂直功能的切分。咱們也須要不一樣的應用之間經過消息隊列,來進行異步任務的執行。

 

 

 全部這些軟件層⾯的改造,其實都是在作分佈式計算的⼀個核⼼⼯做,就是經過消息傳遞(MessagePassing)⽽不是共享內存(Shared?Memory)的⽅式,讓多臺不一樣的計算機協做起來共同完成任務。

⽽由於咱們最終必然要進⾏⽔平擴展,咱們須要在系統設計的早期就基於消息傳遞⽽⾮共享內存來設計系統。即便這些消息只是在同⼀臺服務器上進⾏傳遞。

事實上,有很多增⻓迅猛的公司,早期沒有準備好經過⽔平擴展來⽀撐訪問量的狀況,⽽⼀味經過提高硬件配置Scale Up,來⽀撐更⼤的訪問量,最終影響了公司的存亡

最典型的例⼦,就是敗在Facebook⼿下的MySpace。

3、理解高可用性和單點故障

儘管在1個CPU核⼼的服務器支撐不了咱們的訪問量的時候,選擇垂直擴展是一個最簡單的辦法。不過若是是個人話,第一次擴展我會選擇水平擴展。

選擇水平擴展的一個很好的理由,固然是能夠「強迫」從開發的角度,儘早地讓系統可以支持水平擴展,避免在真的流量快速增長的時候,垂直擴展的解決方案跟不上趟。不過,其實還有一個更重要的理由,那就是
系統的可用性問題。

一、水平擴展另一個重要的理由就是系統的可用性

上面的1核變2核的垂直擴展的方式,擴展完以後,咱們仍是隻有1臺服務器。若是這臺服務器出現了一點硬件故障,好比,CPU壞了,那咱們的整個系統就壞了,就不可用了。

若是採用了水平擴展,即使有一臺服務器的CPU壞了,咱們還有另一臺服務器仍然可以提供服務。負載均衡可以經過健康檢測(Health Check)發現壞掉的服務器沒有響應了,就能夠自動把全部的流量切換到第2臺服務器上,這個操做就叫做故障轉移(Failover),咱們的系統仍然是可用的。

二、什麼是系統的可用性?

系統的 可用性(Avaiability)指的就是,咱們的系統能夠正常服務的時間佔比。不管是由於軟硬件故障,仍是須要對系統進行停機升級,都會讓咱們損失系統的可用性。可用性一般是一個百分比的數字來表示,比
如99.99%。咱們說,系統每月的可用性要保障在99.99%,也就是意味着一個月裏,你的服務宕機的時間不能超過4.32分鐘。

有些系統可用性的損失,是在咱們計劃內的。好比上面說的停機升級,這個就是所謂的計劃內停機時間(Scheduled Downtime)。有些系統可用性的損失,是在咱們計劃外的,好比一臺服務器的硬盤突然壞
了,這個就是所謂的計劃外停機時間(Unscheduled Downtime)。

三、系統的可用性必定不可能作到100%

咱們的系統是必定不可能作到100%可用的,特別是計劃外的停機時間。從簡單的硬件損壞,到機房停電、光纜被挖斷,乃至於各類天然災害,筆如地震、洪水、海嘯,都有可能使得咱們的系統不可用。做爲一個工程師和架構師,咱們要作的就是儘量低成本地提升系統的可用性。

一、硬件服務的可用性

我們的專欄是要講計算機組成原理,那咱們先來看一看硬件服務器的可用性。

如今的服務器的可用性都已經很不錯了,一般都能保障99.99%的可用性了。若是咱們有一個小小的三臺服務器組成的小系統,一臺部署了Nginx來做爲負載均衡和反向代理,一臺跑了PHP-FPM做爲Web應用服務
器,一臺用來做爲MySQL數據庫服務器。每臺服務器的可用性都是99.99%。那麼咱們整個系統的可用哪性是多少呢?你能夠先想想。

答案是:99.99%×99.99%×99.99%=99.97%在這個系統當中,這個數字看起來彷佛沒有那麼大區別。不過反過來看,咱們是從損失了0.01%的可用性,變成了損失0.03%的可用性,不可用的時間變成了原來的3倍。若是咱們有1000臺服務器,那麼整個的可用性,就會變成99.99%^1000=90.5%。也就是說,咱們的服務一年裏有超過一個月是不可用的。這可怎麼辦呀?

 

 二、單點故障問題

咱們先來分析一下緣由。之因此會出現這個問題,是由於在這個場景下,任何一臺服務器出錯了,整個系統就無法用了。這個問題就叫做 單點故障問題(Single Point of Failure,SPOF)。咱們這裏的這個假設特別糟糕。咱們假設這1000臺服務器,每個都存在單點故障問題。因此,咱們的服務也就特別脆弱,隨便哪臺出現點風吹草動,整個服務就掛了。

四、如何解決單點故障

要解決單點故障問題,第一點就是要移除單點。其實移除單點最典型的場景,在咱們水平擴展應用服務器的時候就已經看到了,那就是讓兩臺服務器提供相同的功能,而後經過負載均衡把流量分發到兩臺不一樣的服務器去。即便一臺服務器掛了,還有一臺服務器能夠正常提供服務。

一、不在一個服務器上、不在一個機架上、不在一個交換機上

不過光用兩臺服務器是不夠的,單點故障其實在數據中內心面無處不在。咱們如今用的是雲上的兩臺虛擬機。若是這兩臺虛擬機是託管在同一臺物理機上的,那這臺物理機自己又成爲了一個單點。那咱們就須要把
這兩臺虛擬機分到兩臺不一樣的物理機上。

不過這個仍是不夠。若是這兩臺物理機在同一個機架(Rack)上,那機架上的交換機(Switch)就成了一個單點。即便放到不一樣的機架上,仍是有可能出現整個數據中心遭遇意外故障的狀況。

二、異地多活

去年我本身就遇到過,部署在Azure上的服務所在的數據中信,由於散熱問題觸發了整個數據中心全部服務器被關閉的問題。面對這種狀況,咱們就須要設計進行 異地多活的系統設計和部署。因此,在現代的雲服
務,你在買服務器的時候能夠選擇服務器的area(地區)和zone(區域),⽽要不要把服務器放在不一樣的地區或者區域裏,也是避免單點故障的一個重要因素。

只是可以去除單點,其實咱們的可用性問題尚未解決。好比,上面咱們的負載均衡把流量均勻地分發到2臺服務器上,當一臺應用服務器掛掉的時候,咱們的確還有一臺服務器在提供服務。可是負載均衡會把一半的流量發到已經掛掉的服務器上,因此這個時候只能算做一半可用。

三、故障轉移機制

想要讓整個服務徹底可用,咱們就須要有一套故障轉移(Failover)機制。想要進行故障轉移,就首先要能發現故障。

以咱們這裏的PHP-FPM的Web應用爲例,負載均衡一般會定時去請求一個Web應用提供的健康檢測(Health?Check)的地址。這個時間間隔多是5秒鐘,若是連續2~3次發現健康檢測失敗,負載均衡就會
自動將這臺服務器的流量切換到其餘服務器上。因而,咱們就自動地產生了一次故障轉移。故障轉移的自動化在大型系統中是很重要的,由於服務器越多,出現故障基本就是個必然發生的事情。而自動化的故障轉移既可以減小運維的人手需求,也可以縮短從故障發現到問題解決的時間週期,提升可用性。

那麼,讓咱們算一算,經過水平擴展相同功能的服務器來去掉單點故障,而且經過健康檢查機制來觸發自動的故障轉移,這樣的可用性會變成多少呢?你能夠拿出紙和筆來試一下。

不知道你想明白應該怎麼算了沒有,在這種狀況下,咱們其實只要有任何一臺服務器可以正常運轉,就能正常提供服務。那麼,咱們的可⽤性就是:

100%-(100%-99.99%)×(100%-99.99%)=99.999999%

能夠看出,不能提供服務的時間就減小到了原來的萬分之一。

固然,在實際狀況中,可用性無法作到那麼理想的地步。光從硬件的角度,從服務器到交換機,從網線鏈接到機房電力,從機房的總體散熱到外部的光纖線路等等,可能出現問題的地方太多了。這也是爲何,咱們須要從整個系統層面,去設計系統的高可用性。

4、總結延伸

講到這力裏,相信你已經很清楚,爲何咱們須要水平擴展了。對於怎麼去設計整個硬件的部署,來保障高可用性,你應該也有了一個清晰的認識。這兩點也是分佈式計算在實踐中很是重要的應用場景。

不過,光有這兩點仍是不夠的。一旦系統⾥⾯有了不少臺服務器。特別是,爲了保障可用性,對於一樣功能的、有狀態的數據庫進行了水平的擴展,咱們就會面臨一個新的挑戰,那就是分區一致性問題。不過,這個問題更多的是一個軟件設計問題,我把它留在後面的實戰篇再進行講解。

咱們下面來回顧一下這一講的內容。咱們講了經過升級硬件規格來提高服務能能的垂直擴展。除此以外,也能夠經過增長服務器數量來提高服務能力。不過歸根到底,咱們必定要走上水平擴展的路徑。

一方面是由於垂直擴展不可持續;另外一方面,則是隻有水平擴展才能保障高可用性。而經過水平擴展保障高

可用性,則須要咱們作三件事情。第一個是理解可用性是怎麼計算的。服務器硬件的損壞只是可能致使可用性損失的因素之一,機房內的電路、散熱、交換機、網絡線路,都有可能致使可用性損失。而外部的光纜、天然災害,也都有可能形成咱們整個系統的不可用。

因此,在分析設計系統的時候,咱們須要儘量地排除單點故障。進一步地,對於硬件的故障,咱們還要有自動化的故障轉移策略。在這些策略都齊全以後,咱們才能真的長舒一口氣,在海量的負載和流量下安心睡個好覺。

相關文章
相關標籤/搜索