大數(shù)據(jù)是什么,大數(shù)據(jù)如同少年談性,都好像很明白的樣子漩仙,但是誰都不怎么明白露该。
有人說大數(shù)據(jù)就是大量海量數(shù)據(jù)處理册倒。是嗎西雀?我說這樣理解可能有點(diǎn)片面萨驶。
在此我舉兩個(gè)小例子,希望有助于對(duì)于這個(gè)概念能做一定的闡述艇肴。
例 1:
當(dāng)你有一天在樹林里面運(yùn)送一塊大木樁,你想一次性運(yùn)回農(nóng)場育谬,你牽一頭牛來,這頭牛來運(yùn)輸這塊木頭帮哈,拉的動(dòng)嗎膛檀,可以
當(dāng)你有一天有10塊大木樁,你還牽頭牛來咖刃,它拉得動(dòng)嗎憾筏,可能也拉的動(dòng),但是它會(huì)比較費(fèi)力氧腰,效率會(huì)低一點(diǎn),但是它還是能完成任務(wù)箩帚。
當(dāng)你有一天有50塊大木樁黄痪,你還牽頭牛來,它拉得動(dòng)嗎桅打,拉不動(dòng),為什么鹅搪,50塊木樁的重量超過了它的負(fù)載能力潦嘶,在這種情況下崇众,這50塊木頭對(duì)于這頭牛來說就是一個(gè)大數(shù)據(jù)航厚。
例 2:
NASA美國航空航天總局需要24小時(shí)內(nèi)完成對(duì)月球上面?zhèn)鬏敾貋淼臄?shù)據(jù)進(jìn)行計(jì)算分析,于是部署了一臺(tái)計(jì)算機(jī)眯漩,24小時(shí)內(nèi)完成了
突然麻顶,有一天,領(lǐng)導(dǎo)一上班說队萤,我需要今天下班前得到當(dāng)天數(shù)據(jù)報(bào)告矫钓,大家就慌了,因?yàn)檎D莻€(gè)部署的計(jì)算機(jī)需要16小時(shí)完成新娜。在這種情況的概龄,在8小時(shí)內(nèi)完成對(duì)正常一天數(shù)據(jù)量的分析對(duì)于那臺(tái)計(jì)算機(jī)來就是大數(shù)據(jù)。
那對(duì)于這兩個(gè)例子私杜,當(dāng)遇到大數(shù)據(jù)情況下,解決方案是什么呢嚎幸?
在例一的情況下寄猩,你有兩個(gè)選擇。第一田篇,牽來一頭大象箍铭,大象一次就能拉80個(gè)大木樁,50個(gè)對(duì)于它來說綽綽有余诈火。第二,牽來五頭牛刀崖,一樣可以順利完成任務(wù)。
在例二的情況下馆截,你同樣有兩個(gè)選擇蜂莉,立刻把數(shù)據(jù)分析計(jì)算程序部署到一臺(tái)超級(jí)計(jì)算機(jī)上面,譬如中國的天河-2窖张,美國的Cray蚁滋,這樣可能一下子數(shù)據(jù)就能出來,或者你說我把程序部署到3臺(tái)同等級(jí)別計(jì)算機(jī)上面澄阳,利用這3臺(tái)計(jì)算機(jī)的計(jì)算能力來完成任務(wù)踏拜。
那么問題來了,從成本上面來說哪個(gè)合算肮塞,大家會(huì)驚訝的發(fā)現(xiàn)姻锁,在同樣完成任務(wù)的情況下,五頭牛的成本比一頭大象成本小很多拷窜,而三臺(tái)普通計(jì)算機(jī)比一臺(tái)超級(jí)計(jì)算機(jī)成本小很多涧黄。而那五頭牛和三臺(tái)計(jì)算機(jī),在協(xié)力合作的條件下懊昨,完成了對(duì)于任何一個(gè)單元都不可能完成的任務(wù)春宣,這就是一個(gè)簡單的分布式系統(tǒng) (Distributed system)的例子嫉你,而每個(gè)單元可以從廣義上稱之為一個(gè)微服務(wù)(MicroService)躏惋。
微服務(wù),一個(gè)最近被炒的很火的名字油挥,那他到底是個(gè)什么東西呢款熬?
微服務(wù)沒有一個(gè)精確的定義,可以說這是一種軟件架構(gòu)風(fēng)格惋鹅,利用模組化的方式組合出復(fù)雜的大型應(yīng)用程序殉簸,各功能區(qū)塊使用與語言無關(guān) (Language agnostic) 的 API 集相互通訊般卑,而實(shí)現(xiàn)方法也多種多樣,每個(gè)公司使用微服務(wù)的出發(fā)點(diǎn)也不盡相同蝠检。但是微服務(wù)卻有幾個(gè)重要的共同特點(diǎn):
1. 小而單一 (small and single resposibility)叹谁,并且專注于做一件事情,只負(fù)責(zé)一個(gè)系統(tǒng)下的某一個(gè)功能焰檩。
? ? 譬如我們在第一個(gè)例子中的一頭牛析苫,他只做一件事情,那就是拉車運(yùn)輸衩侥,而且他做的很好顿乒。而你作為趕車的泽谨,也可以是整個(gè)運(yùn)輸系統(tǒng)中的一個(gè)微服務(wù)特漩,你也負(fù)責(zé)一件事件骨杂,就是這幾頭牛都走同一方向,而且方向正確蛤售,你并不負(fù)責(zé)拉車妒潭。
? ?在初步劃分模塊的時(shí)候,通常公司可以按照自己的業(yè)務(wù)領(lǐng)域來分塊服務(wù)漠酿,一個(gè)典型的例子就是垂直電商系統(tǒng)一般可以分塊為用戶模塊服務(wù) Customer Service, 產(chǎn)品模塊服務(wù) Product Service, 訂單模塊服務(wù) Order Service, 支付模塊服務(wù) Payment Service 和 運(yùn)送模塊服務(wù)Shipping Service谎亩,每一個(gè)服務(wù)只負(fù)責(zé)一個(gè)領(lǐng)域模型中所需要完成的任務(wù)。這樣輕松實(shí)現(xiàn)整個(gè)微服務(wù)系統(tǒng)的松耦合和較高的維護(hù)能力匈庭。
2. 獨(dú)立部署 (independently deployable),升級(jí)夭拌,擴(kuò)展或者替換
? ? 每個(gè)服務(wù)都可以單獨(dú)部署及重新部署而不影響整個(gè)系統(tǒng)紊选。這使得服務(wù)很容易升級(jí)。
? ?在此我們可以對(duì)比一下單體應(yīng)用(monolithic application)兵罢。譬如上文中提到的垂直電商系統(tǒng),在單體應(yīng)用下巩那,所有這些模塊都是打包在同一個(gè)WAR此蜈,或者EAR文件下面,部署到一個(gè)應(yīng)用服務(wù)器上面东囚,這個(gè)應(yīng)用服務(wù)器可以Web應(yīng)用服務(wù)器战授,譬如TOMCAT,或者是J2EE應(yīng)用服務(wù)器份帐,譬如WebLogic, IBAM WebSpeher或者是Jboss畜挨。 通常在這樣架構(gòu)下噩凹,當(dāng)我們需要替換,升級(jí)务冕,或者一個(gè)簡單的修改某一個(gè)模塊幻赚,譬如支付模塊的話,我們需要怎么做箩退?修改支付模塊代碼佳谦,編譯整個(gè)項(xiàng)目钻蔑,重新打包成一個(gè)WAR,EAR文件咪笑,然后替換整個(gè)應(yīng)用系統(tǒng)窗怒。即使我們修改的模塊和其他模塊沒有任何關(guān)系,但是扬虚,我們必須一起替換辜昵。這就增加了我們?nèi)粘5墓ぷ髁亢惋L(fēng)險(xiǎn),譬如測試方便贷洲,除了做單元測試,我們還需要做一個(gè)集成測試,來保持我們其他模塊一樣工作雁竞;風(fēng)險(xiǎn)就是如果是一個(gè)架構(gòu)不是很好的軟件,軟件個(gè)模塊之間沒實(shí)現(xiàn)松耦合彪腔,那么修改一個(gè)模塊进栽,很有可能導(dǎo)致另外一個(gè)模塊的不工作快毛,別告訴我你沒有遇到過,當(dāng)你是一個(gè)新人唠帝,加入一個(gè)開發(fā)組襟衰,team leader告訴你,把支付模塊一個(gè)bug修了绍坝,你廢了九牛二虎之力苔悦,很開心的修完了那個(gè)bug,通過單元測試灾挨,提交了代碼竹宋,過了一會(huì)一封郵件過來,jenkins上面出錯(cuò)了秒拔,某一個(gè)和支付模塊完全不相關(guān)的用戶管理模塊出錯(cuò)了飒硅。是誰的錯(cuò),不是你的錯(cuò)庵芭,可能是架構(gòu)師沒有架構(gòu)好軟件,但是通常情況下眨唬,你得負(fù)責(zé)好乐。
? ? 而微服務(wù)的獨(dú)立部署能力就是為了避免這樣類似的問題再出現(xiàn)蔚万,通常一個(gè)微服務(wù)是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)下完成的,各模塊之間有非常清楚明晰的邊界昵慌。
? ? 再拿第一個(gè)例子來說版扩,你趕著五頭牛運(yùn)送木樁,突然有一頭牛脫水倒下了蜻韭,這個(gè)時(shí)候你并不荒柿扣,打個(gè)電話到農(nóng)場,給你再牽一頭或者是牛俯画,或者是驢司草,或者是馬埋虹,你很輕松的就替換了那頭倒下的牛,而且對(duì)于其他幾頭牛并沒有影響胰柑,他們還是可以繼續(xù)安全的工作。
? ? ?那么有人會(huì)說崩瓤,那怎么從一個(gè)單體應(yīng)用踩官,轉(zhuǎn)換成一個(gè)成功,松耦合肾扰,易于升級(jí)和擴(kuò)展的微服務(wù)架構(gòu)的蛋逾,這有一個(gè)非常有趣的話題区匣,包括很多方面的考慮蒋院,從領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),到技術(shù)選擇和實(shí)現(xiàn)姑丑,到怎么一步一步分解一個(gè)巨大而復(fù)雜的單體應(yīng)用辞友,到一個(gè)個(gè)微服務(wù),以及各個(gè)微服務(wù)之間的通信選擇留拾,畢竟當(dāng)你擁有200個(gè)微服務(wù)的時(shí)候痴柔,微服務(wù)之間的通信已經(jīng)不是簡單的進(jìn)程內(nèi)呼叫了疫向,而是通過網(wǎng)絡(luò)協(xié)議來實(shí)現(xiàn)的,穩(wěn)定性和性能都會(huì)有影響谈火。
3. 輕量級(jí)通信協(xié)議 (lightweight communication protocol)
? 最常用的是HTTP協(xié)議下的REST匙奴,或者M(jìn)essage機(jī)制,譬如JMS谍肤, 或者AMQP (Advanced Message Queuing Protocol)
? ? 由于每個(gè)微服務(wù)都是一個(gè)獨(dú)立的應(yīng)用程序荒揣,這個(gè)獨(dú)立程序可以部署在同一個(gè),或者不同的服務(wù)器上面恳蹲,從java程序角度來講俩滥,每一個(gè)微服務(wù)就是一個(gè)java進(jìn)程。所以服務(wù)之間的通信就不再是一個(gè)進(jìn)程內(nèi)的呼叫错忱。我們就需要一個(gè)輕量級(jí)通信協(xié)議來完成各個(gè)分布式服務(wù)之間的通信挂据。而這種通信可以分為兩種崎逃,同步和異步。當(dāng)我們需要一個(gè)同步呼叫來完成一個(gè)業(yè)務(wù)邏輯勒葱,通常會(huì)通過HTTP下的REST API來實(shí)現(xiàn)障贸,通常可以選擇Spring下的Restful框架或者是Oracle下的JAX-RS涩维。而當(dāng)我們需要服務(wù)之間做異步通信時(shí)袁波,Message會(huì)是一個(gè)很好的協(xié)議篷牌。 Java微服務(wù)應(yīng)用程序之間可以使用非常成熟的JMS,如果是Java和非Java程序應(yīng)用之間戳杀,現(xiàn)在比較流行的是AMQP協(xié)議。
4. 去中心化數(shù)據(jù)管理 (decentralized data management)
?多樣化持久性(Polyglot Persistence)隔缀,即讓每一個(gè)微服務(wù)都有其自己的數(shù)據(jù)庫傍菇,并且允許其各自擁有不同類型的數(shù)據(jù)持久化特性一直是微服務(wù)架構(gòu)所倡導(dǎo)的丢习。
? 當(dāng)我們開發(fā)一個(gè)企業(yè)化大型應(yīng)用時(shí),我們通常會(huì)發(fā)現(xiàn)揽思,數(shù)據(jù)的類型见擦,屬性和被查詢和修改的頻率都會(huì)不一樣,而傳統(tǒng)的單體應(yīng)用下,我們通常會(huì)使用一個(gè)中心數(shù)據(jù)庫执俩,來存儲(chǔ)所有數(shù)據(jù)癌刽。譬如一個(gè)垂直電商的應(yīng)用里面可以有客戶信息數(shù)據(jù)显拜,商品數(shù)據(jù),購物車數(shù)據(jù)矮固,訂單數(shù)據(jù)譬淳,支付數(shù)據(jù)邻梆。單體應(yīng)用下,我們很可能就使用一個(gè)MYSQL數(shù)據(jù)庫就解決所有問題尼摹。而微服務(wù)框架下,允許也提倡每一個(gè)服務(wù)模塊下?lián)碛凶约旱臄?shù)據(jù)庫玄呛,這個(gè)數(shù)據(jù)庫可以是SQL類型的數(shù)據(jù)庫惠赫,譬如Oracle儿咱,MYSQL,Postgres等等怠缸,也可以是NOSQL類型數(shù)據(jù)庫钳宪,譬如MongoDB吏颖,Cassandra, Amazon DynamoDB等等,當(dāng)然你也可以根據(jù)你的數(shù)據(jù)類型疚俱,在NOSQL里面來選擇哪種類型的數(shù)據(jù)庫缩多。那么說我們就不能讓兩個(gè)或多個(gè)微服務(wù)之間共享一個(gè)數(shù)據(jù)庫了嗎衬吆,個(gè)人認(rèn)為是不提倡,但是也不反對(duì)逊抡,具體情況具體分析冒嫡。譬如當(dāng)你需要一個(gè)request call里面的多個(gè)數(shù)據(jù)持久化在一個(gè)事務(wù)內(nèi)完成,在這種情況下潜秋,通常一個(gè)SQL數(shù)據(jù)庫會(huì)讓事情變得簡單峻呛。譬如當(dāng)你擔(dān)心數(shù)據(jù)的一致性能否得到保障,而且要達(dá)到ACID級(jí)別時(shí)寨躁,可能分布式數(shù)據(jù)管理會(huì)變得不可能牙勘。當(dāng)然如果你一定要分布式管理數(shù)據(jù)的話方面,可以通過最終一致性(Eventual Consistency)來做。實(shí)現(xiàn)數(shù)據(jù)的強(qiáng)一致性恭金,強(qiáng)最終一致性操禀,還是最終一致性一直是分布式計(jì)算下的一個(gè)難題。這也是我們在設(shè)計(jì)微服務(wù)架構(gòu)時(shí)可能會(huì)遇到也需要考慮的問題横腿。
5. 公共設(shè)施自動(dòng)化 (Infrastructure Automation)
?通過采用一系列的開源軟件颓屑,自動(dòng)化開發(fā),測試耿焊,部署流程揪惦,可以大大提高產(chǎn)品的質(zhì)量和交付能力。
? 在決定是否要采用微服務(wù)架構(gòu)前罗侯,應(yīng)該考慮團(tuán)隊(duì)是否有足夠的經(jīng)驗(yàn)在公共設(shè)施自動(dòng)化方面丹擎。實(shí)戰(zhàn)用例告訴我們,那些在微服務(wù)系統(tǒng)上面取得成功的團(tuán)隊(duì)都擁有豐富的連續(xù)集成和連續(xù)交付能力。這涉及到一連串的自動(dòng)化能力再愈,包括編譯榜苫,單元測試,功能測試翎冲,集成測試垂睬,用戶體驗(yàn)測試和性能測試上面的自動(dòng)化,包括部署自動(dòng)化抗悍。我們只有通過做大量的自動(dòng)化測試驹饺,才能大大的增強(qiáng)團(tuán)隊(duì)的信心。因?yàn)楫?dāng)我們采用微服務(wù)架構(gòu)時(shí)缴渊,我們所要處理的不是一個(gè)單體應(yīng)用所帶來的問題赏壹,而且?guī)资畟€(gè),幾百個(gè)微服務(wù)衔沼,甚至是部署在上百個(gè)服務(wù)器上面蝌借,到那時(shí)候我們再考慮自動(dòng)化昔瞧,可能未免太晚了。
? 這邊也值得聽一下亞馬遜云服務(wù)團(tuán)隊(duì)一直倡導(dǎo)的兩個(gè)微服務(wù)開發(fā)的原則:
? ?1. Two Pizza Size
? ? ? ? 就是說每一個(gè)團(tuán)隊(duì)只需要定兩個(gè)Pizza就能吃飽菩佑,當(dāng)然這邊是指美式Pizza自晰,不是意大利 ? Pizza,基本就是說一個(gè)團(tuán)隊(duì)在6 - 10 人之間稍坯,這也完全符合一個(gè)敏捷開發(fā)團(tuán)體的個(gè)數(shù)酬荞。
? ?2. ?You Build It, You Run It
? ? ? ? 是指誰開發(fā)和編譯的軟件,誰來運(yùn)行瞧哟。這也就是為什么亞馬遜每一個(gè)團(tuán)隊(duì)成員都會(huì)輪流On Call混巧,這也是被很多亞馬遜員工所批評(píng)的。
? ? 不管怎么樣我們從這兩個(gè)原則可以看到在采用微服務(wù)架構(gòu)時(shí)候可以采用的方法绢涡,每一個(gè)團(tuán)隊(duì)負(fù)責(zé)一個(gè)或者多個(gè)微服務(wù)牲剃,采用自動(dòng)化的編譯,測試雄可,集成凿傅,部署,檢測開源工具数苫,讓這個(gè)流程變得很boring聪舒,大大提高交付能力。而且負(fù)責(zé)開發(fā)的團(tuán)隊(duì)當(dāng)然對(duì)于軟件是最熟悉的虐急,一旦出現(xiàn)什么問題箱残,可以立即就能找到根源和解決,而不是需要通過復(fù)雜的部門之間的溝通再來解決問題止吁。
? 這期我們從大數(shù)據(jù)被辑,分布式系統(tǒng),談到了當(dāng)前非常流行的微服務(wù)架構(gòu)以及其共享的一些重要特征敬惦。當(dāng)然盼理,當(dāng)你真正開始著手開始把一個(gè)單體應(yīng)用變?yōu)橐幌盗形⒎?wù)時(shí),所需要面臨的挑戰(zhàn)還有很多俄删,譬如怎么來對(duì)你已經(jīng)存在的碩大的單體應(yīng)用來解體宏怔;譬如當(dāng)你成功解體到一系列的微服務(wù)后,怎么來解決由于分布式結(jié)構(gòu)導(dǎo)致的系統(tǒng)性能問題畴椰;譬如當(dāng)你實(shí)現(xiàn)了多樣持久化后臊诊,發(fā)現(xiàn)事務(wù)處理變得積極復(fù)雜,怎么來管理分布式系統(tǒng)下的數(shù)據(jù)斜脂,保證數(shù)據(jù)一致性抓艳,等等。這些我們希望會(huì)在接下來幾期進(jìn)行討論帚戳。