分布式架构发展
一,計(jì)算機(jī)發(fā)展史概述
1946 年情人節(jié)(2.14) , 世界上第一臺(tái)電子數(shù)字計(jì)算機(jī)誕生在美國(guó)賓夕法尼亞大學(xué)大學(xué),它的名字是:ENIAC; 這臺(tái)計(jì)算機(jī)占地170平米、重達(dá)30噸,每秒可進(jìn)行5000次加法運(yùn)算。第一臺(tái)電子計(jì)算機(jī)誕生以后,意味著一個(gè)日新月異的IT時(shí)代的到來(lái)。一方面單臺(tái)計(jì)算機(jī)的性能每年都在提升:從最早的 8位 CPU 到現(xiàn)在的64位CPU;從早期的MB級(jí)內(nèi)存到現(xiàn)在的GB級(jí)別內(nèi)存;從慢速的機(jī)械存儲(chǔ)到現(xiàn)在的固態(tài)SSD硬盤存儲(chǔ)。ENIAC之后,電子計(jì)算機(jī)便進(jìn)入了 IBM 主導(dǎo)的大型機(jī)時(shí)代,IBM大型機(jī)之父吉恩.阿姆達(dá)爾被認(rèn)為是有史以來(lái)最偉大的計(jì)算機(jī)設(shè)計(jì)師之一。1964年4月7日,在阿姆達(dá)爾的帶領(lǐng)下,歷時(shí)三年,耗費(fèi)50 億美元,第一臺(tái) IBM 大型機(jī) SYSTEM/360 誕生。這使得 IBM 在20 實(shí)際 50~60 年代統(tǒng)治整個(gè)大型計(jì)算機(jī)工業(yè),奠定了 IBM 計(jì)算機(jī)帝國(guó)的江山。由于高可靠性和超強(qiáng)的計(jì)算能力,即便在 X86 和云計(jì)算飛速發(fā)展的情況下,IBM 的大型機(jī)依然牢牢占據(jù)著一定的高端市場(chǎng)份額20 世紀(jì) 80 年代,在大型機(jī)霸主的時(shí)代,計(jì)算機(jī)架構(gòu)同時(shí)向兩個(gè)方向發(fā)展。
1. 以 CISC (微處理器執(zhí)行的計(jì)算機(jī)語(yǔ)言指令集)CPU為架構(gòu)的價(jià)格便宜的面向個(gè)人的PC。
2. 以 RISC (精簡(jiǎn)指令集計(jì)算機(jī))CPU為架構(gòu)的價(jià)格昂貴的面向企業(yè)的小型UNIX 服務(wù)器。
二,分布式架構(gòu)發(fā)展的里程碑
大型主機(jī)的出現(xiàn)。憑借著大型機(jī)超強(qiáng)的計(jì)算和I/O處理能力、穩(wěn)定性、安全性等,在很長(zhǎng)一段時(shí)間內(nèi),大型機(jī)引領(lǐng)了計(jì)算機(jī)行業(yè)及商業(yè)計(jì)算領(lǐng)域的發(fā)展。而集中式的計(jì)算機(jī)系統(tǒng)架構(gòu)也成為了主流。隨著計(jì)算機(jī)的發(fā)展,這種架構(gòu)越來(lái)越難以適應(yīng)人們的需求,比如說:
1. 由于大型主機(jī)的復(fù)雜性,導(dǎo)致培養(yǎng)一個(gè)能夠熟練運(yùn)維大型
主機(jī)的人的成本很高。
2. 大型主機(jī)很貴,一般只有土豪(政府、金融、電信)才能用得起.
3. 單點(diǎn)問題,一臺(tái)大型主機(jī)出現(xiàn)故障,那么整個(gè)系統(tǒng)將處于不可用狀態(tài)。而對(duì)于大型機(jī)的使用群體來(lái)說,這種不可用導(dǎo)致的損失是非常大的.
4. 科技在進(jìn)步,技術(shù)在進(jìn)步。PC機(jī)性能不斷提升,很多企業(yè)放棄大型機(jī)改用小型機(jī)及普通PC來(lái)搭建系統(tǒng)架構(gòu).
2.1 阿里巴巴在 2009 年發(fā)起了一項(xiàng)”去 IOE”運(yùn)動(dòng)
IOE 指的是 IBM 小型機(jī)、Oracle 數(shù)據(jù)庫(kù)、EMC 的高端存儲(chǔ)2009 年“去 IOE”戰(zhàn)略透露,到2013年5月17日最后一臺(tái)IBM小型機(jī)在支付寶下線。
為什么要去 IOE?
阿里巴巴過去一直采用的是 Oracle 數(shù)據(jù)庫(kù),并利用小型機(jī)和高端存儲(chǔ)設(shè)備提供高性能的數(shù)據(jù)處理和存儲(chǔ)服務(wù)。隨著業(yè)務(wù)的不斷發(fā)展,數(shù)據(jù)量和業(yè)務(wù)量呈爆發(fā)性增長(zhǎng),傳統(tǒng)的集中式Oracle 數(shù)據(jù)庫(kù)架構(gòu)在擴(kuò)展性方面遭遇瓶頸。
傳統(tǒng)的商業(yè)數(shù)據(jù)庫(kù)軟件(Oracle,DB2),多以集中式架構(gòu)為主,這些傳統(tǒng)數(shù)據(jù)庫(kù)軟件的最大特點(diǎn)就是將所有的數(shù)據(jù)都集中在一個(gè)數(shù)據(jù)庫(kù)中,依靠大型高端設(shè)備來(lái)提供高處理能力和擴(kuò)展性。集中式數(shù)據(jù)庫(kù)的擴(kuò)展性主要采用向上擴(kuò)展(Scale up)的方式,通過增加 CPU,內(nèi)存,磁盤等方式提高處理能力。這種集中式
數(shù)據(jù)庫(kù)的架構(gòu),使得數(shù)據(jù)庫(kù)成為了整個(gè)系統(tǒng)的瓶頸,已經(jīng)越來(lái)越不適應(yīng)海量數(shù)據(jù)對(duì)計(jì)算能力的巨大需求.
2.2 分布式系統(tǒng)的意義
升級(jí)單機(jī)處理能力的性價(jià)比越來(lái)越低
單機(jī)的處理能力主要依靠 CPU、內(nèi)存、磁盤。通過更換硬件做垂直擴(kuò)展的方式來(lái)提升性能,成本會(huì)越來(lái)越高。
單機(jī)處理能力存在瓶頸
單機(jī)處理能力存在瓶頸,CPU、內(nèi)存都會(huì)有自己的性能瓶頸,也就是說就算你是土豪不惜成本去提升硬件,但是硬件的發(fā)展速度和性能是有限制的。
穩(wěn)定性和可用性這兩個(gè)指標(biāo)很難達(dá)到
單機(jī)系統(tǒng)存在可用性和穩(wěn)定性的問題,這兩個(gè)指標(biāo)又是我們必須要去解決的。
三,分布式架構(gòu)的常見概念
3.1 集群
小飯店原來(lái)只有一個(gè)廚師,切菜洗菜備料炒菜全干。后來(lái)客人多了,廚房一個(gè)廚師忙不過來(lái),又請(qǐng)了個(gè)廚師,兩個(gè)廚師都能炒一樣的菜,這兩個(gè)廚師的關(guān)系是集群。
3.2 分布式
為了讓廚師專心炒菜,把菜做到極致,又請(qǐng)了個(gè)配菜師負(fù)責(zé)切菜,備菜,備料,廚師和配菜師的關(guān)系是分布式,一個(gè)配菜師也忙不過來(lái)了,又請(qǐng)了個(gè)配菜師,兩個(gè)配菜師關(guān)系是集群。
3.3 節(jié)點(diǎn)
節(jié)點(diǎn)是指一個(gè)可以獨(dú)立按照分布式協(xié)議完成一組邏輯的程序個(gè)體。在具體的項(xiàng)目中,一個(gè)節(jié)點(diǎn)表示的是一個(gè)操作系統(tǒng)上的進(jìn)程.
3.4 副本機(jī)制
副本(replica/copy)指在分布式系統(tǒng)中為數(shù)據(jù)或服務(wù)提供的冗余。
數(shù)據(jù)副本指在不同的節(jié)點(diǎn)上持久化同一份數(shù)據(jù),當(dāng)出現(xiàn)某一個(gè)節(jié)點(diǎn)的數(shù)據(jù)丟失時(shí),可以從副本上讀取到數(shù)據(jù)。數(shù)據(jù)副本是分布式系統(tǒng)中解決數(shù)據(jù)丟失問題的唯一手段。
服務(wù)副本表示多個(gè)節(jié)點(diǎn)提供相同的服務(wù),通過主從關(guān)系來(lái)實(shí)現(xiàn)服務(wù)的高可用方案。
3.5 中間件
中間件位于操作系統(tǒng)提供的服務(wù)之外,又不屬于應(yīng)用,他是位于應(yīng)用和系統(tǒng)層之間為開發(fā)者方便的處理通信、輸入輸出的一類軟件,能夠讓用戶關(guān)心自己應(yīng)用的部分。
四,架構(gòu)的發(fā)展過程
一個(gè)成熟的大型網(wǎng)站系統(tǒng)架構(gòu)并不是一開始就設(shè)計(jì)的非常完美,也不是一開始就具備高性能、高可用、安全性等特性,而是隨著用戶量的增加、業(yè)務(wù)功能的擴(kuò)展逐步完善演變過來(lái)的。在這個(gè)過程中,開發(fā)模式、技術(shù)架構(gòu)等都會(huì)發(fā)生非常大的變化。而針對(duì)不同業(yè)務(wù)特征的系統(tǒng),會(huì)有各自的側(cè)重點(diǎn),比如像淘這類的網(wǎng)站,要解決的是海量商品搜索、下單、支付等問題;像騰訊,要解決的是數(shù)億級(jí)別用戶的實(shí)時(shí)消息傳輸;百度所要解決的是海量數(shù)據(jù)的搜索。每一個(gè)類的業(yè)務(wù)都有自己不同的系統(tǒng)架構(gòu)。我們簡(jiǎn)單模擬一個(gè)架構(gòu)演變過程。
我們以 javaweb 為例,來(lái)搭建一個(gè)簡(jiǎn)單的電商系統(tǒng),從這個(gè)系統(tǒng)中來(lái)看系統(tǒng)的演變歷史;要注意的是,接下來(lái)的演示模型,
關(guān)注的是數(shù)據(jù)量、訪問量提升,網(wǎng)站結(jié)構(gòu)發(fā)生的變化,而不是具體關(guān)注業(yè)務(wù)功能點(diǎn)。其次,這個(gè)過程是為了讓大家更好的了,解網(wǎng)站演進(jìn)過程中的一些問題和應(yīng)對(duì)策略。
假如我們系統(tǒng)具備以下功能:
用戶模塊:用戶注冊(cè)和管理
商品模塊:商品展示和管理
交易模塊:創(chuàng)建交易及支付結(jié)算
第一階段(ALL IN ONE)
網(wǎng)站的初期也可以認(rèn)為是互聯(lián)網(wǎng)發(fā)展的早起,我們經(jīng)常會(huì)在單機(jī)上跑我們所有的程序和軟件。把所有軟件和應(yīng)用都部署在一臺(tái)機(jī)器上,這樣就完成一個(gè)簡(jiǎn)單系統(tǒng)的搭建,這個(gè)時(shí)候的講究的是效率。
第二階段 應(yīng)用服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器分離
隨著網(wǎng)站的上線,訪問量逐步上升,服務(wù)器的負(fù)載慢慢提高,在服務(wù)器還沒有超載的時(shí)候,我們應(yīng)該做好規(guī)劃,提升網(wǎng)站的負(fù)載能力。假如代碼層面的優(yōu)化已經(jīng)沒辦法繼續(xù)提高,在不提高單臺(tái)機(jī)器的性能,增加機(jī)器是一個(gè)比較好的方式,投入產(chǎn)出比非常高。這個(gè)階段增加機(jī)器的主要目的是講 web 服務(wù)器和
數(shù)據(jù)庫(kù)服務(wù)器拆分,這樣不僅提高了單機(jī)的負(fù)載能力,也提高了容災(zāi)能力。
第三階段,應(yīng)用服務(wù)器集群-應(yīng)用服務(wù)器負(fù)載告警,如何讓應(yīng)用服務(wù)器走向集群.
隨著訪問量的繼續(xù)增加,單臺(tái)應(yīng)用服務(wù)器已經(jīng)無(wú)法滿足需求。在假設(shè)數(shù)據(jù)庫(kù)服務(wù)器還沒有遇到性能問題的時(shí)候,我們可以增加應(yīng)用服務(wù)器,通過應(yīng)用服務(wù)器集群將用戶請(qǐng)求分流到各個(gè)服務(wù)器中,從而繼續(xù)提升負(fù)載能力。此時(shí)多臺(tái)應(yīng)用服務(wù)器之間沒
有直接的交互,他們都是依賴數(shù)據(jù)庫(kù)各自對(duì)外提供服務(wù)。
架構(gòu)發(fā)展到這個(gè)階段,各種問題也會(huì)慢慢呈現(xiàn)
a. 用戶請(qǐng)求由誰(shuí)來(lái)轉(zhuǎn)發(fā)到具體的應(yīng)用服務(wù)器
b. 用戶如果每次訪問到的服務(wù)器不一樣,那么如何維護(hù)session.
第四階段,數(shù)據(jù)庫(kù)壓力變大,數(shù)據(jù)庫(kù)讀寫分離
架構(gòu)演變到這里,并不是終點(diǎn)。上面我們把應(yīng)用層的性能拉上來(lái)了,但是數(shù)據(jù)庫(kù)的負(fù)載也在慢慢增大,那么怎么去提高數(shù)據(jù)庫(kù)層面的負(fù)
載呢?有了前面的思路以后,自然會(huì)想到增加服務(wù)器。但是假如我們單純的把數(shù)據(jù)庫(kù)一分為二,然后對(duì)于后續(xù)數(shù)據(jù)庫(kù)的請(qǐng)求,分別負(fù)載到兩臺(tái)數(shù)據(jù)庫(kù)服務(wù)器上,那么一定會(huì)造成數(shù)據(jù)庫(kù)不統(tǒng)一的問題。
所以我們一般先考慮讀寫分離的方式.
這個(gè)架構(gòu)的變化會(huì)帶來(lái)幾個(gè)問題
主從數(shù)據(jù)庫(kù)之間的數(shù)據(jù)同步;可以使用 mysql 自帶的master-slave 方式實(shí)現(xiàn)主從復(fù)制.
對(duì)應(yīng)數(shù)據(jù)源的選擇 ; 采用第三方數(shù)據(jù)庫(kù)中間件,例如 mycat
第五階段,使用搜索引擎緩解讀庫(kù)的壓力.
數(shù)據(jù)庫(kù)做讀庫(kù)的話,常常對(duì)模糊查找效率不是特別好,像電商類的網(wǎng)站,搜索是非常核心的功能,即便是做了讀寫分離,這個(gè)問題也不能有效解決。那么這個(gè)時(shí)候就需要引入搜索引擎了使用搜索引擎能夠大大提高我們的查詢速度,但是同時(shí)也會(huì)帶來(lái)一些附加的問題,比如維護(hù)索引的構(gòu)建。
第六階段 引入緩存機(jī)制緩解數(shù)據(jù)庫(kù)的壓力
隨著訪問量的持續(xù)增加,逐漸出現(xiàn)許多用戶訪問統(tǒng)一部分內(nèi)容情況,對(duì)于這些熱點(diǎn)數(shù)據(jù),沒必要每次都從數(shù)據(jù)庫(kù)去讀取,我們可以使用緩存技術(shù),比如 memcache、redis 來(lái)作為我們應(yīng)用層的緩存;另外在某些場(chǎng)景下,比如我們對(duì)用戶的某些IP的訪問頻率做限制,那這個(gè)放內(nèi)存中又不合適,放數(shù)據(jù)庫(kù)又太麻煩,這個(gè)時(shí)候可以使用Nosql 的方式比如 mongDB 來(lái)代替?zhèn)鹘y(tǒng)的關(guān)系型數(shù)據(jù)庫(kù).
第七階段 數(shù)據(jù)庫(kù)的水平/垂直拆分
我們的網(wǎng)站演進(jìn)的變化過程,交易、商品、用戶的數(shù)據(jù)都在同一個(gè)數(shù)據(jù)庫(kù)中,盡管采取了增加緩存,讀寫分離的方式,但是隨著數(shù)據(jù)庫(kù)的壓力持續(xù)增加,數(shù)據(jù)庫(kù)的瓶頸仍然是個(gè)最大的問題。因此我們可以考慮對(duì)數(shù)據(jù)的垂直拆分和水平拆分。
垂直拆分:把數(shù)據(jù)庫(kù)中不同業(yè)務(wù)數(shù)據(jù)拆分到不同的數(shù)據(jù)庫(kù)。
水平拆分:把同一個(gè)表中的數(shù)據(jù)拆分到兩個(gè)甚至跟多的數(shù)據(jù)庫(kù)中,水平拆分的原因是某些業(yè)務(wù)數(shù)據(jù)量已經(jīng)達(dá)到了單個(gè)數(shù)據(jù)庫(kù)的瓶頸,這時(shí)可以采取講表拆分到多個(gè)數(shù)據(jù)庫(kù)中。
第八階段 應(yīng)用的拆分
隨著業(yè)務(wù)的發(fā)展,業(yè)務(wù)越來(lái)越多,應(yīng)用的壓力越來(lái)越大。工程規(guī)模也越來(lái)越龐大。這個(gè)時(shí)候就可以考慮講應(yīng)用拆分,按照領(lǐng)域模型講我們的用戶、商品、交易拆分成多個(gè)子系統(tǒng)。
這樣拆分以后,可能會(huì)有一些相同的代碼,比如用戶操作,在商品和交易都需要查詢,所以會(huì)導(dǎo)致每個(gè)系統(tǒng)都會(huì)有用戶查詢?cè)L問相關(guān)
操作。這些相同的操作一定是要抽象出來(lái),否則就會(huì)是一個(gè)坑。所以通過走服務(wù)化路線的方式來(lái)解決。
那么服務(wù)拆分以后,各個(gè)服務(wù)之間如何進(jìn)行遠(yuǎn)程通信呢?通過 RPC 技術(shù),比較典型的有:webservice、hessian、http、RMI等等。前期通過這些技術(shù)能夠很好的解決各個(gè)服務(wù)之間通信問題,but,互聯(lián)網(wǎng)的發(fā)展是持續(xù)的,所以架構(gòu)的演變和優(yōu)化還在持續(xù)。
五,分布式系統(tǒng)的難點(diǎn)
毫無(wú)疑問,分布式系統(tǒng)對(duì)于集中式系統(tǒng)而言,在實(shí)現(xiàn)上會(huì)更加復(fù)雜。分布式系統(tǒng)將會(huì)是更難理解、設(shè)計(jì)、構(gòu)建和管理的,同時(shí)意味著應(yīng)用程序的根源問題更難發(fā)現(xiàn)。
5.1 三態(tài)
在集中式架構(gòu)中,我們調(diào)用一個(gè)接口返回的結(jié)果只有兩種,成功或者失敗,但是在分布式領(lǐng)域中,會(huì)出現(xiàn)“超時(shí)”這個(gè)狀態(tài)。
5.2 分布式事務(wù)
這是一個(gè)老生常談的問題,我們都知道事務(wù)就是一些列操作的原子性保證,在單機(jī)的情況下,我們能夠依靠本機(jī)的數(shù)據(jù)庫(kù)連
接和組件輕易做到事務(wù)的控制,但是分布式情況下,業(yè)務(wù)原子性操作很可能是跨服務(wù)的,這樣就導(dǎo)致了分布式事務(wù),例如 A和 B 操作分別是不同服務(wù)下的同一個(gè)事務(wù)操作內(nèi)的操作,A 調(diào)用 B,A 如果可以清楚的知道 B 是否成功提交從而控制自身的提交還是回滾操作,但是在分布式系統(tǒng)中調(diào)用會(huì)出現(xiàn)一個(gè)新狀態(tài)就是超時(shí),就是 A 無(wú)法知道 B 是成功還是失敗,這個(gè)時(shí)候 A是提交本地事務(wù)還是回滾呢?其實(shí)這是一個(gè)很難的問題,如果強(qiáng)行保證事務(wù)一致性,可以采取分布式鎖,但是那樣會(huì)增加系統(tǒng)復(fù)雜度而且會(huì)增大系統(tǒng)的開銷,而且事務(wù)跨越的服務(wù)越多,消耗的資源越大,性能越低,所以最好的解決方案就是避免分布式事務(wù)。還有一種解決方案就是重試機(jī)制,但是重試如果不是查詢接口,必然涉及到數(shù)據(jù)庫(kù)的變更,如果第一次調(diào)用成功但是沒返回成功結(jié)果,那調(diào)用方第二次調(diào)用對(duì)調(diào)用方來(lái)說依然是重試,但是對(duì)于被調(diào)用方來(lái)說是重復(fù)調(diào)用,例如 A 向 B 轉(zhuǎn)賬,A-100,B +100,這樣會(huì)導(dǎo)致A扣了100,而B增加200。這樣的結(jié)果不是我們期望的,因此需在要寫入的接口做冪等設(shè)計(jì)。多次調(diào)用和單次調(diào)用是一樣的效果。通常可以設(shè)置一個(gè)唯一鍵,在寫入的時(shí)候查詢是否已經(jīng)存在,避免重復(fù)寫入。但是冪等設(shè)計(jì)的一個(gè)前提就是服務(wù)是高可用,否則無(wú)論怎么重試都不能調(diào)用返回一個(gè)明確的結(jié)果調(diào)用方會(huì)一直等待,雖然可以限制重試的次數(shù),但是這已經(jīng)進(jìn)入了異常狀態(tài)了,甚至到了極端情況還是需要人肉補(bǔ)償處理。其實(shí)根據(jù) CAP 和 BASE 理論,不可能在高可用分布式情況下做到一致性,一般都是最終一致性保證。
5.3 負(fù)載均衡
每個(gè)服務(wù)單獨(dú)部署,為了達(dá)到高可用,每個(gè)服務(wù)至少是兩臺(tái)機(jī)器,因?yàn)榛ヂ?lián)網(wǎng)公司一般使用可靠性不是特別高的普通機(jī)器,長(zhǎng)期運(yùn)行宕機(jī)概率很高,所以兩臺(tái)機(jī)器能夠大大降低服務(wù)不可用的可能性,這正大型項(xiàng)目會(huì)采用十幾臺(tái)甚至上百臺(tái)來(lái)部署一個(gè)服務(wù),這不僅是保證服務(wù)的高可用,更是提升服務(wù)的 QPS,但是這樣又帶來(lái)一個(gè)問題,一個(gè)請(qǐng)求過來(lái)到底路由到哪臺(tái)機(jī)器?路由算法很多,有 DNS 路由,如果 session 在本機(jī),還會(huì)根據(jù)用戶 id 或則 cookie等信息路由到固定的機(jī)器,當(dāng)然現(xiàn)在應(yīng)用服務(wù)器為了擴(kuò)展的方便都會(huì)設(shè)計(jì)為無(wú)狀態(tài)的,session 會(huì)保存到專有的 session 服務(wù)器,所以不會(huì)涉及到拿不到 session 問題。那路由規(guī)則是隨機(jī)獲取么?這是一個(gè)方法,但是據(jù)我所知,實(shí)際情況肯定比這個(gè)復(fù)雜,在一定范圍內(nèi)隨機(jī),但是在大的范圍也會(huì)分為很多個(gè)域,例如如果為了保證異地多活的多機(jī)房,夸機(jī)房調(diào)用的開銷太大,肯定會(huì)優(yōu)先選擇同機(jī)房的服務(wù),這個(gè)要參考具體的機(jī)器分布來(lái)考慮。
5.4 一致性
數(shù)據(jù)被分散或者復(fù)制到不同的機(jī)器上,如何保證各臺(tái)主機(jī)之間的數(shù)據(jù)的一致性將成為一個(gè)難點(diǎn)。
5.5 故障的獨(dú)立性
分布式系統(tǒng)由多個(gè)節(jié)點(diǎn)組成,整個(gè)分布式系統(tǒng)完全出問題的概率是存在的,但是在時(shí)間中出現(xiàn)更多的是某個(gè)節(jié)點(diǎn)出問題,其他節(jié)點(diǎn)都沒問題。這種情況下我們實(shí)現(xiàn)分布式系統(tǒng)時(shí)需要考慮得更加全面些。
原文:https://www.toutiao.com/i6688278093297091084/
轉(zhuǎn)載于:https://juejin.im/post/5cd2c99851882535d06e5754
總結(jié)
- 上一篇: Vue和其他框架的区别
- 下一篇: java springcloud版b2b