J大數(shù)據(jù)是什么,大數(shù)據(jù)如同少年談性,都好像很明白的樣子,但是誰都不怎么明白。 有人說大數(shù)據(jù)就是大量海量數(shù)據(jù)處理。是嗎?我說這樣理解可能有點片面。 在此我舉兩個小例子,希望有助于對于這個概念能做一定的闡述。 例 1: 當(dāng)你有一天在樹林里面運送一塊大木樁,你想一次性運回農(nóng)場,你牽一頭牛來,這頭牛來運輸這塊木頭,拉的動嗎,可以 當(dāng)你有一天有10塊大木樁,你還牽頭牛來,它拉得動嗎,可能也拉的動,但是它會比較費力,效率會低一點,但是它還是能完成任務(wù)。 當(dāng)你有一天有50塊大木樁,你還牽頭牛來,它拉得動嗎,拉不動,為什么,50塊木樁的重量超過了它的負(fù)載能力,在這種情況下,這50塊木頭對于這頭牛來說就是一個大數(shù)據(jù)。 例 2: NASA美國航空航天總局需要24小時內(nèi)完成對月球上面?zhèn)鬏敾貋淼臄?shù)據(jù)進(jìn)行計算分析,于是部署了一臺計算機(jī),24小時內(nèi)完成了 突然,有一天,領(lǐng)導(dǎo)一上班說,我需要今天下班前得到當(dāng)天數(shù)據(jù)報告,大家就慌了,因為正常那個部署的計算機(jī)需要16小時完成。在這種情況的,在8小時內(nèi)完成對正常一天數(shù)據(jù)量的分析對于那臺計算機(jī)來就是大數(shù)據(jù)。 那對于這兩個例子,當(dāng)遇到大數(shù)據(jù)情況下,解決方案是什么呢? 在例一的情況下,你有兩個選擇。第一,牽來一頭大象,大象一次就能拉80個大木樁,50個對于它來說綽綽有余。第二,牽來五頭牛,一樣可以順利完成任務(wù)。 在例二的情況下,你同樣有兩個選擇,立刻把數(shù)據(jù)分析計算程序部署到一臺超級計算機(jī)上面,譬如中國的天河-2,美國的Cray,這樣可能一下子數(shù)據(jù)就能出來,或者你說我把程序部署到3臺同等級別計算機(jī)上面,利用這3臺計算機(jī)的計算能力來完成任務(wù)。 那么問題來了,從成本上面來說哪個合算,大家會驚訝的發(fā)現(xiàn),在同樣完成任務(wù)的情況下,五頭牛的成本比一頭大象成本小很多,而三臺普通計算機(jī)比一臺超級計算機(jī)成本小很多。而那五頭牛和三臺計算機(jī),在協(xié)力合作的條件下,完成了對于任何一個單元都不可能完成的任務(wù),這就是一個簡單的分布式系統(tǒng) (Distributed system)的例子,而每個單元可以從廣義上稱之為一個微服務(wù)(MicroService)。 微服務(wù),一個最近被炒的很火的名字,那他到底是個什么東西呢? 微服務(wù)沒有一個精確的定義,可以說這是一種軟件架構(gòu)風(fēng)格,利用模組化的方式組合出復(fù)雜的大型應(yīng)用程序,各功能區(qū)塊使用與語言無關(guān) (Language agnostic) 的 API 集相互通訊,而實現(xiàn)方法也多種多樣,每個公司使用微服務(wù)的出發(fā)點也不盡相同。但是微服務(wù)卻有幾個重要的共同特點: 1. 小而單一 (small and single resposibility),并且專注于做一件事情,只負(fù)責(zé)一個系統(tǒng)下的某一個功能。 譬如我們在第一個例子中的一頭牛,他只做一件事情,那就是拉車運輸,而且他做的很好。而你作為趕車的,也可以是整個運輸系統(tǒng)中的一個微服務(wù),你也負(fù)責(zé)一件事件,就是這幾頭牛都走同一方向,而且方向正確,你并不負(fù)責(zé)拉車。 在初步劃分模塊的時候,通常公司可以按照自己的業(yè)務(wù)領(lǐng)域來分塊服務(wù),一個典型的例子就是垂直電商系統(tǒng)一般可以分塊為用戶模塊服務(wù) Customer Service, 產(chǎn)品模塊服務(wù) Product Service, 訂單模塊服務(wù) Order Service, 支付模塊服務(wù) Payment Service 和 運送模塊服務(wù)Shipping Service,每一個服務(wù)只負(fù)責(zé)一個領(lǐng)域模型中所需要完成的任務(wù)。這樣輕松實現(xiàn)整個微服務(wù)系統(tǒng)的松耦合和較高的維護(hù)能力。 2. 獨立部署 (independently deployable),升級,擴(kuò)展或者替換 每個服務(wù)都可以單獨部署及重新部署而不影響整個系統(tǒng)。這使得服務(wù)很容易升級。 在此我們可以對比一下單體應(yīng)用(monolithic application)。譬如上文中提到的垂直電商系統(tǒng),在單體應(yīng)用下,所有這些模塊都是打包在同一個WAR,或者EAR文件下面,部署到一個應(yīng)用服務(wù)器上面,這個應(yīng)用服務(wù)器可以Web應(yīng)用服務(wù)器,譬如TOMCAT,或者是J2EE應(yīng)用服務(wù)器,譬如WebLogic, IBAM WebSpeher或者是Jboss。 通常在這樣架構(gòu)下,當(dāng)我們需要替換,升級,或者一個簡單的修改某一個模塊,譬如支付模塊的話,我們需要怎么做?修改支付模塊代碼,編譯整個項目,重新打包成一個WAR,EAR文件,然后替換整個應(yīng)用系統(tǒng)。即使我們修改的模塊和其他模塊沒有任何關(guān)系,但是,我們必須一起替換。這就增加了我們?nèi)粘5墓ぷ髁亢惋L(fēng)險,譬如測試方便,除了做單元測試,我們還需要做一個集成測試,來保持我們其他模塊一樣工作;風(fēng)險就是如果是一個架構(gòu)不是很好的軟件,軟件個模塊之間沒實現(xiàn)松耦合,那么修改一個模塊,很有可能導(dǎo)致另外一個模塊的不工作,別告訴我你沒有遇到過,當(dāng)你是一個新人,加入一個開發(fā)組,team leader告訴你,把支付模塊一個bug修了,你廢了九牛二虎之力,很開心的修完了那個bug,通過單元測試,提交了代碼,過了一會一封郵件過來,jenkins上面出錯了,某一個和支付模塊完全不相關(guān)的用戶管理模塊出錯了。是誰的錯,不是你的錯,可能是架構(gòu)師沒有架構(gòu)好軟件,但是通常情況下,你得負(fù)責(zé)。 而微服務(wù)的獨立部署能力就是為了避免這樣類似的問題再出現(xiàn),通常一個微服務(wù)是領(lǐng)域驅(qū)動設(shè)計下完成的,各模塊之間有非常清楚明晰的邊界。 再拿第一個例子來說,你趕著五頭牛運送木樁,突然有一頭牛脫水倒下了,這個時候你并不荒,打個電話到農(nóng)場,給你再牽一頭或者是牛,或者是驢,或者是馬,你很輕松的就替換了那頭倒下的牛,而且對于其他幾頭牛并沒有影響,他們還是可以繼續(xù)安全的工作。 那么有人會說,那怎么從一個單體應(yīng)用,轉(zhuǎn)換成一個成功,松耦合,易于升級和擴(kuò)展的微服務(wù)架構(gòu)的,這有一個非常有趣的話題,包括很多方面的考慮,從領(lǐng)域驅(qū)動設(shè)計,到技術(shù)選擇和實現(xiàn),到怎么一步一步分解一個巨大而復(fù)雜的單體應(yīng)用,到一個個微服務(wù),以及各個微服務(wù)之間的通信選擇,畢竟當(dāng)你擁有200個微服務(wù)的時候,微服務(wù)之間的通信已經(jīng)不是簡單的進(jìn)程內(nèi)呼叫了,而是通過網(wǎng)絡(luò)協(xié)議來實現(xiàn)的,穩(wěn)定性和性能都會有影響。 3. 輕量級通信協(xié)議 (lightweight communication protocol) 最常用的是HTTP協(xié)議下的REST,或者M(jìn)essage機(jī)制,譬如JMS, 或者AMQP (Advanced Message Queuing Protocol) 由于每個微服務(wù)都是一個獨立的應(yīng)用程序,這個獨立程序可以部署在同一個,或者不同的服務(wù)器上面,從java程序角度來講,每一個微服務(wù)就是一個java進(jìn)程。所以服務(wù)之間的通信就不再是一個進(jìn)程內(nèi)的呼叫。我們就需要一個輕量級通信協(xié)議來完成各個分布式服務(wù)之間的通信。而這種通信可以分為兩種,同步和異步。當(dāng)我們需要一個同步呼叫來完成一個業(yè)務(wù)邏輯,通常會通過HTTP下的REST API來實現(xiàn),通??梢赃x擇Spring下的Restful框架或者是Oracle下的JAX-RS。而當(dāng)我們需要服務(wù)之間做異步通信時,Message會是一個很好的協(xié)議。 Java微服務(wù)應(yīng)用程序之間可以使用非常成熟的JMS,如果是Java和非Java程序應(yīng)用之間,現(xiàn)在比較流行的是AMQP協(xié)議。 4. 去中心化數(shù)據(jù)管理 (decentralized data management) 多樣化持久性(Polyglot Persistence),即讓每一個微服務(wù)都有其自己的數(shù)據(jù)庫,并且允許其各自擁有不同類型的數(shù)據(jù)持久化特性一直是微服務(wù)架構(gòu)所倡導(dǎo)的。 當(dāng)我們開發(fā)一個企業(yè)化大型應(yīng)用時,我們通常會發(fā)現(xiàn),數(shù)據(jù)的類型,屬性和被查詢和修改的頻率都會不一樣,而傳統(tǒng)的單體應(yīng)用下,我們通常會使用一個中心數(shù)據(jù)庫,來存儲所有數(shù)據(jù)。譬如一個垂直電商的應(yīng)用里面可以有客戶信息數(shù)據(jù),商品數(shù)據(jù),購物車數(shù)據(jù),訂單數(shù)據(jù),支付數(shù)據(jù)。單體應(yīng)用下,我們很可能就使用一個MYSQL數(shù)據(jù)庫就解決所有問題。而微服務(wù)框架下,允許也提倡每一個服務(wù)模塊下?lián)碛凶约旱臄?shù)據(jù)庫,這個數(shù)據(jù)庫可以是SQL類型的數(shù)據(jù)庫,譬如Oracle,MYSQL,Postgres等等,也可以是NOSQL類型數(shù)據(jù)庫,譬如MongoDB,Cassandra, Amazon DynamoDB等等,當(dāng)然你也可以根據(jù)你的數(shù)據(jù)類型,在NOSQL里面來選擇哪種類型的數(shù)據(jù)庫。那么說我們就不能讓兩個或多個微服務(wù)之間共享一個數(shù)據(jù)庫了嗎,個人認(rèn)為是不提倡,但是也不反對,具體情況具體分析。譬如當(dāng)你需要一個request call里面的多個數(shù)據(jù)持久化在一個事務(wù)內(nèi)完成,在這種情況下,通常一個SQL數(shù)據(jù)庫會讓事情變得簡單。譬如當(dāng)你擔(dān)心數(shù)據(jù)的一致性能否得到保障,而且要達(dá)到ACID級別時,可能分布式數(shù)據(jù)管理會變得不可能。當(dāng)然如果你一定要分布式管理數(shù)據(jù)的話,可以通過最終一致性(Eventual Consistency)來做。實現(xiàn)數(shù)據(jù)的強(qiáng)一致性,強(qiáng)最終一致性,還是最終一致性一直是分布式計算下的一個難題。這也是我們在設(shè)計微服務(wù)架構(gòu)時可能會遇到也需要考慮的問題。 5. 公共設(shè)施自動化 (Infrastructure Automation) 通過采用一系列的開源軟件,自動化開發(fā),測試,部署流程,可以大大提高產(chǎn)品的質(zhì)量和交付能力。 在決定是否要采用微服務(wù)架構(gòu)前,應(yīng)該考慮團(tuán)隊是否有足夠的經(jīng)驗在公共設(shè)施自動化方面。實戰(zhàn)用例告訴我們,那些在微服務(wù)系統(tǒng)上面取得成功的團(tuán)隊都擁有豐富的連續(xù)集成和連續(xù)交付能力。這涉及到一連串的自動化能力,包括編譯,單元測試,功能測試,集成測試,用戶體驗測試和性能測試上面的自動化,包括部署自動化。我們只有通過做大量的自動化測試,才能大大的增強(qiáng)團(tuán)隊的信心。因為當(dāng)我們采用微服務(wù)架構(gòu)時,我們所要處理的不是一個單體應(yīng)用所帶來的問題,而且?guī)资畟€,幾百個微服務(wù),甚至是部署在上百個服務(wù)器上面,到那時候我們再考慮自動化,可能未免太晚了。 這邊也值得聽一下亞馬遜云服務(wù)團(tuán)隊一直倡導(dǎo)的兩個微服務(wù)開發(fā)的原則: 1. Two Pizza Size 就是說每一個團(tuán)隊只需要定兩個Pizza就能吃飽,當(dāng)然這邊是指美式Pizza,不是意大利 Pizza,基本就是說一個團(tuán)隊在6 - 10 人之間,這也完全符合一個敏捷開發(fā)團(tuán)體的個數(shù)。 2. You Build It, You Run It 是指誰開發(fā)和編譯的軟件,誰來運行。這也就是為什么亞馬遜每一個團(tuán)隊成員都會輪流On Call,這也是被很多亞馬遜員工所批評的。 不管怎么樣我們從這兩個原則可以看到在采用微服務(wù)架構(gòu)時候可以采用的方法,每一個團(tuán)隊負(fù)責(zé)一個或者多個微服務(wù),采用自動化的編譯,測試,集成,部署,檢測開源工具,讓這個流程變得很boring,大大提高交付能力。而且負(fù)責(zé)開發(fā)的團(tuán)隊當(dāng)然對于軟件是最熟悉的,一旦出現(xiàn)什么問題,可以立即就能找到根源和解決,而不是需要通過復(fù)雜的部門之間的溝通再來解決問題。 這期我們從大數(shù)據(jù),分布式系統(tǒng),談到了當(dāng)前非常流行的微服務(wù)架構(gòu)以及其共享的一些重要特征。當(dāng)然,當(dāng)你真正開始著手開始把一個單體應(yīng)用變?yōu)橐幌盗形⒎?wù)時,所需要面臨的挑戰(zhàn)還有很多,譬如怎么來對你已經(jīng)存在的碩大的單體應(yīng)用來解體;譬如當(dāng)你成功解體到一系列的微服務(wù)后,怎么來解決由于分布式結(jié)構(gòu)導(dǎo)致的系統(tǒng)性能問題;譬如當(dāng)你實現(xiàn)了多樣持久化后,發(fā)現(xiàn)事務(wù)處理變得積極復(fù)雜,怎么來管理分布式系統(tǒng)下的數(shù)據(jù),保證數(shù)據(jù)一致性,等等。這些我們希望會在接下來幾期進(jìn)行討論。 |
|