大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的-創(chuàng)新互聯(lián)

這篇文章主要介紹“大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的”,在日常操作中,相信很多人在大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)公司長期為成百上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為閬中企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站建設(shè),閬中網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

接下來,我們將看看高階的權(quán)衡和取舍:

  • 性能與可擴展性

  • 延遲與吞吐量

  • 可用性與一致性

記住每個方面都面臨取舍和權(quán)衡。

然后,我們將深入更具體的主題,如 DNS、CDN 和負(fù)載均衡器。

1. 性能與可擴展性

如果服務(wù)性能的增長與資源的增加是成比例的,服務(wù)就是可擴展的。通常,提高性能意味著服務(wù)于更多的工作單元,另一方面,當(dāng)數(shù)據(jù)集增長時,同樣也可以處理更大的工作單位。 1

另一個角度來看待性能與可擴展性:

  • 如果你的系統(tǒng)有性能問題,對于單個用戶來說是緩慢的。

  • 如果你的系統(tǒng)有可擴展性問題,單個用戶較快但在高負(fù)載下會變慢。

2. 延遲與吞吐量

延遲是執(zhí)行操作或運算結(jié)果所花費的時間。

吞吐量是單位時間內(nèi)(執(zhí)行)此類操作或運算的數(shù)量。

通常,你應(yīng)該以可接受級延遲下大化吞吐量為目標(biāo)。

3. 可用性與一致性

CAP 理論

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

在一個分布式計算系統(tǒng)中,只能同時滿足下列的兩點:

  • 一致性 ─ 每次訪問都能獲得最新數(shù)據(jù)但可能會收到錯誤響應(yīng)

  • 可用性 ─ 每次訪問都能收到非錯響應(yīng),但不保證獲取到最新數(shù)據(jù)

  • 分區(qū)容錯性 ─ 在任意分區(qū)網(wǎng)絡(luò)故障的情況下系統(tǒng)仍能繼續(xù)運行

網(wǎng)絡(luò)并不可靠,所以你應(yīng)要支持分區(qū)容錯性,并需要在軟件可用性和一致性間做出取舍。

CP ─ 一致性和分區(qū)容錯性

等待分區(qū)節(jié)點的響應(yīng)可能會導(dǎo)致延時錯誤。如果你的業(yè)務(wù)需求需要原子讀寫,CP 是一個不錯的選擇。

AP ─ 可用性與分區(qū)容錯性

響應(yīng)節(jié)點上可用數(shù)據(jù)的最近版本可能并不是最新的。當(dāng)分區(qū)解析完后,寫入(操作)可能需要一些時間來傳播。

如果業(yè)務(wù)需求允許最終一致性,或當(dāng)有外部故障時要求系統(tǒng)繼續(xù)運行,AP 是一個不錯的選擇。

4. 一致性模式

有同一份數(shù)據(jù)的多份副本,我們面臨著怎樣同步它們的選擇,以便讓客戶端有一致的顯示數(shù)據(jù)?;叵?nbsp;CAP 理論中的一致性定義 ─ 每次訪問都能獲得最新數(shù)據(jù)但可能會收到錯誤響應(yīng)

弱一致性

在寫入之后,訪問可能看到,也可能看不到(寫入數(shù)據(jù))。盡力優(yōu)化之讓其能訪問最新數(shù)據(jù)。

這種方式可以 memcached 等系統(tǒng)中看到。弱一致性在 VoIP,視頻聊天和實時多人游戲等真實用例中表現(xiàn)不錯。打個比方,如果你在通話中丟失信號幾秒鐘時間,當(dāng)重新連接時你是聽不到這幾秒鐘所說的話的。

最終一致性

在寫入后,訪問最終能看到寫入數(shù)據(jù)(通常在數(shù)毫秒內(nèi))。數(shù)據(jù)被異步復(fù)制。

DNS 和 email 等系統(tǒng)使用的是此種方式。最終一致性在高可用性系統(tǒng)中效果不錯。

強一致性

在寫入后,訪問立即可見。數(shù)據(jù)被同步復(fù)制。

文件系統(tǒng)和關(guān)系型數(shù)據(jù)庫(RDBMS)中使用的是此種方式。強一致性在需要記錄的系統(tǒng)中運作良好。

5. 可用性模式

有兩種支持高可用性的模式: 故障切換(fail-over)和復(fù)制(replication)。

故障切換

工作到備用切換(Active-passive)

關(guān)于工作到備用的故障切換流程是,工作服務(wù)器發(fā)送周期信號給待機中的備用服務(wù)器。如果周期信號中斷,備用服務(wù)器切換成工作服務(wù)器的 IP 地址并恢復(fù)服務(wù)。

宕機時間取決于備用服務(wù)器處于“熱”待機狀態(tài)還是需要從“冷”待機狀態(tài)進行啟動。只有工作服務(wù)器處理流量。

工作到備用的故障切換也被稱為主從切換。

雙工作切換(Active-active)

在雙工作切換中,雙方都在管控流量,在它們之間分散負(fù)載。

如果是外網(wǎng)服務(wù)器,DNS 將需要對兩方都了解。如果是內(nèi)網(wǎng)服務(wù)器,應(yīng)用程序邏輯將需要對兩方都了解。

雙工作切換也可以稱為主主切換。

缺陷:故障切換

  • 故障切換需要添加額外硬件并增加復(fù)雜性。

  • 如果新寫入數(shù)據(jù)在能被復(fù)制到備用系統(tǒng)之前,工作系統(tǒng)出現(xiàn)了故障,則有可能會丟失數(shù)據(jù)。

復(fù)制

主 ─ 從復(fù)制和主 ─ 主復(fù)制

這個主題進一步探討了數(shù)據(jù)庫部分:

  • 主 ─ 從復(fù)制

  • 主 ─ 主復(fù)制

6. 域名系統(tǒng)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

域名系統(tǒng)是把 www.example.com 等域名轉(zhuǎn)換成 IP 地址。

域名系統(tǒng)是分層次的,一些 DNS 服務(wù)器位于頂層。當(dāng)查詢(域名) IP 時,路由或 ISP 提供連接 DNS 服務(wù)器的信息。較底層的 DNS 服務(wù)器緩存映射,它可能會因為 DNS 傳播延時而失效。DNS 結(jié)果可以緩存在瀏覽器或操作系統(tǒng)中一段時間,時間長短取決于存活時間 TTL。

  • NS 記錄(域名服務(wù)) ─ 指定解析域名或子域名的 DNS 服務(wù)器。

  • MX 記錄(郵件交換) ─ 指定接收信息的郵件服務(wù)器。

  • A 記錄(地址) ─ 指定域名對應(yīng)的 IP 地址記錄。

  • CNAME(規(guī)范) ─ 一個域名映射到另一個域名或 CNAME 記錄( example.com 指向 www.example.com )或映射到一個 A 記錄。

CloudFlare 和 Route 53 等平臺提供管理 DNS 的功能。某些 DNS 服務(wù)通過集中方式來路由流量:

  • 加權(quán)輪詢調(diào)度

    • 防止流量進入維護中的服務(wù)器

    • 在不同大小集群間負(fù)載均衡

    • A/B 測試

  • 基于延遲路由

  • 基于地理位置路由

缺陷:DNS

  • 雖說緩存可以減輕 DNS 延遲,但連接 DNS 服務(wù)器還是帶來了輕微的延遲。

  • 雖然它們通常由政府,網(wǎng)絡(luò)服務(wù)提供商和大公司管理,但 DNS 服務(wù)管理仍可能是復(fù)雜的。

  • DNS 服務(wù)最近遭受 DDoS 攻擊,阻止不知道 Twtter IP 地址的用戶訪問 Twiiter。

7. 內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)是一個全球性的代理服務(wù)器分布式網(wǎng)絡(luò),它從靠近用戶的位置提供內(nèi)容。通常,HTML/CSS/JS,圖片和視頻等靜態(tài)內(nèi)容由 CDN 提供,雖然亞馬遜 CloudFront 等也支持動態(tài)內(nèi)容。CDN 的 DNS 解析會告知客戶端連接哪臺服務(wù)器。

將內(nèi)容存儲在 CDN 上可以從兩個方面來提供性能:

  • 從靠近用戶的數(shù)據(jù)中心提供資源

  • 通過 CDN 你的服務(wù)器不必真的處理請求

CDN 推送(push)

當(dāng)你服務(wù)器上內(nèi)容發(fā)生變動時,推送 CDN 接受新內(nèi)容。直接推送給 CDN 并重寫 URL 地址以指向你的內(nèi)容的 CDN 地址。你可以配置內(nèi)容到期時間及何時更新。內(nèi)容只有在更改或新增是才推送,流量最小化,但儲存大化。

CDN 拉取(pull)

CDN 拉取是當(dāng)?shù)谝粋€用戶請求該資源時,從服務(wù)器上拉取資源。你將內(nèi)容留在自己的服務(wù)器上并重寫 URL 指向 CDN 地址。直到內(nèi)容被緩存在 CDN 上為止,這樣請求只會更慢,

存活時間(TTL)決定緩存多久時間。CDN 拉取方式最小化 CDN 上的儲存空間,但如果過期文件并在實際更改之前被拉取,則會導(dǎo)致冗余的流量。

高流量站點使用 CDN 拉取效果不錯,因為只有最近請求的內(nèi)容保存在 CDN 中,流量才能更平衡地分散。

缺陷:CDN

  • CDN 成本可能因流量而異,可能在權(quán)衡之后你將不會使用 CDN。

  • 如果在 TTL 過期之前更新內(nèi)容,CDN 緩存內(nèi)容可能會過時。

  • CDN 需要更改靜態(tài)內(nèi)容的 URL 地址以指向 CDN。

8. 負(fù)載均衡器

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

負(fù)載均衡器將傳入的請求分發(fā)到應(yīng)用服務(wù)器和數(shù)據(jù)庫等計算資源。無論哪種情況,負(fù)載均衡器將從計算資源來的響應(yīng)返回給恰當(dāng)?shù)目蛻舳?。?fù)載均衡器的效用在于:

  • 防止請求進入不好的服務(wù)器

  • 防止資源過載

  • 幫助消除單一的故障點

負(fù)載均衡器可以通過硬件(昂貴)或 HAProxy 等軟件來實現(xiàn)。 增加的好處包括:

  • SSL 終結(jié) ─ 解密傳入的請求并加密服務(wù)器響應(yīng),這樣的話后端服務(wù)器就不必再執(zhí)行這些潛在高消耗運算了。

    • 不需要再每臺服務(wù)器上安裝 X.509 證書。

  • Session 留存 ─ 如果 Web 應(yīng)用程序不追蹤會話,發(fā)出 cookie 并將特定客戶端的請求路由到同一實例。

通常會設(shè)置采用工作 ─ 備用 或 雙工作 模式的多個負(fù)載均衡器,以免發(fā)生故障。

負(fù)載均衡器能基于多種方式來路由流量:

  • 隨機

  • 最少負(fù)載

  • Session/cookie

  • 輪詢調(diào)度或加權(quán)輪詢調(diào)度算法

  • 四層負(fù)載均衡

  • 七層負(fù)載均衡

四層負(fù)載均衡

四層負(fù)載均衡根據(jù)監(jiān)看傳輸層的信息來決定如何分發(fā)請求。通常,這會涉及來源,目標(biāo) IP 地址和請求頭中的端口,但不包括數(shù)據(jù)包(報文)內(nèi)容。四層負(fù)載均衡執(zhí)行網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)來向上游服務(wù)器轉(zhuǎn)發(fā)網(wǎng)絡(luò)數(shù)據(jù)包。

七層負(fù)載均衡器

七層負(fù)載均衡器根據(jù)監(jiān)控應(yīng)用層來決定怎樣分發(fā)請求。這會涉及請求頭的內(nèi)容,消息和 cookie。七層負(fù)載均衡器終結(jié)網(wǎng)絡(luò)流量,讀取消息,做出負(fù)載均衡判定,然后傳送給特定服務(wù)器。比如,一個七層負(fù)載均衡器能直接將視頻流量連接到托管視頻的服務(wù)器,同時將更敏感的用戶賬單流量引導(dǎo)到安全性更強的服務(wù)器。

以損失靈活性為代價,四層負(fù)載均衡比七層負(fù)載均衡花費更少時間和計算資源,雖然這對現(xiàn)代商用硬件的性能影響甚微。

水平擴展

負(fù)載均衡器還能幫助水平擴展,提高性能和可用性。使用商業(yè)硬件的性價比更高,并且比在單臺硬件上垂直擴展更貴的硬件具有更高的可用性。相比招聘特定企業(yè)系統(tǒng)人才,招聘商業(yè)硬件方面的人才更加容易。

缺陷:水平擴展
  • 水平擴展引入了復(fù)雜度并涉及服務(wù)器復(fù)制

    • 服務(wù)器應(yīng)該是無狀態(tài)的:它們也不該包含像 session 或資料圖片等與用戶關(guān)聯(lián)的數(shù)據(jù)。

    • session 可以集中存儲在數(shù)據(jù)庫或持久化緩存(Redis、Memcached)的數(shù)據(jù)存儲區(qū)中。

  • 緩存和數(shù)據(jù)庫等下游服務(wù)器需要隨著上游服務(wù)器進行擴展,以處理更多的并發(fā)連接。

缺陷:負(fù)載均衡器

  • 如果沒有足夠的資源配置或配置錯誤,負(fù)載均衡器會變成一個性能瓶頸。

  • 引入負(fù)載均衡器以幫助消除單點故障但導(dǎo)致了額外的復(fù)雜性。

  • 單個負(fù)載均衡器會導(dǎo)致單點故障,但配置多個負(fù)載均衡器會進一步增加復(fù)雜性。

9. 反向代理(web 服務(wù)器)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

反向代理是一種可以集中地調(diào)用內(nèi)部服務(wù),并提供統(tǒng)一接口給公共客戶的 web 服務(wù)器。來自客戶端的請求先被反向代理服務(wù)器轉(zhuǎn)發(fā)到可響應(yīng)請求的服務(wù)器,然后代理再把服務(wù)器的響應(yīng)結(jié)果返回給客戶端。

帶來的好處包括:

  • 增加安全性 - 隱藏后端服務(wù)器的信息,屏蔽黑名單中的 IP,限制每個客戶端的連接數(shù)。

  • 提高可擴展性和靈活性 - 客戶端只能看到反向代理服務(wù)器的 IP,這使你可以增減服務(wù)器或者修改它們的配置。

  • 本地終結(jié) SSL 會話 - 解密傳入請求,加密服務(wù)器響應(yīng),這樣后端服務(wù)器就不必完成這些潛在的高成本的操作。

    • 免除了在每個服務(wù)器上安裝 X.509 證書的需要

  • 壓縮 - 壓縮服務(wù)器響應(yīng)

  • 緩存 - 直接返回命中的緩存結(jié)果

  • 靜態(tài)內(nèi)容 - 直接提供靜態(tài)內(nèi)容

    • HTML/CSS/JS

    • 圖片

    • 視頻

    • 等等

負(fù)載均衡器與反向代理

  • 當(dāng)你有多個服務(wù)器時,部署負(fù)載均衡器非常有用。通常,負(fù)載均衡器將流量路由給一組功能相同的服務(wù)器上。

  • 即使只有一臺 web 服務(wù)器或者應(yīng)用服務(wù)器時,反向代理也有用,可以參考上一節(jié)介紹的好處。

  • NGINX 和 HAProxy 等解決方案可以同時支持第七層反向代理和負(fù)載均衡。

不利之處:反向代理

  • 引入反向代理會增加系統(tǒng)的復(fù)雜度。

  • 單獨一個反向代理服務(wù)器仍可能發(fā)生單點故障,配置多臺反向代理服務(wù)器(如故障轉(zhuǎn)移)會進一步增加復(fù)雜度。

10. 應(yīng)用層

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

將 Web 服務(wù)層與應(yīng)用層(也被稱作平臺層)分離,可以獨立縮放和配置這兩層。添加新的 API 只需要添加應(yīng)用服務(wù)器,而不必添加額外的 web 服務(wù)器。

單一職責(zé)原則提倡小型的,自治的服務(wù)共同合作。小團隊通過提供小型的服務(wù),可以更激進地計劃增長。

應(yīng)用層中的工作進程也有可以實現(xiàn)異步化。

微服務(wù)

與此討論相關(guān)的話題是 微服務(wù),可以被描述為一系列可以獨立部署的小型的,模塊化服務(wù)。每個服務(wù)運行在一個獨立的線程中,通過明確定義的輕量級機制通訊,共同實現(xiàn)業(yè)務(wù)目標(biāo)。1

例如,Pinterest 可能有這些微服務(wù): 用戶資料、關(guān)注者、Feed 流、搜索、照片上傳等。

服務(wù)發(fā)現(xiàn)

像 Consul,Etcd 和 Zookeeper 這樣的系統(tǒng)可以通過追蹤注冊名、地址、端口等信息來幫助服務(wù)互相發(fā)現(xiàn)對方。Health checks 可以幫助確認(rèn)服務(wù)的完整性和是否經(jīng)常使用一個 HTTP 路徑。Consul 和 Etcd 都有一個內(nèi)建的 key-value 存儲 用來存儲配置信息和其他的共享信息。

不利之處:應(yīng)用層

  • 添加由多個松耦合服務(wù)組成的應(yīng)用層,從架構(gòu)、運營、流程等層面來講將非常不同(相對于單體系統(tǒng))。

  • 微服務(wù)會增加部署和運營的復(fù)雜度。

11. 數(shù)據(jù)庫

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS)

像 SQL 這樣的關(guān)系型數(shù)據(jù)庫是一系列以表的形式組織的數(shù)據(jù)項集合。

校對注:這里作者 SQL 可能指的是 MySQL

ACID 用來描述關(guān)系型數(shù)據(jù)庫事務(wù)的特性。

  • 原子性 - 每個事務(wù)內(nèi)部所有操作要么全部完成,要么全部不完成。

  • 一致性 - 任何事務(wù)都使數(shù)據(jù)庫從一個有效的狀態(tài)轉(zhuǎn)換到另一個有效狀態(tài)。

  • 隔離性 - 并發(fā)執(zhí)行事務(wù)的結(jié)果與順序執(zhí)行事務(wù)的結(jié)果相同。

  • 持久性 - 事務(wù)提交后,對系統(tǒng)的影響是永久的。

關(guān)系型數(shù)據(jù)庫擴展包括許多技術(shù):主從復(fù)制、主主復(fù)制、聯(lián)合、分片、非規(guī)范化和 SQL 調(diào)優(yōu)。

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

主從復(fù)制

主庫同時負(fù)責(zé)讀取和寫入操作,并復(fù)制寫入到一個或多個從庫中,從庫只負(fù)責(zé)讀操作。樹狀形式的從庫再將寫入復(fù)制到更多的從庫中去。如果主庫離線,系統(tǒng)可以以只讀模式運行,直到某個從庫被提升為主庫或有新的主庫出現(xiàn)。

不利之處:主從復(fù)制

  • 將從庫提升為主庫需要額外的邏輯。

  • 參考不利之處:復(fù)制中,主從復(fù)制和主主復(fù)制共同的問題。

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

主主復(fù)制

兩個主庫都負(fù)責(zé)讀操作和寫操作,寫入操作時互相協(xié)調(diào)。如果其中一個主庫掛機,系統(tǒng)可以繼續(xù)讀取和寫入。

不利之處: 主主復(fù)制

  • 你需要添加負(fù)載均衡器或者在應(yīng)用邏輯中做改動,來確定寫入哪一個數(shù)據(jù)庫。

  • 多數(shù)主-主系統(tǒng)要么不能保證一致性(違反 ACID),要么因為同步產(chǎn)生了寫入延遲。

  • 隨著更多寫入節(jié)點的加入和延遲的提高,如何解決沖突顯得越發(fā)重要。

  • 參考不利之處:復(fù)制中,主從復(fù)制和主主復(fù)制共同的問題。

不利之處:復(fù)制

  • 如果主庫在將新寫入的數(shù)據(jù)復(fù)制到其他節(jié)點前掛掉,則有數(shù)據(jù)丟失的可能。

  • 寫入會被重放到負(fù)責(zé)讀取操作的副本。副本可能因為過多寫操作阻塞住,導(dǎo)致讀取功能異常。

  • 讀取從庫越多,需要復(fù)制的寫入數(shù)據(jù)就越多,導(dǎo)致更嚴(yán)重的復(fù)制延遲。

  • 在某些數(shù)據(jù)庫系統(tǒng)中,寫入主庫的操作可以用多個線程并行寫入,但讀取副本只支持單線程順序地寫入。

  • 復(fù)制意味著更多的硬件和額外的復(fù)雜度。

聯(lián)合

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

聯(lián)合(或按功能劃分)將數(shù)據(jù)庫按對應(yīng)功能分割。例如,你可以有三個數(shù)據(jù)庫:論壇、用戶和產(chǎn)品,而不僅是一個單體數(shù)據(jù)庫,從而減少每個數(shù)據(jù)庫的讀取和寫入流量,減少復(fù)制延遲。較小的數(shù)據(jù)庫意味著更多適合放入內(nèi)存的數(shù)據(jù),進而意味著更高的緩存命中幾率。沒有只能串行寫入的中心化主庫,你可以并行寫入,提高負(fù)載能力。

不利之處:聯(lián)合

  • 如果你的數(shù)據(jù)庫模式需要大量的功能和數(shù)據(jù)表,聯(lián)合的效率并不好。

  • 你需要更新應(yīng)用程序的邏輯來確定要讀取和寫入哪個數(shù)據(jù)庫。

  • 用 server link 從兩個庫聯(lián)結(jié)數(shù)據(jù)更復(fù)雜。

  • 聯(lián)合需要更多的硬件和額外的復(fù)雜度。

分片

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

分片將數(shù)據(jù)分配在不同的數(shù)據(jù)庫上,使得每個數(shù)據(jù)庫僅管理整個數(shù)據(jù)集的一個子集。以用戶數(shù)據(jù)庫為例,隨著用戶數(shù)量的增加,越來越多的分片會被添加到集群中。

類似聯(lián)合的優(yōu)點,分片可以減少讀取和寫入流量,減少復(fù)制并提高緩存命中率。也減少了索引,通常意味著查詢更快,性能更好。如果一個分片出問題,其他的仍能運行,你可以使用某種形式的冗余來防止數(shù)據(jù)丟失。類似聯(lián)合,沒有只能串行寫入的中心化主庫,你可以并行寫入,提高負(fù)載能力。

常見的做法是用戶姓氏的首字母或者用戶的地理位置來分隔用戶表。

不利之處:分片

  • 你需要修改應(yīng)用程序的邏輯來實現(xiàn)分片,這會帶來復(fù)雜的 SQL 查詢。

  • 分片不合理可能導(dǎo)致數(shù)據(jù)負(fù)載不均衡。例如,被頻繁訪問的用戶數(shù)據(jù)會導(dǎo)致其所在分片的負(fù)載相對其他分片高。

    • 再平衡會引入額外的復(fù)雜度?;谝恢滦怨5姆制惴梢詼p少這種情況。

  • 聯(lián)結(jié)多個分片的數(shù)據(jù)操作更復(fù)雜。

  • 分片需要更多的硬件和額外的復(fù)雜度。

非規(guī)范化

非規(guī)范化試圖以寫入性能為代價來換取讀取性能。在多個表中冗余數(shù)據(jù)副本,以避免高成本的聯(lián)結(jié)操作。一些關(guān)系型數(shù)據(jù)庫,比如 PostgreSQL 和 Oracle 支持物化視圖,可以處理冗余信息存儲和保證冗余副本一致。

當(dāng)數(shù)據(jù)使用諸如聯(lián)合和分片等技術(shù)被分割,進一步提高了處理跨數(shù)據(jù)中心的聯(lián)結(jié)操作復(fù)雜度。非規(guī)范化可以規(guī)避這種復(fù)雜的聯(lián)結(jié)操作。

在多數(shù)系統(tǒng)中,讀取操作的頻率遠(yuǎn)高于寫入操作,比例可達到 100:1,甚至 1000:1。需要復(fù)雜的數(shù)據(jù)庫聯(lián)結(jié)的讀取操作成本非常高,在磁盤操作上消耗了大量時間。

不利之處:非規(guī)范化

  • 數(shù)據(jù)會冗余。

  • 約束可以幫助冗余的信息副本保持同步,但這樣會增加數(shù)據(jù)庫設(shè)計的復(fù)雜度。

  • 非規(guī)范化的數(shù)據(jù)庫在高寫入負(fù)載下性能可能比規(guī)范化的數(shù)據(jù)庫差。

SQL 調(diào)優(yōu)

SQL 調(diào)優(yōu)是一個范圍很廣的話題,有很多相關(guān)的書可以作為參考。

利用基準(zhǔn)測試和性能分析來模擬和發(fā)現(xiàn)系統(tǒng)瓶頸很重要。

  • 基準(zhǔn)測試 - 用 ab 等工具模擬高負(fù)載情況。

  • 性能分析 - 通過啟用如慢查詢?nèi)罩镜裙ぞ邅磔o助追蹤性能問題。

基準(zhǔn)測試和性能分析可能會指引你到以下優(yōu)化方案。

改進模式

  • 為了實現(xiàn)快速訪問,MySQL 在磁盤上用連續(xù)的塊存儲數(shù)據(jù)。

  • 使用 CHAR 類型存儲固定長度的字段,不要用 VARCHAR。

    • CHAR 在快速、隨機訪問時效率很高。如果使用 VARCHAR,如果你想讀取下一個字符串,不得不先讀取到當(dāng)前字符串的末尾。

  • 使用 TEXT 類型存儲大塊的文本,例如博客正文。TEXT 還允許布爾搜索。使用 TEXT 字段需要在磁盤上存儲一個用于定位文本塊的指針。

  • 使用 INT 類型存儲高達 2^32 或 40 億的較大數(shù)字。

  • 使用 DECIMAL 類型存儲貨幣可以避免浮點數(shù)表示錯誤。

  • 避免使用 BLOBS 存儲對象,存儲存放對象的位置。

  • VARCHAR(255) 是以 8 位數(shù)字存儲的大字符數(shù),在某些關(guān)系型數(shù)據(jù)庫中,大限度地利用字節(jié)。

  • 在適用場景中設(shè)置 NOT NULL 約束來提高搜索性能。

使用正確的索引

  • 你正查詢(SELECT、GROUP BYORDER BY、JOIN)的列如果用了索引會更快。

  • 索引通常表示為自平衡的 B 樹,可以保持?jǐn)?shù)據(jù)有序,并允許在對數(shù)時間內(nèi)進行搜索,順序訪問,插入,刪除操作。

  • 設(shè)置索引,會將數(shù)據(jù)存在內(nèi)存中,占用了更多內(nèi)存空間。

  • 寫入操作會變慢,因為索引需要被更新。

  • 加載大量數(shù)據(jù)時,禁用索引再加載數(shù)據(jù),然后重建索引,這樣也許會更快。

避免高成本的聯(lián)結(jié)操作

  • 有性能需要,可以進行非規(guī)范化。

分割數(shù)據(jù)表

  • 將熱點數(shù)據(jù)拆分到單獨的數(shù)據(jù)表中,可以有助于緩存。

調(diào)優(yōu)查詢緩存

  • 在某些情況下,查詢緩存可能會導(dǎo)致性能問題。

NoSQL

NoSQL 是鍵-值數(shù)據(jù)庫、文檔型數(shù)據(jù)庫、列型數(shù)據(jù)庫或圖數(shù)據(jù)庫的統(tǒng)稱。數(shù)據(jù)庫是非規(guī)范化的,表聯(lián)結(jié)大多在應(yīng)用程序代碼中完成。大多數(shù) NoSQL 無法實現(xiàn)真正符合 ACID 的事務(wù),支持最終一致。

BASE 通常被用于描述 NoSQL 數(shù)據(jù)庫的特性。相比 CAP 理論,BASE 強調(diào)可用性超過一致性。

  • 基本可用 - 系統(tǒng)保證可用性。

  • 軟狀態(tài) - 即使沒有輸入,系統(tǒng)狀態(tài)也可能隨著時間變化。

  • 最終一致性 - 經(jīng)過一段時間之后,系統(tǒng)最終會變一致,因為系統(tǒng)在此期間沒有收到任何輸入。

除了在 SQL 還是 NoSQL 之間做選擇,了解哪種類型的 NoSQL 數(shù)據(jù)庫最適合你的用例也是非常有幫助的。我們將在下一節(jié)中快速了解下 鍵-值存儲、文檔型存儲、列型存儲和圖存儲數(shù)據(jù)庫。

鍵-值存儲

抽象模型:哈希表

鍵-值存儲通常可以實現(xiàn) O(1) 時間讀寫,用內(nèi)存或 SSD 存儲數(shù)據(jù)。數(shù)據(jù)存儲可以按字典順序維護鍵,從而實現(xiàn)鍵的高效檢索。鍵-值存儲可以用于存儲元數(shù)據(jù)。

鍵-值存儲性能很高,通常用于存儲簡單數(shù)據(jù)模型或頻繁修改的數(shù)據(jù),如存放在內(nèi)存中的緩存。鍵-值存儲提供的操作有限,如果需要更多操作,復(fù)雜度將轉(zhuǎn)嫁到應(yīng)用程序?qū)用妗?/p>

鍵-值存儲是如文檔存儲,在某些情況下,甚至是圖存儲等更復(fù)雜的存儲系統(tǒng)的基礎(chǔ)。

文檔類型存儲

抽象模型:將文檔作為值的鍵-值存儲

文檔類型存儲以文檔(XML、JSON、二進制文件等)為中心,文檔存儲了指定對象的全部信息。文檔存儲根據(jù)文檔自身的內(nèi)部結(jié)構(gòu)提供 API 或查詢語句來實現(xiàn)查詢。請注意,許多鍵-值存儲數(shù)據(jù)庫有用值存儲元數(shù)據(jù)的特性,這也模糊了這兩種存儲類型的界限。

基于底層實現(xiàn),文檔可以根據(jù)集合、標(biāo)簽、元數(shù)據(jù)或者文件夾組織。盡管不同文檔可以被組織在一起或者分成一組,但相互之間可能具有完全不同的字段。

MongoDB 和 CouchDB 等一些文檔類型存儲還提供了類似 SQL 語言的查詢語句來實現(xiàn)復(fù)雜查詢。DynamoDB 同時支持鍵-值存儲和文檔類型存儲。

文檔類型存儲具備高度的靈活性,常用于處理偶爾變化的數(shù)據(jù)。

列型存儲

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

抽象模型:嵌套的 ColumnFamily<RowKey, Columns<ColKey, Value, Timestamp>> 映射

類型存儲的基本數(shù)據(jù)單元是列(名/值對)。列可以在列族(類似于 SQL 的數(shù)據(jù)表)中被分組。超級列族再分組普通列族。你可以使用行鍵獨立訪問每一列,具有相同行鍵值的列組成一行。每個值都包含版本的時間戳用于解決版本沖突。

Google 發(fā)布了第一個列型存儲數(shù)據(jù)庫 Bigtable,它影響了 Hadoop 生態(tài)系統(tǒng)中活躍的開源數(shù)據(jù)庫 HBase 和 Facebook 的 Cassandra。像 BigTable,HBase 和 Cassandra 這樣的存儲系統(tǒng)將鍵以字母順序存儲,可以高效地讀取鍵列。

列型存儲具備高可用性和高可擴展性。通常被用于大數(shù)據(jù)相關(guān)存儲。

圖數(shù)據(jù)庫

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

抽象模型: 圖

在圖數(shù)據(jù)庫中,一個節(jié)點對應(yīng)一條記錄,一個弧對應(yīng)兩個節(jié)點之間的關(guān)系。圖數(shù)據(jù)庫被優(yōu)化用于表示外鍵繁多的復(fù)雜關(guān)系或多對多關(guān)系。

圖數(shù)據(jù)庫為存儲復(fù)雜關(guān)系的數(shù)據(jù)模型,如社交網(wǎng)絡(luò),提供了很高的性能。它們相對較新,尚未廣泛應(yīng)用,查找開發(fā)工具或者資源相對較難。許多圖只能通過 REST API 訪問。

SQL 還是 NoSQL

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

選取 SQL 的原因:

  • 結(jié)構(gòu)化數(shù)據(jù)

  • 嚴(yán)格的模式

  • 關(guān)系型數(shù)據(jù)

  • 需要復(fù)雜的聯(lián)結(jié)操作

  • 事務(wù)

  • 清晰的擴展模式

  • 既有資源更豐富:開發(fā)者、社區(qū)、代碼庫、工具等

  • 通過索引進行查詢非???/p>

選取 NoSQL 的原因:

  • 半結(jié)構(gòu)化數(shù)據(jù)

  • 動態(tài)或靈活的模式

  • 非關(guān)系型數(shù)據(jù)

  • 不需要復(fù)雜的聯(lián)結(jié)操作

  • 存儲 TB (甚至 PB)級別的數(shù)據(jù)

  • 高數(shù)據(jù)密集的工作負(fù)載

  • IOPS 高吞吐量

適合 NoSQL 的示例數(shù)據(jù):

  • 埋點數(shù)據(jù)和日志數(shù)據(jù)

  • 排行榜或者得分?jǐn)?shù)據(jù)

  • 臨時數(shù)據(jù),如購物車

  • 頻繁訪問的(“熱”)表

  • 元數(shù)據(jù)/查找表

12. 緩存

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

緩存可以提高頁面加載速度,并可以減少服務(wù)器和數(shù)據(jù)庫的負(fù)載。在這個模型中,分發(fā)器先查看請求之前是否被響應(yīng)過,如果有則將之前的結(jié)果直接返回,來省掉真正的處理。

數(shù)據(jù)庫分片均勻分布的讀取是最好的。但是熱門數(shù)據(jù)會讓讀取分布不均勻,這樣就會造成瓶頸,如果在數(shù)據(jù)庫前加個緩存,就會抹平不均勻的負(fù)載和突發(fā)流量對數(shù)據(jù)庫的影響。

客戶端緩存

緩存可以位于客戶端(操作系統(tǒng)或者瀏覽器),服務(wù)端或者不同的緩存層。

CDN 緩存

CDN 也被視為一種緩存。

Web 服務(wù)器緩存

反向代理和緩存(比如 Varnish)可以直接提供靜態(tài)和動態(tài)內(nèi)容。Web 服務(wù)器同樣也可以緩存請求,返回相應(yīng)結(jié)果而不必連接應(yīng)用服務(wù)器。

數(shù)據(jù)庫緩存

數(shù)據(jù)庫的默認(rèn)配置中通常包含緩存級別,針對一般用例進行了優(yōu)化。調(diào)整配置,在不同情況下使用不同的模式可以進一步提高性能。

應(yīng)用緩存

基于內(nèi)存的緩存比如 Memcached 和 Redis 是應(yīng)用程序和數(shù)據(jù)存儲之間的一種鍵值存儲。由于數(shù)據(jù)保存在 RAM 中,它比存儲在磁盤上的典型數(shù)據(jù)庫要快多了。RAM 比磁盤限制更多,所以例如 least recently used (LRU) 的緩存無效算法可以將「熱門數(shù)據(jù)」放在 RAM 中,而對一些比較「冷門」的數(shù)據(jù)不做處理。

Redis 有下列附加功能:

  • 持久性選項

  • 內(nèi)置數(shù)據(jù)結(jié)構(gòu)比如有序集合和列表

有多個緩存級別,分為兩大類:數(shù)據(jù)庫查詢和對象:

  • 行級別

  • 查詢級別

  • 完整的可序列化對象

  • 完全渲染的 HTML

一般來說,你應(yīng)該盡量避免基于文件的緩存,因為這使得復(fù)制和自動縮放很困難。

數(shù)據(jù)庫查詢級別的緩存

當(dāng)你查詢數(shù)據(jù)庫的時候,將查詢語句的哈希值與查詢結(jié)果存儲到緩存中。這種方法會遇到以下問題:

  • 很難用復(fù)雜的查詢刪除已緩存結(jié)果。

  • 如果一條數(shù)據(jù)比如表中某條數(shù)據(jù)的一項被改變,則需要刪除所有可能包含已更改項的緩存結(jié)果。

對象級別的緩存

將您的數(shù)據(jù)視為對象,就像對待你的應(yīng)用代碼一樣。讓應(yīng)用程序?qū)?shù)據(jù)從數(shù)據(jù)庫中組合到類實例或數(shù)據(jù)結(jié)構(gòu)中:

  • 如果對象的基礎(chǔ)數(shù)據(jù)已經(jīng)更改了,那么從緩存中刪掉這個對象。

  • 允許異步處理:workers 通過使用最新的緩存對象來組裝對象。

建議緩存的內(nèi)容:

  • 用戶會話

  • 完全渲染的 Web 頁面

  • 活動流

  • 用戶圖數(shù)據(jù)

何時更新緩存

由于你只能在緩存中存儲有限的數(shù)據(jù),所以你需要選擇一個適用于你用例的緩存更新策略。

緩存模式

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

應(yīng)用從存儲器讀寫。緩存不和存儲器直接交互,應(yīng)用執(zhí)行以下操作:

  • 在緩存中查找記錄,如果所需數(shù)據(jù)不在緩存中

  • 從數(shù)據(jù)庫中加載所需內(nèi)容

  • 將查找到的結(jié)果存儲到緩存中

  • 返回所需內(nèi)容

def get_user(self, user_id):
    user = cache.get("user.{0}", user_id)    if user is None:        user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id)        if user is not None:            key = "user.{0}".format(user_id)
            cache.set(key, json.dumps(user))    return user

Memcached 通常用這種方式使用。

添加到緩存中的數(shù)據(jù)讀取速度很快。緩存模式也稱為延遲加載。只緩存所請求的數(shù)據(jù),這避免了沒有被請求的數(shù)據(jù)占滿了緩存空間。

緩存的缺點:

  • 請求的數(shù)據(jù)如果不在緩存中就需要經(jīng)過三個步驟來獲取數(shù)據(jù),這會導(dǎo)致明顯的延遲。

  • 如果數(shù)據(jù)庫中的數(shù)據(jù)更新了會導(dǎo)致緩存中的數(shù)據(jù)過時。這個問題需要通過設(shè)置 ? TTL 強制更新緩存或者直寫模式來緩解這種情況。

  • 當(dāng)一個節(jié)點出現(xiàn)故障的時候,它將會被一個新的節(jié)點替代,這增加了延遲的時間。

直寫模式

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

應(yīng)用使用緩存作為主要的數(shù)據(jù)存儲,將數(shù)據(jù)讀寫到緩存中,而緩存負(fù)責(zé)從數(shù)據(jù)庫中讀寫數(shù)據(jù)。

  • 應(yīng)用向緩存中添加/更新數(shù)據(jù)

  • 緩存同步地寫入數(shù)據(jù)存儲

  • 返回所需內(nèi)容

應(yīng)用代碼:

set_user(12345, {"foo":"bar"})

緩存代碼:

def set_user(user_id, values):
    user = db.query("UPDATE Users WHERE id = {0}", user_id, values)
    cache.set(user_id, user)

由于存寫操作所以直寫模式整體是一種很慢的操作,但是讀取剛寫入的數(shù)據(jù)很快。相比讀取數(shù)據(jù),用戶通常比較能接受更新數(shù)據(jù)時速度較慢。緩存中的數(shù)據(jù)不會過時。

直寫模式的缺點:

  • 由于故障或者縮放而創(chuàng)建的新的節(jié)點,新的節(jié)點不會緩存,直到數(shù)據(jù)庫更新為止。緩存應(yīng)用直寫模式可以緩解這個問題。

  • 寫入的大多數(shù)數(shù)據(jù)可能永遠(yuǎn)都不會被讀取,用 TTL 可以最小化這種情況的出現(xiàn)。

回寫模式

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

在回寫模式中,應(yīng)用執(zhí)行以下操作:

  • 在緩存中增加或者更新條目

  • 異步寫入數(shù)據(jù),提高寫入性能。

回寫模式的缺點:

  • 緩存可能在其內(nèi)容成功存儲之前丟失數(shù)據(jù)。

  • 執(zhí)行直寫模式比緩存或者回寫模式更復(fù)雜。

刷新

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

你可以將緩存配置成在到期之前自動刷新最近訪問過的內(nèi)容。

如果緩存可以準(zhǔn)確預(yù)測將來可能請求哪些數(shù)據(jù),那么刷新可能會導(dǎo)致延遲與讀取時間的降低。

刷新的缺點:

  • 不能準(zhǔn)確預(yù)測到未來需要用到的數(shù)據(jù)可能會導(dǎo)致性能不如不使用刷新。

緩存的缺點:

  • 需要保持緩存和真實數(shù)據(jù)源之間的一致性,比如數(shù)據(jù)庫根據(jù)緩存無效。

  • 需要改變應(yīng)用程序比如增加 Redis 或者 memcached。

  • 無效緩存是個難題,什么時候更新緩存是與之相關(guān)的復(fù)雜問題。

13. 異步

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

異步工作流有助于減少那些原本順序執(zhí)行的請求時間。它們可以通過提前進行一些耗時的工作來幫助減少請求時間,比如定期匯總數(shù)據(jù)。

消息隊列

消息隊列接收,保留和傳遞消息。如果按順序執(zhí)行操作太慢的話,你可以使用有以下工作流的消息隊列:

  • 應(yīng)用程序?qū)⒆鳂I(yè)發(fā)布到隊列,然后通知用戶作業(yè)狀態(tài)

  • 一個 worker 從隊列中取出該作業(yè),對其進行處理,然后顯示該作業(yè)完成

不去阻塞用戶操作,作業(yè)在后臺處理。在此期間,客戶端可能會進行一些處理使得看上去像是任務(wù)已經(jīng)完成了。例如,如果要發(fā)送一條推文,推文可能會馬上出現(xiàn)在你的時間線上,但是可能需要一些時間才能將你的推文推送到你的所有關(guān)注者那里去。

Redis 是一個令人滿意的簡單的消息代理,但是消息有可能會丟失。

RabbitMQ 很受歡迎但是要求你適應(yīng)「AMQP」協(xié)議并且管理你自己的節(jié)點。

Amazon SQS 是被托管的,但可能具有高延遲,并且消息可能會被傳送兩次。

任務(wù)隊列

任務(wù)隊列接收任務(wù)及其相關(guān)數(shù)據(jù),運行它們,然后傳遞其結(jié)果。 它們可以支持調(diào)度,并可用于在后臺運行計算密集型作業(yè)。

Celery 支持調(diào)度,主要是用 Python 開發(fā)的。

背壓

如果隊列開始明顯增長,那么隊列大小可能會超過內(nèi)存大小,導(dǎo)致高速緩存未命中,磁盤讀取,甚至性能更慢。背壓可以通過限制隊列大小來幫助我們,從而為隊列中的作業(yè)保持高吞吐率和良好的響應(yīng)時間。一旦隊列填滿,客戶端將得到服務(wù)器忙或者 HTTP 503 狀態(tài)碼,以便稍后重試。客戶端可以在稍后時間重試該請求,也許是指數(shù)退避。

異步的缺點:

  • 簡單的計算和實時工作流等用例可能更適用于同步操作,因為引入隊列可能會增加延遲和復(fù)雜性。

14. 通訊

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

超文本傳輸協(xié)議(HTTP)

HTTP 是一種在客戶端和服務(wù)器之間編碼和傳輸數(shù)據(jù)的方法。它是一個請求/響應(yīng)協(xié)議:客戶端和服務(wù)端針對相關(guān)內(nèi)容和完成狀態(tài)信息的請求和響應(yīng)。HTTP 是獨立的,允許請求和響應(yīng)流經(jīng)許多執(zhí)行負(fù)載均衡,緩存,加密和壓縮的中間路由器和服務(wù)器。

一個基本的 HTTP 請求由一個動詞(方法)和一個資源(端點)組成。 以下是常見的 HTTP 動詞:

動詞描述*冪等安全性可緩存
GET讀取資源YesYesYes
POST創(chuàng)建資源或觸發(fā)處理數(shù)據(jù)的進程NoNoYes,如果回應(yīng)包含刷新信息
PUT創(chuàng)建或替換資源YesNoNo
PATCH部分更新資源NoNoYes,如果回應(yīng)包含刷新信息
DELETE刪除資源YesNoNo

多次執(zhí)行不會產(chǎn)生不同的結(jié)果。

HTTP 是依賴于較低級協(xié)議(如 TCP 和 UDP)的應(yīng)用層協(xié)議。

傳輸控制協(xié)議(TCP)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 
 

TCP 是通過 IP 網(wǎng)絡(luò)的面向連接的協(xié)議。 使用握手建立和斷開連接。 發(fā)送的所有數(shù)據(jù)包保證以原始順序到達目的地,用以下措施保證數(shù)據(jù)包不被損壞:

  • 每個數(shù)據(jù)包的序列號和校驗碼。

  • 確認(rèn)包和自動重傳

如果發(fā)送者沒有收到正確的響應(yīng),它將重新發(fā)送數(shù)據(jù)包。如果多次超時,連接就會斷開。TCP 實行流量控制和擁塞控制。這些確保措施會導(dǎo)致延遲,而且通常導(dǎo)致傳輸效率比 UDP 低。

為了確保高吞吐量,Web 服務(wù)器可以保持大量的 TCP 連接,從而導(dǎo)致高內(nèi)存使用。在 Web 服務(wù)器線程間擁有大量開放連接可能開銷巨大,消耗資源過多,也就是說,一個 memcached 服務(wù)器。連接池 可以幫助除了在適用的情況下切換到 UDP。

TCP 對于需要高可靠性但時間緊迫的應(yīng)用程序很有用。比如包括 Web 服務(wù)器,數(shù)據(jù)庫信息,SMTP,F(xiàn)TP 和 SSH。

以下情況使用 TCP 代替 UDP:

  • 你需要數(shù)據(jù)完好無損。

  • 你想對網(wǎng)絡(luò)吞吐量自動進行最佳評估。

用戶數(shù)據(jù)報協(xié)議(UDP)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

UDP 是無連接的。數(shù)據(jù)報(類似于數(shù)據(jù)包)只在數(shù)據(jù)報級別有保證。數(shù)據(jù)報可能會無序的到達目的地,也有可能會遺失。UDP 不支持擁塞控制。雖然不如 TCP 那樣有保證,但 UDP 通常效率更高。

UDP 可以通過廣播將數(shù)據(jù)報發(fā)送至子網(wǎng)內(nèi)的所有設(shè)備。這對 DHCP 很有用,因為子網(wǎng)內(nèi)的設(shè)備還沒有分配 IP 地址,而 IP 對于 TCP 是必須的。

UDP 可靠性更低但適合用在網(wǎng)絡(luò)電話、視頻聊天,流媒體和實時多人游戲上。

以下情況使用 UDP 代替 TCP:

  • 你需要低延遲

  • 相對于數(shù)據(jù)丟失更糟的是數(shù)據(jù)延遲

  • 你想實現(xiàn)自己的錯誤校正方法

遠(yuǎn)程過程調(diào)用協(xié)議(RPC)

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的 

在 RPC 中,客戶端會去調(diào)用另一個地址空間(通常是一個遠(yuǎn)程服務(wù)器)里的方法。調(diào)用代碼看起來就像是調(diào)用的是一個本地方法,客戶端和服務(wù)器交互的具體過程被抽象。遠(yuǎn)程調(diào)用相對于本地調(diào)用一般較慢而且可靠性更差,因此區(qū)分兩者是有幫助的。熱門的 RPC 框架包括 Protobuf、Thrift 和 Avro。

RPC 是一個“請求-響應(yīng)”協(xié)議:

  • 客戶端程序 ── 調(diào)用客戶端存根程序。就像調(diào)用本地方法一樣,參數(shù)會被壓入棧中。

  • 客戶端 stub 程序 ── 將請求過程的 id 和參數(shù)打包進請求信息中。

  • 客戶端通信模塊 ── 將信息從客戶端發(fā)送至服務(wù)端。

  • 服務(wù)端通信模塊 ── 將接受的包傳給服務(wù)端存根程序。

  • 服務(wù)端 stub 程序 ── 將結(jié)果解包,依據(jù)過程 id 調(diào)用服務(wù)端方法并將參數(shù)傳遞過去。

RPC 調(diào)用示例:

GET /someoperation?data=anId
POST /anotheroperation
{  "data":"anId";  "anotherdata": "another value"}

RPC 專注于暴露方法。RPC 通常用于處理內(nèi)部通訊的性能問題,這樣你可以手動處理本地調(diào)用以更好的適應(yīng)你的情況。

當(dāng)以下情況時選擇本地庫(也就是 SDK):

  • 你知道你的目標(biāo)平臺。

  • 你想控制如何訪問你的“邏輯”。

  • 你想對發(fā)生在你的庫中的錯誤進行控制。

  • 性能和終端用戶體驗是你最關(guān)心的事。

遵循 REST 的 HTTP API 往往更適用于公共 API。

缺點:RPC
  • RPC 客戶端與服務(wù)實現(xiàn)捆綁地很緊密。

  • 一個新的 API 必須在每一個操作或者用例中定義。

  • RPC 很難調(diào)試。

  • 你可能沒辦法很方便的去修改現(xiàn)有的技術(shù)。舉個例子,如果你希望在 Squid 這樣的緩存服務(wù)器上確保 RPC 被正確緩存的話可能需要一些額外的努力了。

表述性狀態(tài)轉(zhuǎn)移(REST)

REST 是一種強制的客戶端/服務(wù)端架構(gòu)設(shè)計模型,客戶端基于服務(wù)端管理的一系列資源操作。服務(wù)端提供修改或獲取資源的接口。所有的通信必須是無狀態(tài)和可緩存的。

RESTful 接口有四條規(guī)則:

  • 標(biāo)志資源(HTTP 里的 URI) ── 無論什么操作都使用同一個 URI。

  • 表示的改變(HTTP 的動作) ── 使用動作, headers 和 body。

  • 可自我描述的錯誤信息(HTTP 中的 status code) ── 使用狀態(tài)碼,不要重新造輪子。

  • HATEOAS(HTTP 中的 HTML 接口) ── 你的 web 服務(wù)器應(yīng)該能夠通過瀏覽器訪問。

REST 請求的例子:

GET /someresources/anId
PUT /someresources/anId
{"anotherdata": "another value"}

REST 關(guān)注于暴露數(shù)據(jù)。它減少了客戶端/服務(wù)端的耦合程度,經(jīng)常用于公共 HTTP API 接口設(shè)計。REST 使用更通常與規(guī)范化的方法來通過 URI 暴露資源,通過 header 來表述并通過 GET、POST、PUT、DELETE 和 PATCH 這些動作來進行操作。因為無狀態(tài)的特性,REST 易于橫向擴展和隔離。

缺點:REST
  • 由于 REST 將重點放在暴露數(shù)據(jù),所以當(dāng)資源不是自然組織的或者結(jié)構(gòu)復(fù)雜的時候它可能無法很好的適應(yīng)。舉個例子,返回過去一小時中與特定事件集匹配的更新記錄這種操作就很難表示為路徑。使用 REST,可能會使用 URI 路徑,查詢參數(shù)和可能的請求體來實現(xiàn)。

  • REST 一般依賴幾個動作(GET、POST、PUT、DELETE 和 PATCH),但有時候僅僅這些沒法滿足你的需要。舉個例子,將過期的文檔移動到歸檔文件夾里去,這樣的操作可能沒法簡單的用上面這幾個 verbs 表達。

  • 為了渲染單個頁面,獲取被嵌套在層級結(jié)構(gòu)中的復(fù)雜資源需要客戶端,服務(wù)器之間多次往返通信。例如,獲取博客內(nèi)容及其關(guān)聯(lián)評論。對于使用不確定網(wǎng)絡(luò)環(huán)境的移動應(yīng)用來說,這些多次往返通信是非常麻煩的。

  • 隨著時間的推移,更多的字段可能會被添加到 API 響應(yīng)中,較舊的客戶端將會接收到所有新的數(shù)據(jù)字段,即使是那些它們不需要的字段,結(jié)果它會增加負(fù)載大小并引起更大的延遲。

RPC 與 REST 比較

操作RPCREST
注冊POST /signupPOST /persons
注銷POST /resign
{
"personid": "1234"
}
DELETE /persons/1234
讀取用戶信息GET /readPerson?personid=1234GET /persons/1234
讀取用戶物品列表GET /readUsersItemsList?personid=1234GET /persons/1234/items
向用戶物品列表添加一項POST /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
}
POST /persons/1234/items
{
"itemid": "456"
}
更新一個物品POST /modifyItem
{
"itemid": "456";
"key": "value"
}
PUT /items/456
{
"key": "value"
}
刪除一個物品POST /removeItem
{
"itemid": "456"
}
DELETE /items/456

15. 安全

這一部分需要更多內(nèi)容。一起來吧!

安全是一個寬泛的話題。除非你有相當(dāng)?shù)慕?jīng)驗、安全方面背景或者正在申請的職位要求安全知識,你不需要了解安全基礎(chǔ)知識以外的內(nèi)容:

  • 在運輸和等待過程中加密

  • 對所有的用戶輸入和從用戶那里發(fā)來的參數(shù)進行處理以防止 XSS 和 SQL 注入。

  • 使用參數(shù)化的查詢來防止 SQL 注入。

  • 使用最小權(quán)限原則。

16. 附錄

一些時候你會被要求做出保守估計。比如,你可能需要估計從磁盤中生成 100 張圖片的縮略圖需要的時間或者一個數(shù)據(jù)結(jié)構(gòu)需要多少的內(nèi)存。2 的次方表和每個開發(fā)者都需要知道的一些時間數(shù)據(jù)(譯注:OSChina 上有這篇文章的譯文)都是一些很方便的參考資料。

2 的次方表

Power           Exact Value         Approx Value        Bytes---------------------------------------------------------------7                             128
8                             256
10                           1024   1 thousand           1 KB
16                         65,536                       64 KB
20                      1,048,576   1 million            1 MB
30                  1,073,741,824   1 billion            1 GB
32                  4,294,967,296                        4 GB
40              1,099,511,627,776   1 trillion           1 TB

每個程序員都應(yīng)該知道的延遲數(shù)

Latency Comparison Numbers--------------------------L1 cache reference                           0.5 ns
Branch mispredict                            5   ns
L2 cache reference                           7   ns                      14x L1 cacheMutex lock/unlock                          100   nsMain memory reference                      100   ns                      20x L2 cache, 200x L1 cacheCompress 1K bytes with Zippy            10,000   ns       10 us
Send 1 KB bytes over 1 Gbps network     10,000   ns       10 usRead 4 KB randomly from SSD*           150,000   ns      150 us          ~1GB/sec SSDRead 1 MB sequentially from memory     250,000   ns      250 usRound trip within same datacenter      500,000   ns      500 usRead 1 MB sequentially from SSD*     1,000,000   ns    1,000 us    1 ms  ~1GB/sec SSD, 4X memoryDisk seek                           10,000,000   ns   10,000 us   10 ms  20x datacenter roundtripRead 1 MB sequentially from 1 Gbps  10,000,000   ns   10,000 us   10 ms  40x memory, 10X SSDRead 1 MB sequentially from disk    30,000,000   ns   30,000 us   30 ms 120x memory, 30X SSD
Send packet CA->Netherlands->CA    150,000,000   ns  150,000 us  150 ms
Notes-----1 ns = 10^-9 seconds1 us = 10^-6 seconds = 1,000 ns1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns

基于上述數(shù)字的指標(biāo):

  • 從磁盤以 30 MB/s 的速度順序讀取

  • 以 100 MB/s 從 1 Gbps 的以太網(wǎng)順序讀取

  • 從 SSD 以 1 GB/s 的速度讀取

  • 以 4 GB/s 的速度從主存讀取

  • 每秒能繞地球 6-7 圈

  • 數(shù)據(jù)中心內(nèi)每秒有 2,000 次往返

延遲數(shù)可視化

大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的

到此,關(guān)于“大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

標(biāo)題名稱:大型互聯(lián)網(wǎng)系統(tǒng)架構(gòu)是怎么設(shè)計的-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article24/dcoije.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、用戶體驗、微信公眾號商城網(wǎng)站、網(wǎng)站建設(shè)、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管