国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
分布式架構(gòu)--基本思想?yún)R總

在互聯(lián)網(wǎng)大行其道的今天,各種分布式系統(tǒng)已經(jīng)司空見慣。搜索引擎、電商網(wǎng)站、微博、微信、O2O平臺(tái)。。凡是涉及到大規(guī)模用戶、高并發(fā)訪問的,無一不是分布式。

關(guān)于分布式系統(tǒng),并沒有一個(gè)標(biāo)準(zhǔn)答案,說某某架構(gòu)一定是最好的。不同的業(yè)務(wù)形態(tài)所面對(duì)的挑戰(zhàn)不一樣,使用的架構(gòu)設(shè)計(jì)也不一樣,通常都需要具體業(yè)務(wù)具體分析。

但不管那種業(yè)務(wù),不管何種分布式系統(tǒng),有一些基本的思想還是相通的。本文將對(duì)這些基本思想進(jìn)行一個(gè)梳理匯總。

分拆

系統(tǒng)分拆

微信的架構(gòu)師說過一句話:“大系統(tǒng)小做“。對(duì)于一個(gè)大的復(fù)雜系統(tǒng),首先想到的就是對(duì)其分拆,拆成多個(gè)子系統(tǒng)。每個(gè)子系統(tǒng)自己的存儲(chǔ)/Service/接口層,各個(gè)子系統(tǒng)獨(dú)立開發(fā)、測(cè)試、部署、運(yùn)維。
從團(tuán)隊(duì)管理角度講,也可以不同團(tuán)隊(duì)用自己熟悉的語言體系,團(tuán)隊(duì)之間基于接口進(jìn)行協(xié)作,職責(zé)清晰,各司其職。

子系統(tǒng)分拆

拆成子系統(tǒng)之后,子系統(tǒng)內(nèi)部又可以分層,分模塊。當(dāng)然,這里“系統(tǒng)“,“子系統(tǒng)“,“層“,“模塊“ 都只是一個(gè)相對(duì)概念。在一個(gè)系統(tǒng)里面,某個(gè)模塊復(fù)雜到一定程度,會(huì)把它抽出來,單獨(dú)做成一個(gè)系統(tǒng);而在初期,很大簡(jiǎn)單模塊,可能不回拆分,集中在一個(gè)系統(tǒng)里面。
這就像一個(gè)生物組織,自身是在不斷成長、演化、有分有合,不斷變化發(fā)展的。

存儲(chǔ)分拆

Nosql:對(duì)于Nosql數(shù)據(jù)庫,比如MongoDB,其天生就是分布式的,很容易實(shí)現(xiàn)數(shù)據(jù)的分片。
MySQL: 對(duì)于mysql,或者其它關(guān)系型數(shù)據(jù)庫,就會(huì)設(shè)計(jì)到分庫分表。而分庫分表,就會(huì)涉及到幾個(gè)關(guān)鍵性的問題:切分維度,join的處理,分布式事務(wù)

計(jì)算分拆

計(jì)算的分拆有2種思路:
數(shù)據(jù)分拆:一個(gè)大的數(shù)據(jù)集,拆分成多個(gè)小的數(shù)據(jù)集,并行計(jì)算。
比如大規(guī)模數(shù)據(jù)歸并排序

任務(wù)分拆:把一個(gè)長的任務(wù),拆分成幾個(gè)環(huán)節(jié),各個(gè)環(huán)節(jié)并行計(jì)算。

Java中多線程的Fork/Join框架,Hadoop中的Map/Reduce,都是計(jì)算分拆的典型框架。其思路都是相似的,先分拆計(jì)算,再合并結(jié)果。

再比如分布式的搜索引擎中,數(shù)據(jù)分拆,分別建索引,查詢結(jié)果再合并。

并發(fā)

最常見的就是多線程,盡可能提高程序的并發(fā)度。
比如多次rpc順序調(diào)用,通過異步rpc轉(zhuǎn)化為并發(fā)調(diào)用;
比如數(shù)據(jù)分片,你的一個(gè)Job要掃描全表,跑幾個(gè)小時(shí),數(shù)據(jù)分片,用多線程,性能會(huì)加快好幾倍。

緩存

緩存大家都不陌生,遇到性能問題,大家首先想到的就是緩存。關(guān)于緩存,一個(gè)關(guān)鍵點(diǎn)就是:緩存的粒度問題。

比如Tweet的架構(gòu),緩存的粒度從小到大,有Row Cache, Vector Cache, Fragment Cache, Page Cache。

粒度越小,重用性越好,但查詢需要多次,需要數(shù)據(jù)拼裝;
粒度越大,越容易會(huì)失效,任何一個(gè)小的地方改動(dòng),都可能造成緩存的失效。

在線計(jì)算 vs. 離線計(jì)算 / 同步 vs. 異步

在實(shí)際的業(yè)務(wù)需求中,并不是所有需要都需要完全實(shí)時(shí)的:
比如內(nèi)部針對(duì)產(chǎn)品、運(yùn)營開發(fā)的各種報(bào)表查詢、分析系統(tǒng);
比如微博的傳播,我發(fā)了一個(gè)微博,我的粉絲延遲幾秒才看到,這是可以接受的,因?yàn)樗⒉粫?huì)注意到晚了幾秒;
比如搜索引擎的索引,我發(fā)了一篇博客,可能幾分鐘之后,才會(huì)被搜索引擎索引到;
比如支付寶轉(zhuǎn)帳、提現(xiàn),也并非這邊轉(zhuǎn)出之后,對(duì)方立即收到;
。。。

這類例子很多。這種“非實(shí)時(shí)也可以接受“的場(chǎng)景,就為架構(gòu)的設(shè)計(jì)贏得了充分的回旋余地。

因?yàn)榉菍?shí)時(shí),我們就可以做異步,比如使用消息隊(duì)列,比如使用后臺(tái)的Job,周期性處理某類任務(wù);

也因?yàn)榉菍?shí)時(shí),我們可以做讀寫分離,讀和寫不是完全同步,比如Mysql的Master-Slave。

全量 + 增量

全量/增量其實(shí)也是在線/離線的思路:
比如搜索引擎的全量索引 + 增量索引,前者是為了吞吐,后者為了實(shí)時(shí);
比如OceanBase數(shù)據(jù)庫,每次更新存在一個(gè)小表里面,定期merge;

Push vs. Pull

在所有分布式系統(tǒng)中,都涉及到一個(gè)基本問題:節(jié)點(diǎn)之間(或者2個(gè)子系統(tǒng)之間)的狀態(tài)通知。比如一個(gè)節(jié)點(diǎn)狀態(tài)變更了,要通知另外一個(gè)節(jié)點(diǎn),都有2種策略:
Push: 節(jié)點(diǎn)A狀態(tài)變了, push給節(jié)點(diǎn)B
Pull: 也就是輪詢。節(jié)點(diǎn)B周期性的去詢問節(jié)點(diǎn)A的狀態(tài)。

這個(gè)問題不光出現(xiàn)在分布式系統(tǒng)中,可以說是編寫代碼的一個(gè)基本問題。對(duì)應(yīng)到面向?qū)ο蟮木幊讨?,也就是常說的“雙向關(guān)聯(lián)”這種耦合問題。

A調(diào)用B,B再回調(diào)A,這種情形,在系統(tǒng)開發(fā)中經(jīng)常出現(xiàn)。再復(fù)雜一點(diǎn),多個(gè)模塊之間,彼此調(diào)用,調(diào)用關(guān)系跟蜘蛛網(wǎng)一樣。

這個(gè)問題的出現(xiàn),就和Push/Pull的策略密切相關(guān):
A調(diào)用B,那邏輯就會(huì)寫在B這邊;B調(diào)用A,邏輯就會(huì)寫在A這邊。所以是采用主動(dòng)調(diào)用的pull方式,還是回調(diào)的push方式,會(huì)嚴(yán)重影響職責(zé)在各個(gè)模塊或者子系統(tǒng)里面的分配。

批量

批量其實(shí)也是在線/離線的一種思想,把實(shí)時(shí)問題,轉(zhuǎn)化為一個(gè)批量處理的問題,從而降低對(duì)系統(tǒng)吞吐量的壓力
比如Kafka中的批量發(fā)消息;
比如廣告扣費(fèi)系統(tǒng)中,把多次點(diǎn)擊累積在一起扣費(fèi);
。。

重寫輕讀 vs 重讀輕寫

重寫輕讀,本質(zhì)就是“空間換時(shí)間“。你不是計(jì)算起來耗時(shí),延遲高嗎,那我可以提前計(jì)算,然后存儲(chǔ)起來。取的時(shí)候,直接去取。

我們通常對(duì)Mysql的用法,都是重讀輕寫,寫的時(shí)候,簡(jiǎn)單;查的時(shí)候,做復(fù)雜的join計(jì)算,返回結(jié)果。這樣做的好處是容易做到數(shù)據(jù)的強(qiáng)一致性,不會(huì)因?yàn)樽侄稳哂?,造成?shù)據(jù)的不一致。但是性能可能就是問題。

而微博的Feeds架構(gòu),就是典型的重寫輕讀。我要去看Feeds,按通常的mysql的做法,我要先去查我關(guān)注的所有的人,然后把所有人的消息排序,分頁返回。很顯然,在大數(shù)據(jù)量下,這個(gè)會(huì)很耗時(shí)。
而如果采用重寫輕讀,怎么做呢?你不是要看Feeds嗎,那就為每個(gè)人準(zhǔn)備一個(gè)Feeds,或者說收件箱。某個(gè)人發(fā)了微博之后,把他的微博擴(kuò)散到所有人的收件箱,這個(gè)擴(kuò)散是異步的,在后臺(tái)擴(kuò)散。這樣每個(gè)人看自己的Feeds的時(shí)候,直接去自己的收件箱取就可以了。

讀寫分離

同樣,對(duì)傳統(tǒng)的單機(jī)Mysql數(shù)據(jù)庫,讀和寫是完全同步的。寫進(jìn)去的內(nèi)容,立馬就可以讀到。
但在很多業(yè)務(wù)場(chǎng)景下,讀和寫并不需要完全同步。這個(gè)時(shí)候,就可以分開存儲(chǔ),寫到一個(gè)地方,再異步的同步到另一個(gè)地方。這樣就可以實(shí)現(xiàn)讀寫分離。
比如Mysql的Master/Slave就是個(gè)典型,Slave上面的數(shù)據(jù)并不是和Master實(shí)時(shí)同步的;
再比如各種報(bào)表分析,OLTP/OLAP,線上/線下數(shù)據(jù)分離,線上數(shù)據(jù)定期同步到Hive集群,再做分析。

動(dòng)靜分離

動(dòng)靜分離的典型例子就是網(wǎng)站的前端,動(dòng)態(tài)的頁面,放在web服務(wù)器上;靜態(tài)的css/jss/img,直接放到CDN上,這樣既提高性能,也極大的降低服務(wù)器壓力。

按照這個(gè)思路,很多大型網(wǎng)站都致力于動(dòng)態(tài)內(nèi)容的靜態(tài)化,靜態(tài)化之后,就可以很容易的緩存。

冷熱分離

比如定期把mysql中的歷史數(shù)據(jù),同步到hive

限流

現(xiàn)在很多電商都會(huì)有秒殺活動(dòng),秒殺的一個(gè)特點(diǎn)就是商品很少,但短時(shí)間內(nèi)流量暴增,服務(wù)器完全處理不了這么多請(qǐng)求。

應(yīng)對(duì)這類問題的一個(gè)基本思路就是限流,既然處理不了那么多請(qǐng)求,既然很大人進(jìn)去了,也是搶不到的。那索性不要放那么多人進(jìn)去。

這個(gè)和我們?nèi)粘I钪?,?jié)假日,某個(gè)景點(diǎn)人數(shù)過多,限制人流量是同樣的道理。

服務(wù)熔斷與降級(jí)

服務(wù)降級(jí)是系統(tǒng)的最后一道保險(xiǎn)。在一個(gè)復(fù)雜系統(tǒng)內(nèi)部,一個(gè)系統(tǒng)往往會(huì)調(diào)用其它很大系統(tǒng)的服務(wù)。在大流量的情況下,我們可能會(huì)在保證主流程能正常工作的情況下,對(duì)其它服務(wù)做降級(jí)。

所謂降級(jí),也就是當(dāng)某個(gè)服務(wù)不可用時(shí),干脆就別讓其提供服務(wù)了,直接返回一個(gè)缺省的結(jié)果。雖然這個(gè)服務(wù)不可用,但它不至于讓整個(gè)主流程癱瘓,這就可以最大限度的保證核心系統(tǒng)可用。

CAP理論

上面講的各種思想,用一個(gè)更大的思想來概括的話,就是CAP。

Consistency:數(shù)據(jù)一致性,這個(gè)很容易理解,就是沒有臟數(shù)據(jù)。我們知道,在Mysql中有一致性的概念,比如參照完整性約束、事務(wù)等。但這里的C主要特指同1份數(shù)據(jù)的多個(gè)備份之間的一致性。

Availability:可用性有2重意思,一個(gè)是說穩(wěn)定性,服務(wù)可用,不會(huì)掛;另外一個(gè)是性能,也就是要快,如果延遲很高,經(jīng)常超時(shí),那和掛了也就區(qū)別不大了。

Partition tolerance(分區(qū)容錯(cuò)性):分區(qū),其實(shí)指網(wǎng)絡(luò)分區(qū)。當(dāng)你把數(shù)據(jù)從1個(gè)物理設(shè)備,分到多個(gè)物理設(shè)備之后,設(shè)備之間必然是通過網(wǎng)絡(luò)進(jìn)行通信。這就會(huì)遇到網(wǎng)絡(luò)分區(qū),也就是典型的“2將軍問題“,網(wǎng)絡(luò)超時(shí)時(shí)間不定。學(xué)術(shù)上有個(gè)詞,叫“異步通信環(huán)境“。

以前說CAP理論,說對(duì)于一個(gè)分布式系統(tǒng),上面3個(gè),只能同時(shí)滿足2個(gè)。但這個(gè)其實(shí)不準(zhǔn)確,P其實(shí)一定存在,是你避免不了的。能做的,其實(shí)主要是在C和A之間權(quán)衡。

比如拿Mysql來說,它的C最強(qiáng),A次之,P最弱。如果你為了A,給數(shù)據(jù)做冗余,比如重寫輕讀,那C就很難保證;為了P,給數(shù)據(jù)做分庫分表,那就做不了事務(wù);

比如Nosql,P最強(qiáng),可以很好的做數(shù)據(jù)拆分,但C就不夠,做不了事務(wù);

比如微博系統(tǒng),對(duì)C的要求降低,就可以加很多緩存,提高A;數(shù)據(jù)分片,提高P;

而支付,交易轉(zhuǎn)帳,對(duì)C的要求很高,就不能簡(jiǎn)單的用Cache來提高性能

最終一致性

前面提到,在分布式系統(tǒng)中,因?yàn)閿?shù)據(jù)的分拆,服務(wù)的分拆,強(qiáng)一致性就很難保證。這個(gè)時(shí)候,用的最多的就是“最終一致性“。

強(qiáng)一致性,弱一致性,最終一致性,是一致性的幾個(gè)不同的等級(jí)。在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中,通過事務(wù)來保證強(qiáng)一致性。

但在分布式系統(tǒng)中,通常都會(huì)把強(qiáng)一致性折中成最終一致性,從而變相的解決分布式事務(wù)問題。

典型的轉(zhuǎn)帳的例子,A給B轉(zhuǎn)帳1萬塊錢,A的賬號(hào)扣1萬,B的賬號(hào)加1萬。但這2步未必需要同時(shí)發(fā)生, A的扣完之后,B的賬號(hào)上面未必立馬就有,但只要保證B最終可以收到就可以了。

最終一致性的實(shí)現(xiàn),通常都需要一個(gè)高可靠的消息隊(duì)列。關(guān)于這個(gè),網(wǎng)上有各種分享文章,后續(xù)也會(huì)對(duì)這個(gè)問題單獨(dú)闡述。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
架構(gòu)師之路,分布式架構(gòu)下數(shù)據(jù)庫一致性常用方法初探
高并發(fā)架構(gòu)系列:數(shù)據(jù)庫主從同步的3種一致性方案實(shí)現(xiàn),優(yōu)劣比較
分布式架構(gòu)心得
分布式緩存的通用方法—《可伸縮服務(wù)架構(gòu)》
《大型技術(shù)架構(gòu)》讀書筆記
『互聯(lián)網(wǎng)架構(gòu)』軟件架構(gòu)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服