分布式系統並不是什麼新鮮詞,在上個世紀七八十年代就已經有各種分布式系統出現。只是在網際網路時代,分布式系統才大放異彩,尤其是 google 更是把分布式系統運用到了極致。google 整個的軟體構架都是基於各種各樣的分布式系統,諸如 borg、mapreduce、bigtable 等。正是這些分布式系統,使得 google 可以處理高併發請求響應以及海量資料處理等。apache 旗下的 hadoop、spark、mesos 等分布式系統,把大資料處理相關技術變得非常親民,讓更多企業客戶體會到了分布式系統的便利。
分布式系統最大的特點是可擴充套件性,它能夠適應需求變化而擴充套件。企業級應用需求經常隨時間而不斷變化,這也對企業級應用平台提出了很高的要求。企業級應用平台必須要能適應需求的變化,即具有可擴充套件性。比如移動網際網路 2c 應用,隨著網際網路企業的業務規模不斷增大,業務變得越來越複雜,併發使用者請求越來越多,要處理的資料也越來越多,這個時候企業級應用平台必須能夠適應這些變化,支援高併發訪問和海量資料處理。分布式系統有良好的可擴充套件性,可以通過增加伺服器數量來增強分布式系統整體的處理能力,以應對企業的業務增長帶來的計算需求。
分布式系統最大的特點是廉價高效:由成本低廉的 pc 伺服器組成的集群,在效能方面能夠達到或超越大型機的處理效能,在成本上遠低於大型機。這也是分布式系統最吸引人之處。成本低廉的 pc 伺服器在硬體可靠性方面比大型機相去甚遠,於是分布式系統由軟體來對硬體進行容錯,通過軟體來保證整體系統的高可靠性。
上面簡單介紹了分布式系統的基本情況,下面詳細闡述筆者理解的幾個分布式系統設計理念:
1. 分布式系統對伺服器硬體要求很低
這一點主要現在如下兩個方面:
一般而言,網際網路公司的大型資料中心都是選用大量廉價的 pc 伺服器而不是用幾台高效能伺服器搭建分布式集群,以此來降低資料中心成本。比如,google 對於資料中心的成本控制做到了極致:所有伺服器一律不要機箱;主機板完全定製,只要最基本的元件,早期的定製主機板連電源開關和 usb 介面都不要;在主機板上加裝隔離帶把 cpu 單獨隔出來,讓冷風只吹 cpu,不吹記憶體、硬碟等不需要降溫的元件,最大限度降低冷卻電力消耗。
2. 分布式系統強調橫向可擴充套件性
橫向可擴充套件性(scale out)是指通過增加伺服器數量來提公升集群整體效能。縱向可擴充套件性(scale up)是指提公升每台伺服器效能進而提公升集群整體效能。縱向可擴充套件性的上限非常明顯,單台伺服器的效能不可能無限提公升,而且跟伺服器效能相比,網路開銷才是分布式系統最大的瓶頸。橫向可擴充套件性的上限空間比較大,集群總能很方便地增加伺服器。而且分布式系統會盡可能保證橫向擴充套件帶來集群整體效能的(準)線性提公升。比如有 10 臺伺服器組成的集群,橫向擴充套件為 100 臺同樣伺服器的集群,那麼整體分布式系統效能會提公升為接近原來的 10 倍。
網際網路公司的資料中心,一般乙個分布式系統橫向擴充套件的上限在萬台伺服器左右。google 資料中心的基本單元,cell,由兩萬台左右伺服器組成,每個 cell 由一套分布式管理系統,borg,統一管理,每個資料中心都由多個 cell 組成。
3. 分布式系統不允許單點失效(no single point failure)
單點失效是指,某個應用服務只有乙份例項執行在某一台伺服器上,這台伺服器一旦掛掉,那麼這個應用服務必然也受影響而掛掉,導致整個服務不可用。例如,某**後台如果只在某一台伺服器上執行乙份,那這台伺服器一旦宕機,該**服務必然受影響而不可用。再比如,如果所有資料都存在某一台伺服器上,那一旦這台伺服器壞了,所有資料都不可訪問。
因為分布式系統的伺服器都是廉價的 pc 伺服器,硬體不能保證 100% 可靠,所以分布式系統預設每台伺服器隨時都可能發生故障掛掉。同時分布式系統必須要提供高可靠服務,不允許出現單點失效,因此分布式系統裡執行的每個應用服務都有多個執行例項跑在多個節點上,每個資料點都有多個備份存在不同的節點上。這樣一來,多個節點同時發生故障,導致某個應用服務的所有例項都掛掉、或某個資料點的多個備份都不可讀的概率大大降低,進而有效防止單點失效。
通常情況,不要讓伺服器滿負荷執行,伺服器長時間滿負荷執行的話,出故障的概率顯著公升高。所以分布式系統採用一大堆中低效能的 pc 伺服器,盡可能把負載均攤到所有伺服器上,讓每台伺服器的負載都不高,保證集群整體穩定性。
4. 分布式系統盡可能減少節點間通訊開銷
5. 分布式系統應用服務最好做成無狀態的
應用服務的狀態是指執行時程式因為處理服務請求而存在記憶體的資料。分布式應用服務最好是設計成無狀態。因為如果應用程式是有狀態的,那麼一旦伺服器宕機就會使得應用服務程式受影響而掛掉,那存在記憶體的資料也就丟失了,這顯然不是高可靠的服務。把應用服務設計成無狀態的,讓程式把需要儲存的資料都儲存在專門的儲存上,這樣應用服務程式可以任意重啟而不丟失資料,方便分布式系統在伺服器宕機後恢復應用服務。
比如,在設計**後台的時候,對於使用者登陸請求,可以把登陸使用者的 session 相關資訊儲存在 redis 或 memcache 等快取服務中,這樣每個**的後台例項不儲存使用者登入狀態,這樣即使重啟**後台程式也不丟失使用者的登入狀態資訊;如果把使用者的 session 相關資訊儲存在**後台程式的記憶體裡,那一旦受理使用者登入的**後台程式例項掛掉,必然有使用者的登入狀態資訊會丟失。
總而言之,分布式系統是大資料時代企業級應用的首選平台,它有良好的可擴充套件性,尤其是橫向可擴充套件性(scale out),使得分布式系統非常靈活,能應對千變萬化的企業級需求,而且降低了企業客戶對伺服器硬體的要求,真正能做到應用服務層面的彈性擴充套件(auto-scaling)。
一文了解學習分布式追蹤系統 Zipkin
zipkin 基本原理架構介紹,簡單入門示例和 zipkin ui 介紹 幾種收集器 collector http rabbitmq 和 kafka 配置介紹 幾種儲存器 storage memory mysql elasticsearch 和 cassandra 配置介紹 本地日誌列印追蹤資訊配置...
一文搞定分布式系統ID生成方案
系統唯一id是我們在設計乙個系統的時候常常會遇見的問題,也常常為這個問題而糾結。生成id的方法有很多,適應不同的場景 需求以及效能要求。所以有些比較複雜的系統會有多個id生成的策略。下面就介紹一些常見的id生成策略。資料庫自增長序列或字段 最常見的方式。利用資料庫,全資料庫唯一。優點 1 簡單,方便...
一文搞懂MySQL XA如何實現分布式事務
目錄 mysql支援單機事務的良好表現毋庸置疑,那麼在分布式系統中,涉及多個節點,mysql又是如何實現分布式事務的呢?比如開發乙個業務系統,它接受外tzxdqdk部的請求,然後訪問多個內部其它系統才能執行該請求。執行時我們需要同時更新多個資料庫的值 d1,d2,d3 由於系統必須處於乙個一致性,也...