1. 程式人生 > >《從0開始學架構》——架構設計的複雜度來源

《從0開始學架構》——架構設計的複雜度來源

本系列是極客時間《從0開始學架構》的讀書筆記。

既然架構設計也是一種為了解決高複雜度問題的方案,那這些高複雜度問題從何而來呢?

一、高效能

對應《04 | 複雜度來源:高效能》

主要體現在兩方面:單機複雜度和叢集複雜度。

在單臺機器上,為了高效能,先後出現了批處理系統、分時系統、並行系統。

分時系統分為多程序和多執行緒。

但是在單核上,雖然多程序和多執行緒對使用者來講是並行的,但本質只是併發(邏輯上處於同一時間段)。於是出現真正的多工並行系統:多CPU。

單機系統的複雜度主要體現在,需要按照實際業務,將不同技術選擇與結合。

雖然單機在效能上發展迅速,但和現實中所遇到的問題相比,又顯得遠遠不如。所以必須採用機器叢集,才能滿足現實業務的吞吐量。

相對於單機來說,採用叢集需要考慮在機器之間通訊的問題,這是叢集複雜度的最主要來源之一。比如說如何將任務分配,如何將任務分解。一旦使用叢集,就需要考慮如何保證叢集內部的負載均衡,不能旱的旱死澇的澇死;隨著機器數的增多業務也隨之拆分,叢集內的通訊耗時也上升,就需要考慮叢集內的通訊耗時,防止得不償失。

另一個主要的複雜度來源是一致性,不過此節講的是高效能不是高可用,所以作者沒有提及。

作者同樣沒有提及的是,高效能的定義。所謂高效能,可以粗略認為是響應速度。而本節主要是從吞吐量上來進行優化的,這是因為對於一定規模的請求,吞吐量越大,平均響應速度越快(但不會超過上限)。

二、高可用

對應《05 | 複雜度來源:高可用》

高可用指的是服務“無中斷”。
實現高可用的手段是:增加機器。為實現高效能增加機器,是為了擴充套件效能。而為實現高可用增加機器,是為了增加冗餘。

複雜度分為兩方面。一方面是計算高可用,複雜度來源同高效能的叢集一樣。
另一方面是儲存高可用,也就是之前我提到資料一致性問題了。這個領域有一個著名的CAP定理,也就是說,儲存高可用不可能同時滿足“一致性、可用性、分割槽容錯性”,只能滿足其中兩個。
一般需要為了不一致的資料進行決策。決策機制分為獨裁式、協商式(主備等)、民主式(ZooKeeper叢集的選舉)

三、可擴充套件性

對應《06 | 複雜度來源:可擴充套件性》

我原本以為可擴充套件性是指水平擴充套件,沒想到這裡的可擴充套件性指的是對於需求變化是否可快速無成本擴充套件。

這個其實我認為是最難的,因為你沒法去度量人類啊,誰知道之後會出現什麼鬼需求呢?

關於這點,作者談了談在面向物件設計下的方法。

一個是分層,通過隔離變化,將變化層與穩定層隔離。比如說業務上會使用多個SQL資料庫,那就通過一個統一的資料庫連線層來與各個資料庫通訊。

另一個就是抽象,將一個系統抽出一個抽象層和實現層。在面向物件設計中,典型的實踐是設計模式和規則引擎。雖然我不太懂這兩個,但是最近看了一本《冒號課堂》,裡面對於面向物件和抽象進行了詳細的講解。對於面向物件,最好是對於Java、C++、C#有深刻的實踐。規則引擎則必須對規則進行抽象。

但是反過來說,怎麼去設計可擴充套件性強的架構,怎麼不會過度設計,很難拿出一些非常客觀的度量方法。即使有人說有,我根據過往經驗,也不太會信。

四、低成本、安全、規模

對應《07 | 複雜度來源:低成本、安全、規模》

如題所示。如文中所述,這類問題出現時,需要的解決方法更趨向於“創新”。有可能是引入新技術,也有可能是創造新技術。

這類新技術如:為解決高併發場景下關係型資料庫無法應對而創造的NoSQL(Redis,Memcached),為解決關係型資料庫全文搜尋低效而創造的專門的全文搜尋引擎(ElasticSearch、Solr、Sphinx),為解決海量資料儲存和計算問題而創造的Hadoop。

可以發現,大多數都是儲存領域關於大流量+高併發的問題。