分布式
分布式其他
1. 談談業(yè)務中使用分布式的場景
分布式是將一個業(yè)務拆分不同的子業(yè)務陪拘,分布在不同的機器上執(zhí)行。有些人會認為分布式=集群茬底。然而集群本意是指多臺服務器幾種在一起克婶,實現(xiàn)同一業(yè)務,可以視為一臺計算機扛芽。分布式的組織松散,不像集群有著極強的組織性积瞒,一臺服務器宕機川尖,其他的可以代替其進行功能處理,而分布式的每一個節(jié)點都完成不同的業(yè)務茫孔,一個節(jié)點宕機了這個業(yè)務就無法訪問了叮喳。
分布式的每一個節(jié)點都可以用作集群,而集群卻不一定是分布式银酬。
分布式是在服務應用層隨著用戶量的增加嘲更,并發(fā)量增加,但項目難以承受如此巨大的并發(fā)請求而導致的性能瓶頸揩瞪。而對于底層數(shù)據(jù)庫層而言,隨著業(yè)務的發(fā)展篓冲,數(shù)據(jù)庫存儲信息過多李破,多大,也會導致數(shù)據(jù)庫壓力變大壹将,從而引起性能瓶頸嗤攻。
分布式是對于以上的解決方案。我們可以綜合使用分布式和集群來進行高并發(fā)高可用系統(tǒng)的開發(fā)诽俯。
參考:
《面試題:談談業(yè)務中使用分布式的場景》
《分布式和集群區(qū)別妇菱?什么是云計算平臺?分布式的應用場景?》
2. Session 分布式方案
在集群/分布式環(huán)境下必須要考慮用戶訪問所產(chǎn)生的session如何處理闯团。如果不做任何處理的話辛臊,如果用戶兩次訪問請求分別被不同服務器處理,則會導致分別有兩個session被創(chuàng)建房交,而且第二次無法通過session域獲取可能需要的數(shù)據(jù)彻舰,這將會成為系統(tǒng)設計的致命缺陷。
因此在分布式系統(tǒng)中候味,我們必須通過一定的策略來確保一個session必須能夠被不同的服務器獲取或者一個用戶的所有請求必須被同一臺服務器處理刃唤。
- 粘性session
將用戶鎖定到某一服務器上。當一個服務器接收了用戶第一次請求白群,則以后該用戶所有請求都將由這臺服務器處理尚胞。這種方案不需要對session做任何特殊處理但缺乏容錯性:如果服務器故障,用戶被迫轉移到另一臺服務器帜慢,或不同服務器實現(xiàn)不同功能辐真,用戶所請求的功能只能由另一臺服務器實現(xiàn)時,都會導致session失效崖堤。此功能可以通過在Nginx配置而輕易達成侍咱。 - 服務器session復制
任何一個服務器上的session發(fā)生改變,該節(jié)點會把這個session的所有內(nèi)容序列化密幔,然后廣播給其他節(jié)點而不管其他服務器需不需要session楔脯,以此來保證session同步。
該方案容錯率高胯甩,各個服務器間的session更夠實時響應昧廷。但會對網(wǎng)絡負荷造成壓力,如果session量大的話可能造成網(wǎng)絡堵塞偎箫,拖慢服務器性能木柬。此方案可通過tomcat開啟集群后配置網(wǎng)絡廣播實現(xiàn)。 - session共享機制
使用分布式緩存方案例如memcached淹办,redis眉枕。但要求其必須是集群。
此方案容錯高怜森,session實時響應速挑。
使用相應的開源插件可以達成此方案。 - session持久化到數(shù)據(jù)庫
使用一個數(shù)據(jù)庫專門存儲session信息以保證session的持久化副硅。
此方案當服務器出現(xiàn)問題時姥宝,session不會丟失。但本身數(shù)據(jù)庫的訪問速度就是很多系統(tǒng)的業(yè)務場景恐疲,都應該降低查詢數(shù)據(jù)庫的次數(shù)腊满,此方法會導致增加數(shù)據(jù)庫的訪問套么,當訪問量很大時甚至會拖垮數(shù)據(jù)庫。 - terracotta實現(xiàn)session復制
terracotta的基本原理是對于集群鍵共享的數(shù)據(jù)碳蛋,當一個節(jié)點發(fā)生變化的時候胚泌,terracotta只把變化的部分發(fā)送給terracotta服務器,然后由服務器把它轉發(fā)給真正需要這個數(shù)據(jù)的節(jié)點疮蹦≈畛伲可以認為是第二種方案的優(yōu)化。
此方案對網(wǎng)絡的壓力很小愕乎,也不比浪費CPU時間和內(nèi)存進行大量的序列化操作阵苇。把這種集群間數(shù)據(jù)共享的機制應用在session同步上,既避免了對數(shù)據(jù)庫的依賴感论,又能達到負載均衡和災難恢復的效果绅项。
參考:
《【Linux運維-集群技術進階】集群/分布式環(huán)境下5種session處理策略》
3. Session 分布式處理
我沒分清楚此題跟上面那題有什么區(qū)別,請參見2題比肄。
4. 分布式鎖的應用場景快耿、分布式鎖的產(chǎn)生原因、基本概念
在分布式場景下很多情況都需要實現(xiàn)最終一致性芳绩。在設計遠程上下文的領域事件的時候掀亥,為了保證最終一致性,在通過領域事件進行通訊的方式中妥色,可以共享存儲搪花,做全局XA事務,也可以借助消息中間件嘹害,和采用分布式鎖撮竿。
基于分布式鎖的解決方案都是相較于持久化方案提供了高可用性,并且支持豐富化的使用場景笔呀。
參考:
《分布式鎖》
5. 分布式鎖的常見解決方案
- 數(shù)據(jù)庫鎖表
數(shù)據(jù)庫鎖能實現(xiàn)一個簡單的避免共享資源被多個系統(tǒng)操作的情況幢踏,在并發(fā)量不高的情況下身隐,數(shù)據(jù)庫鎖的性能時可以依賴的燃乍,而且由于數(shù)據(jù)庫的數(shù)據(jù)具有持久化的特性绘盟,可以滿足一般的應用需求晤碘。
但數(shù)據(jù)庫鎖實現(xiàn)智能是非阻塞鎖,如果無法獲得會返回失敗喊递,且沒有過期時間袭艺,導致如果程序異常會無法釋放鎖庸诱,表將會被鎖導致鎖表情況產(chǎn)生敛助。且這把鎖無法重入而且無法解決數(shù)據(jù)庫宕機的問題。如果宕機屋确,會使整個應用無法工作纳击。 - 緩存鎖
使用緩存作為分布鎖续扔,性能非常強大,redis可以達到每秒100k的操作次數(shù)焕数,足以滿足絕大部分應用的鎖定需求纱昧。
redis鎖定的原理是利用setex命令,即只有在某個key不存在的情況下才能set成功該key堡赔,這就達到了多個進程并發(fā)去set同一個key识脆,只有一個進程能夠set成功。且redis自帶expire功能可以讓我們無需主動去產(chǎn)出鎖善已。且在2.6.12版本之后灼捂,redis的set命令直接設置NX和EX屬性,一個命令就能完成原子性的加鎖和設計過期時間换团。
緩存鎖的性能優(yōu)異悉稠,但由于數(shù)據(jù)保存于內(nèi)存,一旦緩存服務宕機艘包,數(shù)據(jù)將丟失的猛。 - 分布式緩存鎖——Redlock
redis作者鑒于單點redis作為分布式鎖的可能出現(xiàn)的鎖數(shù)據(jù)丟失問題,提出了Redlock算法想虎,該算法實現(xiàn)了比單一節(jié)點更安全卦尊、可靠的分布式鎖管理(DLM)。
使用Redlock算法舌厨,可以保證在掛掉最多2個節(jié)點的時候岂却,分布式鎖服務仍然能工作,這相比之前的數(shù)據(jù)庫鎖和緩存鎖大大提高了可用性邓线,由于redis的高效性能淌友,分布式緩存鎖性能并不比數(shù)據(jù)庫鎖差。 - zookeeper
zookeeper實現(xiàn)了類似paxos協(xié)議骇陈,是一個擁有多個節(jié)點分布式協(xié)調(diào)服務震庭。對zookeeper寫入請求會轉發(fā)到leader,leader寫入完成你雌,并同步到其他節(jié)點器联,直到所有節(jié)點都寫入完成,才返回客戶端寫入成功婿崭。它支持watcher機制拨拓,這樣實現(xiàn)阻塞鎖,可以watch鎖數(shù)據(jù)氓栈,等到數(shù)據(jù)被刪除渣磷,zookeeper會通知客戶端去重新競爭鎖。zookeeper的數(shù)據(jù)也支持臨時節(jié)點的概念授瘦,即客戶端寫入的數(shù)據(jù)是臨時數(shù)據(jù)醋界,在客戶端宕機后竟宋,臨時數(shù)據(jù)會被刪除,這樣就實現(xiàn)了鎖的異常釋放形纺。使用這樣的方式丘侠,就不需要給鎖增加超時自動釋放的特性了。
參考:
《分布式鎖》
6. 分布式事務的常見解決方案
分布式事務的處理一直以來都是個難題逐样。
- 2PC方案--強一致性
數(shù)據(jù)更新成功后蜗字,,任意時刻所有副本中的數(shù)據(jù)都是一致的脂新,一般采用同步方式實現(xiàn)挪捕。
2PC的核心原理是通過提交分階段和記日志的方式,記錄下事務提交所處的階段狀態(tài)戏羽,在組件宕機重啟后担神,可通過日志恢復事務提交的階段狀態(tài),并在這個狀態(tài)節(jié)點重試始花。 - eBay時間隊列方案 -- 最終一致性
弱一致性地一種形式妄讯,數(shù)據(jù)更新成功后,系統(tǒng)不城虐立即可以返回最新新入的值酷宵,但是保證最終會返回上一次更新操作的值亥贸。
eBay事件隊列是將需要分布式處理的任務通過消息或者日志的方式來異步執(zhí)行,消息或日志可以存到本地文件浇垦、數(shù)據(jù)庫或消息隊列炕置,再通過業(yè)務規(guī)則進行失敗重試,它要求各服務的接口是冪等的男韧。 - TCC(Try-Confirm-Cancel)補償模式 -- 最終一致性
由服務 A朴摊、服務B、服務C此虑、服務D 共同組成的一個微服務架構系統(tǒng)甚纲。服務A 需要依次調(diào)用服務B、服務C 和服務D 共同完成一個操作朦前。當服務A 調(diào)用服務D 失敗時介杆,若要保證整個系統(tǒng)數(shù)據(jù)的一致性,就要對服務B 和服務C 的invoke 操作進行回滾韭寸,執(zhí)行反向的revert 操作春哨。回滾成功后恩伺,整個微服務系統(tǒng)是數(shù)據(jù)一致的赴背。 - 緩存數(shù)據(jù)最終一致性
緩存(Redis 或者Memcached)通常被用在數(shù)據(jù)庫前面,作為數(shù)據(jù)讀取的緩沖,使得I/O 操作不至于直接落在數(shù)據(jù)庫上癞尚。
7. 集群與負載均衡的算法與實現(xiàn)
負載均衡算法可以參考Nginx的負載均衡的策略乱陡。
8. 說說分庫與分表設計
此題和第九題都請參見dataStorage\數(shù)據(jù)庫.md的第十題浇揩。
9. 分庫與分表帶來的分布式困境與應對之策