日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

分布式面试题(含解答)

發(fā)布時(shí)間:2025/4/16 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式面试题(含解答) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

分布式事務(wù)

指事務(wù)的每個(gè)操作步驟都位于不同的節(jié)點(diǎn)上,需要保證事務(wù)的 AICD 特性。

1. 產(chǎn)生原因

數(shù)據(jù)庫(kù)分庫(kù)分表;

SOA 架構(gòu),比如一個(gè)電商網(wǎng)站將訂單業(yè)務(wù)和庫(kù)存業(yè)務(wù)分離出來(lái)放到不同的節(jié)點(diǎn)上。

2. 應(yīng)用場(chǎng)景

下單:減少庫(kù)存同時(shí)更新訂單狀態(tài)。庫(kù)存和訂單不在不同一個(gè)數(shù)據(jù)庫(kù),因此涉及分布式事務(wù)。

支付:買家賬戶扣款同時(shí)賣家賬戶入賬。買家和賣家賬戶信息不在同一個(gè)數(shù)據(jù)庫(kù),因此涉及分布式事務(wù)。

3. 解決方案

3.1 兩階段提交協(xié)議

兩階段提交協(xié)議可以很好得解決分布式事務(wù)問(wèn)題,它可以使用 XA 來(lái)實(shí)現(xiàn),XA 它包含兩個(gè)部分:事務(wù)管理器和本地資源管理器。其中本地資源管理器往往由數(shù)據(jù)庫(kù)實(shí)現(xiàn),比如 Oracle、DB2 這些商業(yè)數(shù)據(jù)庫(kù)都實(shí)現(xiàn)了 XA 接口,而事務(wù)管理器作為全局的協(xié)調(diào)者,負(fù)責(zé)各個(gè)本地資源的提交和回滾。

3.2 消息中間件

消息中間件也可稱作消息系統(tǒng) (MQ),它本質(zhì)上是一個(gè)暫存轉(zhuǎn)發(fā)消息的一個(gè)中間件。在分布式應(yīng)用當(dāng)中,我們可以把一個(gè)業(yè)務(wù)操作轉(zhuǎn)換成一個(gè)消息,比如支付寶的余額轉(zhuǎn)如余額寶操作,支付寶系統(tǒng)執(zhí)行減少余額操作之后向消息系統(tǒng)發(fā)一個(gè)消息,余額寶系統(tǒng)訂閱這條消息然后進(jìn)行增加賬戶金額操作。

3.2.1 消息處理模型

點(diǎn)對(duì)點(diǎn)

.

發(fā)布/訂閱

.

3.2.2 消息的可靠性

消息的發(fā)送端的可靠性:發(fā)送端完成操作后一定能將消息成功發(fā)送到消息系統(tǒng)。

消息的接收端的可靠性:接收端僅且能夠從消息中間件成功消費(fèi)一次消息。

發(fā)送端的可靠性

在本地?cái)?shù)據(jù)建一張消息表,將消息數(shù)據(jù)與業(yè)務(wù)數(shù)據(jù)保存在同一數(shù)據(jù)庫(kù)實(shí)例里,這樣就可以利用本地?cái)?shù)據(jù)庫(kù)的事務(wù)機(jī)制。事務(wù)提交成功后,將消息表中的消息轉(zhuǎn)移到消息中間件,若轉(zhuǎn)移消息成功則刪除消息表中的數(shù)據(jù),否則繼續(xù)重傳。

接收端的可靠性

保證接收端處理消息的業(yè)務(wù)邏輯具有冪等性:只要具有冪等性,那么消費(fèi)多少次消息,最后處理的結(jié)果都是一樣的。

保證消息具有唯一編號(hào),并使用一張日志表來(lái)記錄已經(jīng)消費(fèi)的消息編號(hào)。

負(fù)載均衡的算法與實(shí)現(xiàn)

1. 算法

1.1 輪詢(Round Robin)

輪詢算法把每個(gè)請(qǐng)求輪流發(fā)送到每個(gè)服務(wù)器上。下圖中,一共有 6 個(gè)客戶端產(chǎn)生了 6 個(gè)請(qǐng)求,這 6 個(gè)請(qǐng)求按 (1, 2, 3, 4, 5, 6) 的順序發(fā)送。最后,(1, 3, 5) 的請(qǐng)求會(huì)被發(fā)送到服務(wù)器 1,(2, 4, 6) 的請(qǐng)求會(huì)被發(fā)送到服務(wù)器 2。

.

該算法比較適合每個(gè)服務(wù)器的性能差不多的場(chǎng)景,如果有性能存在差異的情況下,那么性能較差的服務(wù)器可能無(wú)法承擔(dān)多大的負(fù)載。下圖中,服務(wù)器 2 的性能比服務(wù)器 1 差,那么服務(wù)器 2 可能無(wú)法承擔(dān)多大的負(fù)載。

.

1.2 加權(quán)輪詢(Weighted Round Robbin)

加權(quán)輪詢是在輪詢的基礎(chǔ)上,根據(jù)服務(wù)器的性能差異,為服務(wù)器賦予一定的權(quán)值。例如下圖中,服務(wù)器 1 被賦予的權(quán)值為 5,服務(wù)器 2 被賦予的權(quán)值為 1,那么 (1, 2, 3, 4, 5) 請(qǐng)求會(huì)被發(fā)送到服務(wù)器 1,(6) 請(qǐng)求會(huì)被發(fā)送到服務(wù)器 2。

.

1.3 最少連接(least Connections)

由于每個(gè)請(qǐng)求的連接時(shí)間不一樣,使用輪詢或者加權(quán)輪詢算法的話,可能會(huì)讓一臺(tái)服務(wù)器當(dāng)前連接數(shù)多大,而另一臺(tái)服務(wù)器的連接多小,造成負(fù)載不均衡。例如下圖中,(1, 3, 5) 請(qǐng)求會(huì)被發(fā)送到服務(wù)器 1,但是 (1, 3) 很快就斷開(kāi)連接,此時(shí)只有 (5) 請(qǐng)求連接服務(wù)器 1;(2, 4, 6) 請(qǐng)求被發(fā)送到服務(wù)器 2,它們的連接都還沒(méi)有斷開(kāi),繼續(xù)運(yùn)行時(shí),服務(wù)器 2 會(huì)承擔(dān)多大的負(fù)載。

.

最少連接算法就是將請(qǐng)求發(fā)送給當(dāng)前最少連接數(shù)的服務(wù)器上。例如下圖中,服務(wù)器 1 當(dāng)前連接數(shù)最小,那么請(qǐng)求 6 就會(huì)被發(fā)送到服務(wù)器 1 上。

.

1.4 加權(quán)最小連接(Weighted Least Connection)

在最小連接的基礎(chǔ)上,根據(jù)服務(wù)器的性能為每臺(tái)服務(wù)器分配權(quán)重,然后根據(jù)權(quán)重計(jì)算出每臺(tái)服務(wù)器能處理的連接數(shù)。

.

1.5 隨機(jī)算法(Random)

把請(qǐng)求隨機(jī)發(fā)送到服務(wù)器上。和輪詢算法類似,該算法比較適合服務(wù)器性能差不多的場(chǎng)景。

.

2. 實(shí)現(xiàn)

2.1 DNS 解析

使用 DNS 作為負(fù)載均衡器,會(huì)根據(jù)負(fù)載情況返回不同服務(wù)器的 IP 地址。大型網(wǎng)站基本使用了這種方式最為第一級(jí)負(fù)載均衡手段,然后在內(nèi)部在第二級(jí)負(fù)載均衡。

.

2.2 修改 MAC 地址

使用 LVS(Linux Virtual Server)這種鏈路層負(fù)載均衡器,根據(jù)負(fù)載情況修改請(qǐng)求的 MAC 地址。

.

2.3 修改 IP 地址

在網(wǎng)絡(luò)層修改請(qǐng)求的目的 IP 地址。

.

2.4 HTTP 重定向

HTTP 重定向負(fù)載均衡服務(wù)器收到 HTTP 請(qǐng)求之后會(huì)返回服務(wù)器的地址,并將該地址寫(xiě)入 HTTP 重定向響應(yīng)中返回給瀏覽器,瀏覽器收到后再次發(fā)送請(qǐng)求。

.

2.5 反向代理

正向代理:發(fā)生在客戶端,是由用戶主動(dòng)發(fā)起的。比如FQ,客戶端通過(guò)主動(dòng)訪問(wèn)代理服務(wù)器,讓代理服務(wù)器獲得需要的外網(wǎng)數(shù)據(jù),然后轉(zhuǎn)發(fā)回客戶端。

反向代理:發(fā)生在服務(wù)器端,用戶不知道發(fā)生了代理。

.

分布式鎖

Java 提供了兩種內(nèi)置的鎖的實(shí)現(xiàn),一種是由 JVM 實(shí)現(xiàn)的 synchronized 和 JDK 提供的 Lock,當(dāng)你的應(yīng)用是單機(jī)或者說(shuō)單進(jìn)程應(yīng)用時(shí),可以使用 synchronized 或 Lock 來(lái)實(shí)現(xiàn)鎖。當(dāng)應(yīng)用涉及到多機(jī)、多進(jìn)程共同完成時(shí),那么這時(shí)候就需要一個(gè)全局鎖來(lái)實(shí)現(xiàn)多個(gè)進(jìn)程之間的同步。

1. 使用場(chǎng)景

例如一個(gè)應(yīng)用有手機(jī) APP 端和 Web 端,如果在兩個(gè)客戶端同時(shí)進(jìn)行一項(xiàng)操作時(shí),那么就會(huì)導(dǎo)致這項(xiàng)操作重復(fù)進(jìn)行。

2. 實(shí)現(xiàn)方式

2.1 數(shù)據(jù)庫(kù)分布式鎖

基于 MySQL 鎖表

該實(shí)現(xiàn)方式完全依靠數(shù)據(jù)庫(kù)唯一索引來(lái)實(shí)現(xiàn)。當(dāng)想要獲得鎖時(shí),就向數(shù)據(jù)庫(kù)中插入一條記錄,釋放鎖時(shí)就刪除這條記錄。如果記錄具有唯一索引,就不會(huì)同時(shí)插入同一條記錄。這種方式存在以下幾個(gè)問(wèn)題:

鎖沒(méi)有失效時(shí)間,解鎖失敗會(huì)導(dǎo)致死鎖,其他線程無(wú)法再獲得鎖。

只能是非阻塞鎖,插入失敗直接就報(bào)錯(cuò)了,無(wú)法重試。

不可重入,同一線程在沒(méi)有釋放鎖之前無(wú)法再獲得鎖。

采用樂(lè)觀鎖增加版本號(hào)

根據(jù)版本號(hào)來(lái)判斷更新之前有沒(méi)有其他線程更新過(guò),如果被更新過(guò),則獲取鎖失敗。

2.2 Redis 分布式鎖

基于 SETNX、EXPIRE

使用 SETNX(set if not exist)命令插入一個(gè)鍵值對(duì)時(shí),如果 Key 已經(jīng)存在,那么會(huì)返回 False,否則插入成功并返回 True。因此客戶端在嘗試獲得鎖時(shí),先使用 SETNX 向 Redis 中插入一個(gè)記錄,如果返回 True 表示獲得鎖,返回 False 表示已經(jīng)有客戶端占用鎖。

EXPIRE 可以為一個(gè)鍵值對(duì)設(shè)置一個(gè)過(guò)期時(shí)間,從而避免了死鎖的發(fā)生。

RedLock 算法

ReadLock 算法使用了多個(gè) Redis 實(shí)例來(lái)實(shí)現(xiàn)分布式鎖,這是為了保證在發(fā)生單點(diǎn)故障時(shí)還可用。

嘗試從 N 個(gè)相互獨(dú)立 Redis 實(shí)例獲取鎖,如果一個(gè)實(shí)例不可用,應(yīng)該盡快嘗試下一個(gè)。

計(jì)算獲取鎖消耗的時(shí)間,只有當(dāng)這個(gè)時(shí)間小于鎖的過(guò)期時(shí)間,并且從大多數(shù)(N/2+1)實(shí)例上獲取了鎖,那么就認(rèn)為鎖獲取成功了。

如果鎖獲取失敗,會(huì)到每個(gè)實(shí)例上釋放鎖。

2.3 Zookeeper 分布式鎖

Zookeeper 是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件,例如配置管理、分布式協(xié)同以及命名的中心化等,這些都是分布式系統(tǒng)中非常底層而且是必不可少的基本功能,但是如果自己實(shí)現(xiàn)這些功能而且要達(dá)到高吞吐、低延遲同時(shí)還要保持一致性和可用性,實(shí)際上非常困難。

抽象模型

Zookeeper 提供了一種樹(shù)形結(jié)構(gòu)級(jí)的命名空間,/app1/p_1 節(jié)點(diǎn)表示它的父節(jié)點(diǎn)為 /app1。

.

節(jié)點(diǎn)類型

永久節(jié)點(diǎn):不會(huì)因?yàn)闀?huì)話結(jié)束或者超時(shí)而消失;

臨時(shí)節(jié)點(diǎn):如果會(huì)話結(jié)束或者超時(shí)就會(huì)消失;

有序節(jié)點(diǎn):會(huì)在節(jié)點(diǎn)名的后面加一個(gè)數(shù)字后綴,并且是有序的,例如生成的有序節(jié)點(diǎn)為 /lock/node-0000000000,它的下一個(gè)有序節(jié)點(diǎn)則為 /lock/node-0000000001,依次類推。

監(jiān)聽(tīng)器

為一個(gè)節(jié)點(diǎn)注冊(cè)監(jiān)聽(tīng)器,在節(jié)點(diǎn)狀態(tài)發(fā)生改變時(shí),會(huì)給客戶端發(fā)送消息。

分布式鎖實(shí)現(xiàn)

創(chuàng)建一個(gè)鎖目錄 /lock。

在 /lock 下創(chuàng)建臨時(shí)的且有序的子節(jié)點(diǎn),第一個(gè)客戶端對(duì)應(yīng)的子節(jié)點(diǎn)為 /lock/lock-0000000000,第二個(gè)為 /lock/lock-0000000001,以此類推。

客戶端獲取 /lock 下的子節(jié)點(diǎn)列表,判斷自己創(chuàng)建的子節(jié)點(diǎn)是否為當(dāng)前子節(jié)點(diǎn)列表中序號(hào)最小的子節(jié)點(diǎn),如果是則認(rèn)為獲得鎖,否則監(jiān)聽(tīng)自己的前一個(gè)子節(jié)點(diǎn),獲得子節(jié)點(diǎn)的變更通知后重復(fù)此步驟直至獲得鎖;

執(zhí)行業(yè)務(wù)代碼,完成后,刪除對(duì)應(yīng)的子節(jié)點(diǎn)。

會(huì)話超時(shí)

如果一個(gè)已經(jīng)獲得鎖的會(huì)話超時(shí)了,因?yàn)閯?chuàng)建的是臨時(shí)節(jié)點(diǎn),因此該會(huì)話對(duì)應(yīng)的臨時(shí)節(jié)點(diǎn)會(huì)被刪除,其它會(huì)話就可以獲得鎖了??梢钥吹?#xff0c;Zookeeper 分布式鎖不會(huì)出現(xiàn)數(shù)據(jù)庫(kù)分布式鎖的死鎖問(wèn)題。

羊群效應(yīng)

在步驟二,一個(gè)節(jié)點(diǎn)未獲得鎖,需要監(jiān)聽(tīng)監(jiān)聽(tīng)自己的前一個(gè)子節(jié)點(diǎn),這是因?yàn)槿绻O(jiān)聽(tīng)所有的子節(jié)點(diǎn),那么任意一個(gè)子節(jié)點(diǎn)狀態(tài)改變,其它所有子節(jié)點(diǎn)都會(huì)收到通知,而我們只希望它的下一個(gè)子節(jié)點(diǎn)收到通知。

分布式 Session

如果不做任何處理的話,用戶將出現(xiàn)頻繁登錄的現(xiàn)象,比如集群中存在 A、B 兩臺(tái)服務(wù)器,用戶在第一次訪問(wèn)網(wǎng)站時(shí),Nginx 通過(guò)其負(fù)載均衡機(jī)制將用戶請(qǐng)求轉(zhuǎn)發(fā)到 A 服務(wù)器,這時(shí) A 服務(wù)器就會(huì)給用戶創(chuàng)建一個(gè) Session。當(dāng)用戶第二次發(fā)送請(qǐng)求時(shí),Nginx 將其負(fù)載均衡到 B 服務(wù)器,而這時(shí)候 B 服務(wù)器并不存在 Session,所以就會(huì)將用戶踢到登錄頁(yè)面。這將大大降低用戶體驗(yàn)度,導(dǎo)致用戶的流失,這種情況是項(xiàng)目絕不應(yīng)該出現(xiàn)的。

1. 粘性 Session

原理

粘性 Session 是指將用戶鎖定到某一個(gè)服務(wù)器上,比如上面說(shuō)的例子,用戶第一次請(qǐng)求時(shí),負(fù)載均衡器將用戶的請(qǐng)求轉(zhuǎn)發(fā)到了 A 服務(wù)器上,如果負(fù)載均衡器設(shè)置了粘性 Session 的話,那么用戶以后的每次請(qǐng)求都會(huì)轉(zhuǎn)發(fā)到 A 服務(wù)器上,相當(dāng)于把用戶和 A 服務(wù)器粘到了一塊,這就是粘性 Session 機(jī)制。

優(yōu)點(diǎn)

簡(jiǎn)單,不需要對(duì) Session 做任何處理。

缺點(diǎn)

缺乏容錯(cuò)性,如果當(dāng)前訪問(wèn)的服務(wù)器發(fā)生故障,用戶被轉(zhuǎn)移到第二個(gè)服務(wù)器上時(shí),他的 Session 信息都將失效。

適用場(chǎng)景

發(fā)生故障對(duì)客戶產(chǎn)生的影響較小;

服務(wù)器發(fā)生故障是低概率事件。

2. 服務(wù)器 Session 復(fù)制

原理

任何一個(gè)服務(wù)器上的 Session 發(fā)生改變,該節(jié)點(diǎn)會(huì)把這個(gè) Session 的所有內(nèi)容序列化,然后廣播給所有其它節(jié)點(diǎn),不管其他服務(wù)器需不需要 Session,以此來(lái)保證 Session 同步。

優(yōu)點(diǎn)

可容錯(cuò),各個(gè)服務(wù)器間 Session 能夠?qū)崟r(shí)響應(yīng)。

缺點(diǎn)

會(huì)對(duì)網(wǎng)絡(luò)負(fù)荷造成一定壓力,如果 Session 量大的話可能會(huì)造成網(wǎng)絡(luò)堵塞,拖慢服務(wù)器性能。

實(shí)現(xiàn)方式

設(shè)置 Tomcat 的 server.xml 開(kāi)啟 tomcat 集群功能。

在應(yīng)用里增加信息:通知應(yīng)用當(dāng)前處于集群環(huán)境中,支持分布式,即在 web.xml 中添加 選項(xiàng)。

3. Session 共享機(jī)制

使用分布式緩存方案比如 Memcached、Redis,但是要求 Memcached 或 Redis 必須是集群。

使用 Session 共享也分兩種機(jī)制,兩種情況如下:

3.1 粘性 Session 共享機(jī)制

和粘性 Session 一樣,一個(gè)用戶的 Session 會(huì)綁定到一個(gè) Tomcat 上。Memcached 只是起到備份作用。

.

3.2 非粘性 Session 共享機(jī)制

原理

Tomcat 本身不存儲(chǔ) Session,而是存入 Memcached 中。Memcached 集群構(gòu)建主從復(fù)制架構(gòu)。

.

優(yōu)點(diǎn)

可容錯(cuò),Session 實(shí)時(shí)響應(yīng)。

實(shí)現(xiàn)方式

用開(kāi)源的 msm 插件解決 Tomcat 之間的 Session 共享:Memcached_Session_Manager(MSM)

4. Session 持久化到數(shù)據(jù)庫(kù)

原理

拿出一個(gè)數(shù)據(jù)庫(kù),專門用來(lái)存儲(chǔ) Session 信息。保證 Session 的持久化。

優(yōu)點(diǎn)

服務(wù)器出現(xiàn)問(wèn)題,Session 不會(huì)丟失

缺點(diǎn)

如果網(wǎng)站的訪問(wèn)量很大,把 Session 存儲(chǔ)到數(shù)據(jù)庫(kù)中,會(huì)對(duì)數(shù)據(jù)庫(kù)造成很大壓力,還需要增加額外的開(kāi)銷維護(hù)數(shù)據(jù)庫(kù)。

5. Terracotta 實(shí)現(xiàn) Session 復(fù)制

原理

Terracotta 的基本原理是對(duì)于集群間共享的數(shù)據(jù),當(dāng)在一個(gè)節(jié)點(diǎn)發(fā)生變化的時(shí)候,Terracotta 只把變化的部分發(fā)送給 Terracotta 服務(wù)器,然后由服務(wù)器把它轉(zhuǎn)發(fā)給真正需要這個(gè)數(shù)據(jù)的節(jié)點(diǎn)。它是服務(wù)器 Session 復(fù)制的優(yōu)化。

.

優(yōu)點(diǎn)

這樣對(duì)網(wǎng)絡(luò)的壓力就非常小,各個(gè)節(jié)點(diǎn)也不必浪費(fèi) CPU 時(shí)間和內(nèi)存進(jìn)行大量的序列化操作。把這種集群間數(shù)據(jù)共享的機(jī)制應(yīng)用在 Session 同步上,既避免了對(duì)數(shù)據(jù)庫(kù)的依賴,又能達(dá)到負(fù)載均衡和災(zāi)難恢復(fù)的效果。

分庫(kù)與分表帶來(lái)的分布式困境與應(yīng)對(duì)之策

.

1. 事務(wù)問(wèn)題

使用分布式事務(wù)。

2. 查詢問(wèn)題

使用匯總表。

3. ID 唯一性

使用全局唯一 ID:GUID;

為每個(gè)分片指定一個(gè) ID 范圍。

轉(zhuǎn)載于:https://www.cnblogs.com/workstation-nigoudongma/p/9546801.html

總結(jié)

以上是生活随笔為你收集整理的分布式面试题(含解答)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。