低成本
當我們的架構(gòu)方案只涉及幾臺或者十幾臺服務(wù)器時,一般情況下成本并不是我們重點關(guān)注的目標燎斩,但如果架構(gòu)方案涉及幾百上千甚至上萬臺服務(wù)器虱歪,成本就會變成一個非常重要的架構(gòu)設(shè)計考慮點。
當我們設(shè)計“高性能”“高可用”的架構(gòu)時栅表,通用的手段都是增加更多服務(wù)器來滿足“高性能”和“高可用”的要求笋鄙;而低成本正好與此相反,我們需要減少服務(wù)器的數(shù)量才能達成低成本的目標怪瓶。因此萧落,低成本本質(zhì)上是與高性能和高可用沖突的,所以低成本很多時候不會是架構(gòu)設(shè)計的首要目標,而是架構(gòu)設(shè)計的附加約束找岖。
低成本給架構(gòu)設(shè)計帶來的主要復(fù)雜度體現(xiàn)在陨倡,往往只有“創(chuàng)新”才能達到低成本目標。這里的“創(chuàng)新”既包括開創(chuàng)一個全新的技術(shù)領(lǐng)域(這個要求對絕大部分公司太高)许布,也包括引入新技術(shù)兴革,如果沒有找到能夠解決自己問題的新技術(shù),那么就真的需要自己創(chuàng)造新技術(shù)了蜜唾。
新技術(shù)例子:
NoSQL(Memcache杂曲、Redis 等)的出現(xiàn)是為了解決關(guān)系型數(shù)據(jù)庫無法應(yīng)對高并發(fā)訪問帶來的訪問壓力。
全文搜索引擎(Sphinx袁余、Elasticsearch擎勘、Solr)的出現(xiàn)是為了解決關(guān)系型數(shù)據(jù)庫 like 搜索的低效的問題。
Hadoop 的出現(xiàn)是為了解決傳統(tǒng)文件系統(tǒng)無法應(yīng)對海量數(shù)據(jù)存儲和計算的問題颖榜。
業(yè)界例子:
Facebook 為了解決 PHP 的低效問題货抄,剛開始的解決方案是 HipHop PHP,可以將 PHP 語言翻譯為 C++ 語言執(zhí)行朱转,后來改為 HHVM蟹地,將 PHP 翻譯為字節(jié)碼然后由虛擬機執(zhí)行,和 Java 的 JVM 類似藤为。
新浪微博將傳統(tǒng)的 Redis/MC + MySQL 方式怪与,擴展為 Redis/MC + SSD Cache + MySQL 方式,SSD Cache 作為 L2 緩存使用缅疟,既解決了 MC/Redis 成本過高分别,容量小的問題,也解決了穿透 DB 帶來的數(shù)據(jù)庫訪問壓力(來源:http://www.infoq.com/cn/articles/weibo-platform-archieture )存淫。
Linkedin 為了處理每天 5 千億的事件耘斩,開發(fā)了高效的 Kafka 消息系統(tǒng)。
其他類似將 Ruby on Rails 改為 Java桅咆、Lua + redis 改為 Go 語言實現(xiàn)的例子還有很多括授。
無論是引入新技術(shù),還是自己創(chuàng)造新技術(shù)岩饼,都是一件復(fù)雜的事情荚虚。引入新技術(shù)的主要復(fù)雜度在于需要去熟悉新技術(shù),并且將新技術(shù)與已有技術(shù)結(jié)合起來籍茧;創(chuàng)造新技術(shù)的主要復(fù)雜度在于需要自己去創(chuàng)造全新的理念和技術(shù)版述,并且新技術(shù)跟舊技術(shù)相比,需要有質(zhì)的飛躍寞冯。
相比來說渴析,創(chuàng)造新技術(shù)復(fù)雜度更高晚伙,因此一般中小公司基本都是靠引入新技術(shù)來達到低成本的目標;而大公司更有可能自己去創(chuàng)造新的技術(shù)來達到低成本的目標俭茧,因為大公司才有足夠的資源撬腾、技術(shù)和時間去創(chuàng)造新技術(shù)。
安全
安全本身是一個龐大而又復(fù)雜的技術(shù)領(lǐng)域恢恼,并且一旦出問題,對業(yè)務(wù)和企業(yè)形象影響非常大胰默。
例如:
2016 年雅虎爆出史上最大規(guī)模信息泄露事件场斑,逾 5 億用戶資料在 2014 年被竊取。
2016 年 10 月美國遭史上最大規(guī)模 DDoS 攻擊牵署,東海岸網(wǎng)站集體癱瘓漏隐。
2013 年 10 月,為全國 4500 多家酒店提供網(wǎng)絡(luò)服務(wù)的浙江慧達驛站網(wǎng)絡(luò)有限公司奴迅,因安全漏洞問題青责,致 2 千萬條入住酒店的客戶信息泄露,由此導(dǎo)致很多敲詐取具、家庭破裂的后續(xù)事件脖隶。
正因為經(jīng)常能夠看到或者聽到各類安全事件,所以大部分技術(shù)人員和架構(gòu)師暇检,對安全這部分會多一些了解和考慮产阱。
從技術(shù)的角度來講,安全可以分為兩類:一類是功能上的安全块仆,一類是架構(gòu)上的安全构蹬。
1. 功能安全
例如,常見的 XSS 攻擊悔据、CSRF 攻擊庄敛、SQL 注入、Windows 漏洞科汗、密碼破解等藻烤,本質(zhì)上是因為系統(tǒng)實現(xiàn)有漏洞,黑客有了可乘之機头滔。黑客會利用各種漏洞潛入系統(tǒng)隐绵,這種行為就像小偷一樣,黑客和小偷的手法都是利用系統(tǒng)或家中不完善的地方潛入拙毫,并進行破壞或者盜取依许。因此形象地說,功能安全其實就是“防小偷”缀蹄。
從實現(xiàn)的角度來看峭跳,功能安全更多地是和具體的編碼相關(guān)膘婶,與架構(gòu)關(guān)系不大。現(xiàn)在很多開發(fā)框架都內(nèi)嵌了常見的安全功能蛀醉,能夠大大減少安全相關(guān)功能的重復(fù)開發(fā)悬襟,但框架只能預(yù)防常見的安全漏洞和風(fēng)險(常見的 XSS 攻擊、CSRF 攻擊拯刁、SQL 注入等)脊岳,無法預(yù)知新的安全問題,而且框架本身很多時候也存在漏洞(例如垛玻,流行的 Apache Struts2 就多次爆出了調(diào)用遠程代碼執(zhí)行的高危漏洞割捅,給整個互聯(lián)網(wǎng)都造成了一定的恐慌)。所以功能安全是一個逐步完善的過程帚桩,而且往往都是在問題出現(xiàn)后才能有針對性的提出解決方案亿驾,我們永遠無法預(yù)測系統(tǒng)下一個漏洞在哪里,也不敢說自己的系統(tǒng)肯定沒有任何問題账嚎。換句話講莫瞬,功能安全其實也是一個“攻”與“防”的矛盾,只能在這種攻防大戰(zhàn)中逐步完善郭蕉,不可能在系統(tǒng)架構(gòu)設(shè)計的時候一勞永逸地解決疼邀。
2. 架構(gòu)安全
如果說功能安全是“防小偷”,那么架構(gòu)安全就是“防強盜”召锈。強盜會直接用大錘將門砸開檩小,或者用炸藥將圍墻炸倒;小偷是偷東西烟勋,而強盜很多時候就是故意搞破壞规求,對系統(tǒng)的影響也大得多。因此架構(gòu)設(shè)計時需要特別關(guān)注架構(gòu)安全卵惦,尤其是互聯(lián)網(wǎng)時代阻肿,理論上來說系統(tǒng)部署在互聯(lián)網(wǎng)上時,全球任何地方都可以發(fā)起攻擊沮尿。
傳統(tǒng)的架構(gòu)安全主要依靠防火墻丛塌,防火墻最基本的功能就是隔離網(wǎng)絡(luò),通過將網(wǎng)絡(luò)劃分成不同的區(qū)域畜疾,制定出不同區(qū)域之間的訪問控制策略來控制不同信任程度區(qū)域間傳送的數(shù)據(jù)流赴邻。例如,下圖是一個典型的銀行系統(tǒng)的安全架構(gòu)啡捶。
從圖中可以看到姥敛,整個系統(tǒng)根據(jù)不同的分區(qū)部署了多個防火墻來保證系統(tǒng)的安全。
防火墻的功能雖然強大瞎暑,但性能一般彤敛,所以在傳統(tǒng)的銀行和企業(yè)應(yīng)用領(lǐng)域應(yīng)用較多与帆。但在互聯(lián)網(wǎng)領(lǐng)域,防火墻的應(yīng)用場景并不多墨榄。因為互聯(lián)網(wǎng)的業(yè)務(wù)具有海量用戶訪問和高并發(fā)的特點玄糟,防火墻的性能不足以支撐;尤其是互聯(lián)網(wǎng)領(lǐng)域的 DDoS 攻擊袄秩,輕則幾 GB阵翎,重則幾十 GB。
公司一般不會堆防火墻來防 DDoS 攻擊之剧,因為 DDoS 攻擊最大的影響是大量消耗機房的出口總帶寬郭卫。不管防火墻處理能力有多強,當出口帶寬被耗盡時猪狈,整個業(yè)務(wù)在用戶看來就是不可用的,因為用戶的正常請求已經(jīng)無法到達系統(tǒng)了辩恼。防火墻能夠保證內(nèi)部系統(tǒng)不受沖擊雇庙,但用戶也是進不來的。對于用戶來說灶伊,業(yè)務(wù)都已經(jīng)受到影響了疆前,至于是因為用戶自己進不去,還是因為系統(tǒng)出故障聘萨,用戶其實根本不會關(guān)心竹椒。
基于上述原因,互聯(lián)網(wǎng)系統(tǒng)的架構(gòu)安全目前并沒有太好的設(shè)計手段來實現(xiàn)米辐,更多地是依靠運營商或者云服務(wù)商強大的帶寬和流量清洗的能力胸完,較少自己來設(shè)計和實現(xiàn)。
規(guī)模
很多企業(yè)級的系統(tǒng)翘贮,既沒有高性能要求赊窥,也沒有雙中心高可用要求,也不需要什么擴展性狸页,但往往這樣的系統(tǒng)通常很復(fù)雜锨能!因為這樣的系統(tǒng)往往功能特別多,邏輯分支特別多芍耘。特別是有的系統(tǒng)址遇,發(fā)展時間比較長,不斷地往上面疊加功能斋竞,后來的人由于不熟悉整個發(fā)展歷史倔约,可能連很多功能的應(yīng)用場景都不清楚,或者細節(jié)根本無法掌握坝初,面對的就是一個黑盒系統(tǒng)跺株,看不懂复濒、改不動、不敢改乒省、修不了巧颈,復(fù)雜度自然就感覺很高了。
規(guī)模帶來復(fù)雜度的主要原因就是“量變引起質(zhì)變”袖扛,當數(shù)量超過一定的閾值后砸泛,復(fù)雜度會發(fā)生質(zhì)的變化。常見的規(guī)模帶來的復(fù)雜度有:
1. 功能越來越多蛆封,導(dǎo)致系統(tǒng)復(fù)雜度指數(shù)級上升
例如唇礁,某個系統(tǒng)開始只有 3 大功能,后來不斷增加到 8 大功能惨篱,雖然還是同一個系統(tǒng)盏筐,但復(fù)雜度已經(jīng)相差很大了。
下面以一個簡單的抽象模型來計算一下砸讳,假設(shè)系統(tǒng)間的功能都是兩兩相關(guān)的琢融,系統(tǒng)的復(fù)雜度 = 功能數(shù)量 + 功能之間的連接數(shù)量,通過計算我們可以看出:
3 個功能的系統(tǒng)復(fù)雜度 = 3 + 3 = 6
8 個功能的系統(tǒng)復(fù)雜度 = 8 + 28 = 36
可以看出簿寂,具備 8 個功能的系統(tǒng)的復(fù)雜度不是比具備 3 個功能的系統(tǒng)的復(fù)雜度多 5漾抬,而是多了 30,基本是指數(shù)級增長的常遂,主要原因在于隨著系統(tǒng)功能數(shù)量增多纳令,功能之間的連接呈指數(shù)級增長。下圖形象地展示了功能數(shù)量的增多帶來了復(fù)雜度克胳。
通過肉眼就可以很直觀地看出平绩,具備 8 個功能的系統(tǒng)復(fù)雜度要高得多。
2. 數(shù)據(jù)越來越多漠另,系統(tǒng)復(fù)雜度發(fā)生質(zhì)變
與功能類似馒过,系統(tǒng)數(shù)據(jù)越來越多時,也會由量變帶來質(zhì)變酗钞,最近幾年火熱的“大數(shù)據(jù)”就是在這種背景下誕生的腹忽。大數(shù)據(jù)單獨成為了一個熱門的技術(shù)領(lǐng)域,主要原因就是數(shù)據(jù)太多以后砚作,傳統(tǒng)的數(shù)據(jù)收集窘奏、加工、存儲葫录、分析的手段和工具已經(jīng)無法適應(yīng)着裹,必須應(yīng)用新的技術(shù)才能解決。目前的大數(shù)據(jù)理論基礎(chǔ)是 Google 發(fā)表的三篇大數(shù)據(jù)相關(guān)論文米同,其中 Google File System 是大數(shù)據(jù)文件存儲的技術(shù)理論骇扇,Google Bigtable 是列式數(shù)據(jù)存儲的技術(shù)理論摔竿,Google MapReduce 是大數(shù)據(jù)運算的技術(shù)理論,這三篇技術(shù)論文各自開創(chuàng)了一個新的技術(shù)領(lǐng)域少孝。
即使我們的數(shù)據(jù)沒有達到大數(shù)據(jù)規(guī)模继低,數(shù)據(jù)的增長也可能給系統(tǒng)帶來復(fù)雜性。最典型的例子莫過于使用關(guān)系數(shù)據(jù)庫存儲數(shù)據(jù)稍走,以 MySQL 為例袁翁,MySQL 單表的數(shù)據(jù)因不同的業(yè)務(wù)和應(yīng)用場景會有不同的最優(yōu)值,但不管怎樣都肯定是有一定的限度的婿脸,一般推薦在 5000 萬行左右粱胜。如果因為業(yè)務(wù)的發(fā)展,單表數(shù)據(jù)達到了 10 億行狐树,就會產(chǎn)生很多問題焙压,例如:
添加索引會很慢,可能需要幾個小時抑钟,這幾個小時內(nèi)數(shù)據(jù)庫表是無法插入數(shù)據(jù)的涯曲,相當于業(yè)務(wù)停機了。
修改表結(jié)構(gòu)和添加索引存在類似的問題味赃,耗時可能會很長掀抹。
即使有索引虐拓,索引的性能也可能會很低心俗,因為數(shù)據(jù)量太大。
數(shù)據(jù)庫備份耗時很長蓉驹。
……
因此城榛,當 MySQL 單表數(shù)據(jù)量太大時,我們必須考慮將單表拆分為多表态兴,這個拆分過程也會引入更多復(fù)雜性狠持,例如:
- 拆表的規(guī)則是什么?
以用戶表為例:是按照用戶 id 拆分表瞻润,還是按照用戶注冊時間拆表喘垂?
- 拆完表后查詢?nèi)绾翁幚恚?/li>
以用戶表為例:假設(shè)按照用戶 id 拆表,當業(yè)務(wù)需要查詢學(xué)歷為“本科”以上的用戶時绍撞,要去很多表查詢才能得到最終結(jié)果正勒,怎么保證性能?