中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

管理微服務(wù)中的數(shù)據(jù)

2018-08-16    來源:raincent

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

核心要點(diǎn)

• Stitch Fix是一家服裝零售商,他們所雇傭的數(shù)據(jù)科學(xué)家基本上和工程師的數(shù)量持平。數(shù)據(jù)科學(xué)家在算法方面的工作對(duì)公司的成功至關(guān)重要,而他們的成功則依賴于大量的數(shù)據(jù)。

• 盡管微服務(wù)對(duì)于實(shí)現(xiàn)高擴(kuò)展性的解決方案是非常必要的,但是應(yīng)該在公司取得足夠成功,微服務(wù)是真正合理且必要時(shí),再去接觸高度分布式系統(tǒng)的復(fù)雜性。

• 現(xiàn)在所有采用微服務(wù)的公司,包括eBay、Twitter和Amazon.com,都經(jīng)歷了從單體系統(tǒng)遷移的過程。

• 真正的微服務(wù)平臺(tái)需要每個(gè)微服務(wù)負(fù)責(zé)自己的數(shù)據(jù)。在微服務(wù)遷移的過程中,創(chuàng)建獨(dú)立的數(shù)據(jù)存儲(chǔ)是最有挑戰(zhàn)性的工作。

• 分拆單體數(shù)據(jù)庫時(shí),會(huì)涉及到一個(gè)重復(fù)的過程,也就是隔離每個(gè)服務(wù)的數(shù)據(jù),防止其他服務(wù)直接對(duì)數(shù)據(jù)進(jìn)行訪問。
 



本文根據(jù)QCon舊金山2017上Randy Shoup上的演講改編,他是Stitch Fix的工程副總裁(VP)。

我是Stitch Fix的工程副總裁Randy Shoup,根據(jù)我的背景,我會(huì)講解如何管理微服務(wù)中的數(shù)據(jù)的課程。

Stitch Fix是美國的一家服裝零售商,我們使用技術(shù)和數(shù)據(jù)科學(xué)幫助顧客查找他們喜歡的服裝。在Stitch Fix之前,我擔(dān)任過“流動(dòng)的CTO服務(wù)提供者(CTO as a service)”,幫助企業(yè)討論技術(shù)和他們的處境。

在職業(yè)生涯的早期,我曾經(jīng)在谷歌擔(dān)任Google App Engine的主管。這是谷歌的平臺(tái)即服務(wù),類似于Heroku、Cloud Foundry等等。我更早在eBay擔(dān)任了六年半的首席工程師,在那里我?guī)椭鷪F(tuán)隊(duì)建立了數(shù)代的搜索基礎(chǔ)設(shè)施。如果你曾經(jīng)用過eBay并且找到了你想要的東西,那說明我們的團(tuán)隊(duì)做的很棒。如果你沒有找到想要的東西的話,那你現(xiàn)在也應(yīng)該知道該將責(zé)任歸咎于誰了。

我們首先會(huì)簡要介紹一下Stitch Fix,因?yàn)檫@涉及到將單體拆分為微服務(wù)的經(jīng)驗(yàn)教訓(xùn)和技術(shù)。Stitch Fix與標(biāo)準(zhǔn)的服裝零售商截然不同。我們不是在線商店或者要求顧客到店里,如果有位專家專門為你做這些事情,那又是什么樣的體驗(yàn)?zāi)?

我們會(huì)要求你填寫一個(gè)非常詳細(xì)的個(gè)人風(fēng)格問卷,包括60到70個(gè)問題,大約需要20到30分鐘。我們會(huì)詢問你的體型、身高、體重、喜歡什么樣的風(fēng)格、你是否想要炫耀自己的手臂、是否希望將臀部藏起來……我們會(huì)問一些非常詳細(xì)和個(gè)人化的事情。為什么要這樣做呢?在生活中,能夠知道如何為你推薦衣服的人必須是了解你的人。我們明確地詢問這些問題并利用數(shù)據(jù)科學(xué)來實(shí)現(xiàn)我們的目標(biāo)。我們會(huì)為客戶投遞五件貨物,這些貨物是由全國范圍內(nèi)的3500名造型師中的某一位所挑選的。你可以選擇保留喜歡的貨物,付錢給我們,然后將其余的貨物免費(fèi)寄還給我們。

在幕后,人工和機(jī)器層面都會(huì)發(fā)生好多事情。在機(jī)器層面,我們每晚都會(huì)檢查每件庫存,參考每個(gè)客戶,計(jì)算出預(yù)期購買的可能性。換句話說,也就是針對(duì)我們發(fā)送給他的襯衣,計(jì)算Randy留下它的條件概率。設(shè)想一下,有72%的概率Randy會(huì)保留這件襯衫,54%的機(jī)會(huì)留下這條褲子,47%概率會(huì)留下這雙鞋,對(duì)于在座的每個(gè)人,百分比會(huì)有所不同。我們有一個(gè)機(jī)器學(xué)習(xí)模型,將其放到一個(gè)整體中計(jì)算這些百分比,它是由針對(duì)每個(gè)客戶的一組個(gè)性化推薦算法組成的,造型師會(huì)使用這些模型的結(jié)果。

造型師本質(zhì)是在為你購物,站在你的角度上選擇五件商品,他(或她)查看這些推薦算法并確定將哪些貨物放到郵寄給客戶的包裹中。

我們還需要人工將它們組合在一起,這是機(jī)器目前無法做到的。有時(shí)候,人類能夠回答“我將要去曼哈頓參加一個(gè)晚上舉行的婚禮,所以給我推薦一些合適的衣服”。機(jī)器不知道如何應(yīng)對(duì),但是人類知道機(jī)器所不知道的事情。

所有的這些都需要大量的數(shù)據(jù)。Stitch Fix的數(shù)據(jù)科學(xué)家和工程師的比例是一比一,這是非常有意思的,我相信也是獨(dú)一無二的。我們的團(tuán)隊(duì)中有一百多名軟件工程師,大約有八十位數(shù)據(jù)科學(xué)家和算法開發(fā)人員,他們從事所有數(shù)據(jù)科學(xué)的工作。據(jù)我所知,在行業(yè)內(nèi)這是一個(gè)獨(dú)一無二的比例。我不知道還有哪家公司能夠做到這種接近一比一的比例。

我們利用這些數(shù)據(jù)科學(xué)家都做些什么呢?事實(shí)證明,如果你足夠聰明,就會(huì)有回報(bào)。

我們對(duì)要購買的衣服也采用相同的技術(shù)。我們針對(duì)購買者運(yùn)行推薦算法,這些算法會(huì)判斷得出,下一季我們會(huì)購買更多的棉布衣服、露肩裝或緊身長褲。

我們將數(shù)據(jù)分析應(yīng)用到庫存管理中:我們要將哪些貨物放到哪個(gè)倉庫中等等。我們使用它來優(yōu)化物流和選擇運(yùn)輸公司,這樣的話,就能以最低的成本將貨物及時(shí)送達(dá)您的家中。我們還會(huì)做一些標(biāo)準(zhǔn)的事情,比如需求預(yù)測(cè)。

我們是一家實(shí)體企業(yè):我們會(huì)真正地購買衣服、將它們放到倉庫中并將其寄送給你。這不像eBay、Google以及一些虛擬企業(yè),如果我們對(duì)需求的猜測(cè)是錯(cuò)誤的,如果需求是我們預(yù)期的兩倍,那這就不是什么值得慶祝的好事了。這將會(huì)是一場(chǎng)災(zāi)難,因?yàn)槲覀冎荒転橐话氲娜颂峁┓⻊?wù)。如果我們有成倍的客戶,那我們就需要成倍的倉庫、造型師、雇員等類似的東西。對(duì)于我們來說,掌握正確的信息非常重要。

在這里,我們利用人工的地方都是人工做的最好的,而使用機(jī)器的地方也是機(jī)器做的最好的。

當(dāng)你設(shè)計(jì)這種規(guī)模的系統(tǒng)時(shí),我希望你要有一系列的目標(biāo)。你希望確保開發(fā)團(tuán)隊(duì)能夠繼續(xù)獨(dú)立且快速地往前發(fā)展,這就是我所稱的“特性敏捷(feature velocity)”。我們想要可擴(kuò)展性,所以隨著業(yè)務(wù)的增長,就會(huì)想要基礎(chǔ)設(shè)施也隨之增長。我們想要組件能夠根據(jù)負(fù)載進(jìn)行擴(kuò)展,以滿足我們對(duì)它們的要求。同時(shí),我們還想要這些組件是有彈性的,所以故障要進(jìn)行隔離,不要讓基礎(chǔ)設(shè)施產(chǎn)生級(jí)聯(lián)。

具有這些需求的高效組織有很多工作需要完成。DevOps手冊(cè)中包含了來自Gene Kim、Nicole Forsgren和其他人針對(duì)高效組織和低效組織差異性的研究。高效組織運(yùn)轉(zhuǎn)地更快,也更穩(wěn)定。你不必在速度和穩(wěn)定性之間做非此即彼的選擇,你可以二者兼得。

高效的組織每天會(huì)進(jìn)行多次部署,而不是每月一次,從代碼提交至源碼控制工具到部署中間的延遲不超過一個(gè)小時(shí),而在其他的組織中,這個(gè)過程可能會(huì)耗費(fèi)一周。這是速度方面的差別。

在穩(wěn)定性方面,高效的組織在一個(gè)小時(shí)之內(nèi)就能從故障中恢復(fù)過來,而在低效的組織中這可能會(huì)耗費(fèi)一天的時(shí)間,并且前者的故障率會(huì)更低。高效的組織很少會(huì)出現(xiàn)部署有問題的版本并不得不進(jìn)行回滾操作,而更慢的組織可能會(huì)有一半的時(shí)間在處理這種情況。這是一個(gè)巨大的差異。

其實(shí),不僅僅是速度和穩(wěn)定性,甚至不僅僅是技術(shù)指標(biāo)。在盈利能力、市場(chǎng)占有率以及生產(chǎn)力方面,高效的組織超出業(yè)務(wù)目標(biāo)的可能性是低效組織的2.5倍。所以這些不僅對(duì)于工程師非常重要,它們也關(guān)系到業(yè)務(wù)人員。

演化至微服務(wù)

當(dāng)我擔(dān)任“流動(dòng)的CTO服務(wù)提供者”時(shí),經(jīng)常會(huì)被問到的一個(gè)問題就是“嘿,Randy,你在Google和eBay都工作過,那么告訴我們一下在那里你們是怎么做的吧。”

我會(huì)回答說:“我承諾會(huì)告訴你這些事情,但是你們得保證不要跟著這樣做”。我說這些并不是為了保守Google和eBay的秘密,而是因?yàn)镚oogle具有15000人所組成的工程團(tuán)隊(duì),和只有五人圍坐在會(huì)議室的創(chuàng)業(yè)團(tuán)隊(duì)相比,他們面臨的是一些不同的問題。這是三個(gè)數(shù)量級(jí)級(jí)別的差異,對(duì)于不同規(guī)模的公司,會(huì)有不同的解決方案。

盡管如此,我還是很樂意告訴大家,眾所周知的這些公司是如何演進(jìn)至微服務(wù)的——它們并不是一開始就是微服務(wù),而是隨著時(shí)間演化至此的。

eBay

eBay正在對(duì)其基礎(chǔ)設(shè)施進(jìn)行第五次的重寫。在1995年的時(shí)候,它起初是一個(gè)單體的PERL應(yīng)用,當(dāng)它的創(chuàng)立者希望嘗試Web的時(shí)候,他花費(fèi)了三天的勞動(dòng)節(jié)和周末假期,最終構(gòu)建出了eBay。

下一代架構(gòu)是一個(gè)單體的C++應(yīng)用,在糟糕的場(chǎng)景中,單個(gè)DLL有340萬行代碼。它們甚至到達(dá)了編譯器對(duì)類中方法數(shù)量的限制,也就是16,000個(gè)。我相信很多人都認(rèn)為他們的應(yīng)用是單體架構(gòu)的,但是很少有人能夠比這更糟糕。

第三代是使用Java進(jìn)行重寫的,但是我們不能將其稱為微服務(wù),它是小應(yīng)用(mini-application)。他們將應(yīng)用拆分為200個(gè)不同的Java應(yīng)用。其中一個(gè)負(fù)責(zé)搜索部分,另一個(gè)負(fù)責(zé)購買部分等等。eBay當(dāng)前的實(shí)例可以稱為一組多語種(polyglot)的微服務(wù)。

Twitter

Twitter經(jīng)歷了類似的演化,現(xiàn)在大致是其第三代。它起初是一個(gè)Rails應(yīng)用,別名為Monorail。第二代將前端抽取到了JavaScript中,而后端修改成了Scala編寫的服務(wù),因?yàn)門witter是該技術(shù)的早期采用者,我們現(xiàn)在可以將其稱為多語種集合的微服務(wù)。

Amazon.com

Amazon.com盡管沒有明確的分代,但是他們經(jīng)歷了類似的演化。它最初是一個(gè)單體的C++和Perl應(yīng)用,我們?cè)诋a(chǎn)品頁面中依然能夠看到它存在的痕跡。在Amazon.com URL中我們有時(shí)會(huì)看到“obidos”,這就是最初Amazon.com應(yīng)用的代碼名。Obidos是亞馬遜河上的一個(gè)地方,位于巴西,這也是它得名的原因。

Amazon.com按照面向服務(wù)的架構(gòu)在2000至2005年間重寫了所有的內(nèi)容。服務(wù)主要是通過Java和Scala編寫的。在這個(gè)階段中,Amazon.com在業(yè)務(wù)上并不是特別突出。但是Jeff Bezos堅(jiān)定信念并強(qiáng)迫(或者說強(qiáng)烈鼓勵(lì))公司中的每個(gè)人以面向服務(wù)的架構(gòu)重構(gòu)所有內(nèi)容。現(xiàn)在,我們可以公平地將Amazon.com歸類為多語種集合的微服務(wù)。

這些故事都遵循了通用的模式。沒有人是從微服務(wù)開始的。但是,經(jīng)過一定的擴(kuò)展(這種擴(kuò)展可能只有0.1%的人能夠遇到),每個(gè)人最終都實(shí)現(xiàn)了我們所謂的微服務(wù)。

沒有人開始就是微服務(wù),經(jīng)過特定的擴(kuò)展,每個(gè)人最終都形成了微服務(wù)。

我要說的是,如果你最終沒有后悔自己早期的技術(shù)決策,那么你可能過度工程了。

我為什么要說這些呢?

想象一下在1995年eBay的競爭者和Amazon.com的競爭者。如果這家公司不去尋找恰當(dāng)?shù)漠a(chǎn)品市場(chǎng)、業(yè)務(wù)模型以及人們肯花錢支付的領(lǐng)域,而是構(gòu)建了一個(gè)五年之后才可能用上的分布式系統(tǒng),那么我們沒有聽到過這家公司也是事出有因的。

同樣,思考你的業(yè)務(wù)在什么地方、你在團(tuán)隊(duì)中的位置。如果你是小型的創(chuàng)業(yè)公司的話,Amazon.com、Google和Netflix的方案并不一定是適合你的方案。

微服務(wù)

我喜歡在定義微服務(wù)的“微”的時(shí)候,代指的不是代碼的行數(shù),而是接口的范圍。

微服務(wù)有單一的目的以及簡單、定義良好的接口,它是模塊化和獨(dú)立的。值得關(guān)注和探究的關(guān)鍵問題在于,正如Amazon.com所發(fā)現(xiàn)的那樣,有效的微服務(wù)具有隔離的持久化。換句話說,微服務(wù)不應(yīng)該與其他的服務(wù)共享數(shù)據(jù)。

對(duì)于可靠地執(zhí)行業(yè)務(wù)邏輯并保證不可變性的微服務(wù)來說,我們不能讓人們閱讀和寫入服務(wù)背后的數(shù)據(jù)。eBay以另外一種方式發(fā)現(xiàn)了同樣的問題。eBay在2008年組織很多非常聰明的人付出了很大的努力之后,構(gòu)建出了一個(gè)服務(wù)層,但是它并不成功。盡管服務(wù)構(gòu)建地非常好,接口非常棒并符合正交的原則(他們花費(fèi)了很多的時(shí)間來進(jìn)行思考),但是在接口下面是大量的共享數(shù)據(jù)庫,這些數(shù)據(jù)庫對(duì)應(yīng)用是直接可用的。為了完成應(yīng)用層的工作,人們并不是必須要使用服務(wù)層,所以他們干脆就不使用這個(gè)服務(wù)層。

在Stitch Fix,我們經(jīng)歷了自己的發(fā)展歷程。我們并沒有構(gòu)建過單體的應(yīng)用,但是我們所面臨的單體問題是我們所構(gòu)建的單體化數(shù)據(jù)庫。

我們正在拆分單體數(shù)據(jù)庫并從中抽取服務(wù),但是有一些非常棒的東西我們還希望能夠保留。

圖1展示了我們所面臨問題的一個(gè)簡單視圖。我們的應(yīng)用要比這個(gè)數(shù)量更多,但是在一張圖片上只能放下這么多的東西了。

 

 

圖1:Stitch Fix的單體、共享數(shù)據(jù)庫

我們實(shí)際上有一個(gè)包含所有內(nèi)容的共享數(shù)據(jù)庫,也就是Stitch Fix感興趣的所有數(shù)據(jù)。它包括客戶、我們所投遞的包裹、包裹中盛放的貨物、關(guān)于庫存的元數(shù)據(jù)(如樣式和SKU)、倉庫的信息,這大約有175張不同的表。我們還有70到80個(gè)不同的應(yīng)用程序和服務(wù),它們?yōu)榱送瓿筛髯缘墓ぷ,都要使用相同的?shù)據(jù)庫。這就是問題所在。對(duì)于團(tuán)隊(duì)來講,共享數(shù)據(jù)庫就是一個(gè)耦合點(diǎn),導(dǎo)致他們相互依賴,而無法做到相互獨(dú)立。這也是單點(diǎn)故障和性能的瓶頸。

我們的計(jì)劃是從共享數(shù)據(jù)庫中解耦應(yīng)用和服務(wù)。這里需要很多的工作。

 

 

圖2:拆分共享數(shù)據(jù)庫

圖2展示了拆分共享數(shù)據(jù)庫的步驟。圖A是起始點(diǎn),這里進(jìn)行了省略,如果將所有內(nèi)容都畫進(jìn)去的話,那么真實(shí)的圖像將會(huì)充滿了方框和線,所以假設(shè)只有三張表和兩個(gè)應(yīng)用程序。在樣例中,我們要做的第一件事情就是構(gòu)建一個(gè)服務(wù)來代表客戶信息(B)。這將是一個(gè)微服務(wù),具備定義良好的接口。在創(chuàng)建該服務(wù)之前,我們會(huì)與該服務(wù)的消費(fèi)者就該接口進(jìn)行協(xié)商。

接下來,我們讓應(yīng)用從服務(wù)中讀取數(shù)據(jù),而不是使用共享數(shù)據(jù)庫從表中進(jìn)行讀取(C)。這里最難的部分就是這些線的移動(dòng)。這并不是危言聳聽,但是簡單的一張圖真的無法表現(xiàn)其中的困難。在完成這一點(diǎn)之后,調(diào)用者不能直接連接數(shù)據(jù)庫,而是要經(jīng)過服務(wù)。然后,我們將這個(gè)表從共享數(shù)據(jù)庫中移除,并將其放到一個(gè)隔離的私有數(shù)據(jù)庫中,這個(gè)數(shù)據(jù)庫只與該微服務(wù)關(guān)聯(lián)(D)。這里會(huì)涉及很多較困難的工作,這是一種模式。

接下來的任務(wù)就是為貨物(item)信息執(zhí)行相同的處理過程。我們創(chuàng)建一個(gè)貨物服務(wù),應(yīng)用使用該服務(wù)而不再直接使用表(E)。然后,我們提取該表并將其變成微服務(wù)的一個(gè)私有數(shù)據(jù)庫。接下來,為SKU或樣式執(zhí)行相同的過程,并不斷地優(yōu)化和重復(fù)(F)。最后,每個(gè)微服務(wù)的邊界都包含了代表應(yīng)用程序的方框及其數(shù)據(jù)庫,比如成對(duì)出現(xiàn)的client-service和“core client”數(shù)據(jù)庫(F)。

我們已經(jīng)拆分了單體數(shù)據(jù)庫,每個(gè)表都放在了合適的位置上,所以每個(gè)微服務(wù)都有自己的持久化。但是,單體數(shù)據(jù)庫有很多有價(jià)值的功能,我并不想放棄它們。這包括非常便利地跨不同的服務(wù)和應(yīng)用共享數(shù)據(jù)、能夠便利地跨表執(zhí)行聯(lián)結(jié)以及事務(wù)性。我想要就像一個(gè)原子單元那樣跨多個(gè)實(shí)體進(jìn)行操作。這些都是單體數(shù)據(jù)庫的通用功能。

事件

在接下來的遷移中,對(duì)于各種數(shù)據(jù)庫特性,我們有的能夠保持,有的則無法繼續(xù)保持,但是對(duì)于無法保持的特性,也都有變通的辦法。在深入介紹這些內(nèi)容之前,我需要指出一個(gè)架構(gòu)性的構(gòu)建塊,你可能知道它但是并沒有對(duì)其產(chǎn)生應(yīng)有的興趣,它就是事件(event)。維基百科對(duì)事件的定義是狀態(tài)上的顯著變化或者發(fā)生某些感興趣事情的聲明。

在傳統(tǒng)的三層系統(tǒng)中,用戶或客戶端使用展現(xiàn)層,應(yīng)用層代表了無狀態(tài)的業(yè)務(wù)邏輯,持久化層則是由關(guān)系型數(shù)據(jù)庫作為支撐的。但是,作為架構(gòu)師,我們?nèi)鄙僖粋(gè)代表狀態(tài)的變化的基礎(chǔ)構(gòu)建塊,這也就是我所謂的事件。因?yàn)槭录话愣际钱惒降,可能我生成的事件并沒有人監(jiān)聽,也可能系統(tǒng)中只有一個(gè)消費(fèi)者在監(jiān)聽,還可能有很多的消費(fèi)者會(huì)訂閱它。

在架構(gòu)中,在將事件提升至第一級(jí)構(gòu)造之后,我們將會(huì)把它們用到微服務(wù)中。

微服務(wù)接口都會(huì)包括一個(gè)前門,對(duì)吧?它顯然要包括同步的請(qǐng)求和響應(yīng)。它一般會(huì)是HTTP協(xié)議,或者是JSON,或者是gRPC,反正諸如此類吧,但是它顯然需要包括一個(gè)入口點(diǎn)。但是它還包括了一些并不那么明顯的內(nèi)容(我希望我能說服你它們真的存在),那就是服務(wù)所產(chǎn)生的所有的事件、服務(wù)消費(fèi)的所有事件以及服務(wù)傳入和傳出數(shù)據(jù)的所有方式。為了進(jìn)行分析而讀取服務(wù)中的大量數(shù)據(jù)或者為了上傳而向服務(wù)批量寫入數(shù)據(jù)都是服務(wù)接口的一部分。簡而言之,我認(rèn)為服務(wù)的接口包括傳入和傳出數(shù)據(jù)的所有機(jī)制。

在將事件納入工具集之后,我們就要使用事件作為工具來解決共享數(shù)據(jù)、聯(lián)結(jié)和事務(wù)方面的問題。首先看一下共享數(shù)據(jù)的問題。在單體數(shù)據(jù)庫中,使用共享數(shù)據(jù)是非常容易的。我們將應(yīng)用指向共享的表就萬事大吉了。但是,在微服務(wù)領(lǐng)域該在什么地方共享數(shù)據(jù)呢?

我們有多種不同的可選方案,但是我首先會(huì)為你介紹一個(gè)在討論該問題時(shí)的工具或術(shù)語。這個(gè)原則或者術(shù)語叫做“單系統(tǒng)記錄(single system of record)”。如果系統(tǒng)中存在感興趣的客戶、貨物或包裹數(shù)據(jù)的話,那么應(yīng)該有且僅有一個(gè)服務(wù)作為該數(shù)據(jù)的權(quán)威系統(tǒng)記錄。系統(tǒng)中應(yīng)該只有一個(gè)服務(wù)擁有客戶數(shù)據(jù)、擁有貨物數(shù)據(jù)或擁有包裹數(shù)據(jù)。系統(tǒng)中會(huì)有客戶、貨物等數(shù)據(jù)的各種表述形式(當(dāng)然要在Stitch Fix之中),但是系統(tǒng)中的其他副本必須是只讀的,是系統(tǒng)記錄的非權(quán)威緩存。

再深入解釋一下:只讀和非權(quán)威。不要在任何地方修改客戶記錄并期望它能夠在其他系統(tǒng)中得到保持。如果需要修改數(shù)據(jù)的話,我們需要去系統(tǒng)記錄,這是目前唯一能夠在毫秒級(jí)就告訴我們用戶正在做什么的地方。

這就是系統(tǒng)記錄的理念,有多種不同的技術(shù)可以按照這種方式來使用,實(shí)現(xiàn)數(shù)據(jù)的共享。第一個(gè)是最為明顯和簡單的:從系統(tǒng)記錄中以同步方式進(jìn)行查找。

我們考慮Stitch Fix中的交付服務(wù)。在這個(gè)服務(wù)中,我們要將一件東西寄送到客戶的實(shí)際物理地址?蛻舴⻊(wù)擁有客戶本身的數(shù)據(jù),其中有一項(xiàng)就是客戶的地址。交付服務(wù)有一種可選方案就是調(diào)用客戶服務(wù)并查找地址。這種方式并沒有什么錯(cuò)誤,這是最合法的做法。但是,有時(shí)候這種做法并不合適。我們可能并不想讓所有的功能都與客戶服務(wù)耦合。交付服務(wù)或其他類似的服務(wù)可能會(huì)頻繁訪問客戶服務(wù),從而影響到性能。

另外一種方案要將異步事件和本地緩存結(jié)合起來。客戶服務(wù)依然掌握客戶的表述,但是當(dāng)客戶數(shù)據(jù)變更時(shí)(比如客戶地址),客戶服務(wù)會(huì)發(fā)送一個(gè)更新事件。當(dāng)?shù)刂钒l(fā)生變化的時(shí)候,交付服務(wù)會(huì)監(jiān)聽到該事件并在本地緩存地址信息,然后交付服務(wù)就能很愉快地投遞這個(gè)包裹了。

交付服務(wù)中的緩存還有其他很好的屬性。如果客戶服務(wù)沒有保留地址變化的歷史的話,我們可以在交付服務(wù)中記住它。在一定情況下這是有可能發(fā)生的:客戶在發(fā)起訂單和我們交付之間修改了地址信息。我們希望確保能夠?qū)⒂唵伟l(fā)送至正確的地方。

聯(lián)結(jié)

在單體數(shù)據(jù)庫中,進(jìn)行表聯(lián)結(jié)是非常容易的。我們只需要在SQL語句的FROM子句中添加另一個(gè)表的名稱就萬事大吉了。在所有的表都位于一個(gè)大的、單體數(shù)據(jù)庫中時(shí),這種方式是很好的,但是如果A和B是獨(dú)立的服務(wù),那么在SQL語句中就無法這樣使用了。一旦我們跨微服務(wù)切分?jǐn)?shù)據(jù),從概念上來講,聯(lián)結(jié)就更難實(shí)現(xiàn)了。

在架構(gòu)上我們始終都會(huì)有解決方案,有不止一種方式來處理聯(lián)結(jié)。第一種方式是在客戶端進(jìn)行聯(lián)結(jié)。在A和B實(shí)現(xiàn)聯(lián)結(jié)時(shí),將所有感興趣的內(nèi)容都取出來。在這個(gè)樣例中,我們假設(shè)要生成一個(gè)訂單的歷史。當(dāng)客戶進(jìn)入Stitch Fix想要查看我們所發(fā)送給他的包裹歷史時(shí),我們可能會(huì)按照這種方式來為客戶提供頁面。我們首先可能會(huì)讓訂單歷史頁面調(diào)用客戶服務(wù)獲取當(dāng)前版本的客戶信息,包括他的姓名、地址以及我們?yōu)樗l(fā)送了多少商品。然后,需要訪問訂單服務(wù)獲取客戶所有訂單的詳細(xì)信息。這里的過程就是從客戶服務(wù)中獲取一條客戶信息,然后通過訂單服務(wù)查詢匹配該客戶的所有訂單。

在無法通過一個(gè)服務(wù)獲取所有數(shù)據(jù)的Web頁面中,這都是一個(gè)基本的模式。同樣,這是該問題的一個(gè)完全合法的解決方案。在Stitch Fix,我們一直這樣做,我相信在你的應(yīng)用中也全是這樣的用法。

但是,我們假設(shè)這種方式無法使用了,至于原因可能是性能、穩(wěn)定性或者我們對(duì)訂單服務(wù)執(zhí)行了太多的查詢。

接下來就是第二種方案,我們創(chuàng)建一個(gè)服務(wù),按照數(shù)據(jù)庫的術(shù)語,我喜歡將其稱為“物化視圖(materializing the view)”。假設(shè)我們要編寫一個(gè)貨物反饋服務(wù)(item-feedback)。在Stitch Fix,我們將包裹發(fā)送出去,人們會(huì)將我們發(fā)送給他的商品留下一部分,然后將剩余的退還回來。我們想要知道原因,同時(shí)我們還會(huì)記住人們留下了什么商品、退還了什么商品。這些內(nèi)容我們希望通過貨物反饋服務(wù)來進(jìn)行記錄。我們可能會(huì)有1000或10000件特定型號(hào)的襯衫,在每次發(fā)送給客戶時(shí),我們都想記住所有客戶對(duì)它的反饋。這樣按照乘法計(jì)算下來,就能會(huì)有成千上萬的記錄信息。

為了實(shí)現(xiàn)該功能,我們需要有一個(gè)貨物服務(wù),它代表了襯衫的元數(shù)據(jù)。貨物反饋服務(wù)要監(jiān)聽來自貨物服務(wù)的事件,比如新的貨物上架、已有貨物下架以及感興趣的元數(shù)據(jù)變更。它還需要監(jiān)聽來自訂單服務(wù)的事件。每個(gè)訂單的反饋都要生成一個(gè)事件,也就是說如果我們?cè)诎蟹胖昧宋寮唐,那么可能就?huì)有五個(gè)事件。訂單反饋服務(wù)監(jiān)聽這些事件并物化聯(lián)結(jié)。換句話說,它會(huì)記住每個(gè)貨物所得到的反饋,并將其放到一個(gè)緩存的位置中。換個(gè)更有意思的說法就是,它在本地的存儲(chǔ)中維護(hù)了貨物和訂單的非規(guī)范化聯(lián)結(jié)。

很多常見的系統(tǒng)其實(shí)一直都這樣做,我們甚至都沒有想到他們會(huì)采用這樣的做法。比如,所有企業(yè)級(jí)(也就是需要花錢的)的數(shù)據(jù)庫系統(tǒng)都有一個(gè)物化視圖(Materialized view)的概念。Oracle、SQL Server以及很多企業(yè)級(jí)數(shù)據(jù)庫都有物化視圖的概念。

大多數(shù)的NoSQL系統(tǒng)都是按照這種方式運(yùn)行的。所有受到Dynamo啟發(fā)創(chuàng)建的數(shù)據(jù)存儲(chǔ),比如DynamoDB(來自Amazon)、Cassandra、React或Voldemort,都來源于相同的NoSQL傳統(tǒng)行為,也就是強(qiáng)迫我們提前就把事情做好。關(guān)系型數(shù)據(jù)庫對(duì)簡單的寫入進(jìn)行了優(yōu)化,也就是寫入到單個(gè)記錄或單個(gè)表中。在讀取的時(shí)候,我們?cè)賹⑵浣M合在一起。大多數(shù)的NoSQL則恰恰相反。我們所要存儲(chǔ)的表就是想要進(jìn)行查詢時(shí)所使用的表。我們不會(huì)在寫入時(shí)將數(shù)據(jù)寫到多個(gè)子表中,而是向我們后續(xù)想要讀取的存儲(chǔ)查詢(stored queries)中寫入五次。每個(gè)NoSQL系統(tǒng)都強(qiáng)制我們預(yù)先進(jìn)行這種類型的物化聯(lián)結(jié)。

我們所使用的搜索引擎幾乎都是將一個(gè)特定的實(shí)體與另外一個(gè)特定的實(shí)體按照某種特定的形式聯(lián)結(jié)起來。所有的分析系統(tǒng)都會(huì)聯(lián)結(jié)大量的數(shù)據(jù),因?yàn)檫@就是分析系統(tǒng)的意義所在。

通過講解,我希望你能夠?qū)@項(xiàng)技術(shù)感覺更加熟悉。

事務(wù)

關(guān)系型數(shù)據(jù)庫非常棒的一點(diǎn)就是其事務(wù)的概念。在關(guān)系型數(shù)據(jù)庫中,事務(wù)包含了ACID屬性:也就是原子性、一致性、隔離性和持久性。在單體數(shù)據(jù)庫中,我們可以實(shí)現(xiàn)這一點(diǎn)。在我們的系統(tǒng)中,這是數(shù)據(jù)庫所帶來的好處之一,跨實(shí)體實(shí)現(xiàn)事務(wù)是非常容易的。在SQL語句中,我們開始事務(wù)、執(zhí)行插入和更新,然后提交,所有的操作要么全部完成,要么全部取消。

將數(shù)據(jù)進(jìn)行跨服務(wù)分割會(huì)讓事務(wù)變得非常困難。我甚至想把“困難”改成“不可能”。我是怎么知道不可能的呢?在數(shù)據(jù)庫社區(qū)有一些技術(shù)來實(shí)現(xiàn)分布式事務(wù),比如兩階段提交,但實(shí)際上幾乎沒有人真的這樣做。作為這一現(xiàn)實(shí)情況的論據(jù),那就是整個(gè)世界上沒有云服務(wù)會(huì)實(shí)現(xiàn)分布式事務(wù)。為什么呢?那是因?yàn)樗强缮炜s性殺手。

所以,我們不再具備事務(wù)功能,但是依然有其他的做法。比如有個(gè)想要更新A、B和C的事務(wù),我們將它們放到一個(gè)saga中,這些操作要么作為一個(gè)整體全部執(zhí)行,要么全部不執(zhí)行。要?jiǎng)?chuàng)建一個(gè)saga,我們需要將事務(wù)建模為一個(gè)由單個(gè)原子事件組成的狀態(tài)機(jī)。圖3有助于更清晰地理解這一點(diǎn)。我們按照一個(gè)工作流的方式重新實(shí)現(xiàn)更新A、更新B和更新C。更新A會(huì)生成一個(gè)事件,該事件會(huì)被服務(wù)B所消費(fèi)。服務(wù)B完成自己的工作,并生成一個(gè)供服務(wù)C消費(fèi)的事件。最后,狀態(tài)機(jī)最終是一個(gè)終止?fàn)顟B(tài),A、B和C都完成了更新。

 

 

圖3:工作流和sagas

現(xiàn)在,假設(shè)某個(gè)地方出錯(cuò)了,我們需要按照相反的順序應(yīng)用補(bǔ)償操作。我們撤銷在服務(wù)C中所做的工作,它會(huì)產(chǎn)生一個(gè)或多個(gè)事件,然后撤銷在服務(wù)B中所做的工作,這也會(huì)產(chǎn)生一個(gè)或多個(gè)事件,最后我們撤銷在服務(wù)A中所做的工作。這就是saga的核心概念,在它的背后有很多的細(xì)節(jié)。如果你想要了解saga的更多知識(shí)的話,我強(qiáng)烈推薦Chris Richardson的QCon演講 在微服務(wù)中借助Sagas實(shí)現(xiàn)數(shù)據(jù)一致性。

如物化視圖類似,我們?nèi)粘J褂玫暮芏嘞到y(tǒng)都是按照這種方式運(yùn)行的?紤]一個(gè)支付處理系統(tǒng),如果你想要通過信用卡為我付款,我希望看到錢從你的賬號(hào)轉(zhuǎn)走,然后奇跡般地出現(xiàn)在我的錢包中,并且這一切都是在一個(gè)工作單元中完成的。但事實(shí)并非完全如此,在幕后有很多的事情要涉及到支付處理,并且要與很多銀行進(jìn)行對(duì)話,這些都像是金融魔術(shù)。

在我們講解事務(wù)的經(jīng)典例子中,我們要從Justin的賬戶中轉(zhuǎn)走一些錢,然后將其添加到Randy的賬戶中。世界上的金融系統(tǒng)沒有一家是這樣運(yùn)作的,相反,每個(gè)金融系統(tǒng)都將其實(shí)現(xiàn)為一個(gè)工作流。首先,錢會(huì)從Justin的賬戶取出,并且要在銀行存放幾天。它在銀行的存放期要比我想象得還長,但是它最終會(huì)出現(xiàn)在我的賬戶上。

舉另外一個(gè)費(fèi)用審批的例子,也許每個(gè)人在大會(huì)結(jié)束后都要進(jìn)行費(fèi)用報(bào)銷。這并不是立即就能完成的。你要將費(fèi)用提交給你的主管,他批準(zhǔn)之后,再將其報(bào)告給他的老板,老板再審批通過……層層審批。報(bào)銷還要經(jīng)歷一個(gè)付款處理流程,最終錢會(huì)到達(dá)你的錢包和賬戶上。你希望這個(gè)過程是一個(gè)整體的單元,但是它實(shí)際上是以工作流的形式來完成的。任意多步的工作流都與之類似。

考慮最后一個(gè)樣例,如果你以編寫代碼為生,假設(shè)你在IDE中點(diǎn)擊回車鍵,你的代碼就會(huì)部署到生產(chǎn)環(huán)境中,想象一下這將會(huì)發(fā)生什么呢?其實(shí)沒有人會(huì)這樣做。這并不是一個(gè)原子性的事務(wù),它也不應(yīng)如此。在持續(xù)交付管道中,當(dāng)我要提交的時(shí)候,要做很多的事情,最終我們希望能夠部署到生產(chǎn)環(huán)境上。這是高效組織的做法。但是,這些并不是一個(gè)原子的過程。同樣,它是一個(gè)狀態(tài)機(jī):這件事完成,執(zhí)行下一件,然后再下一件,如果這個(gè)過程中有錯(cuò)誤的話,我們就會(huì)進(jìn)行回滾。這聽起來非常熟悉。我們每天使用的系統(tǒng)都是這種行為方式,這意味著在我們構(gòu)建的服務(wù)中采取這種技術(shù)是沒有什么問題的。

概況來講,我們探討了如何將事件作為架構(gòu)工具箱中的一項(xiàng)工具。我們看到了如何在系統(tǒng)中借助事件在不同的組件之間共享數(shù)據(jù),介紹了如何使用事件來幫助我們實(shí)現(xiàn)聯(lián)結(jié)以及如何借助事件完成事務(wù)。

關(guān)于作者

Randy Shoup 在硅谷有著25年的工作經(jīng)驗(yàn),他曾經(jīng)在各種規(guī)模的公司中擔(dān)任高級(jí)技術(shù)領(lǐng)導(dǎo)和主管,從創(chuàng)業(yè)公司,到中型公司,再到eBay和Google這樣的大公司,他都有過工作經(jīng)歷。目前,他在位于舊金山的Stitch Fix擔(dān)任工程VP。他對(duì)文化、技術(shù)和組織之間的關(guān)系研究特別有熱情。

Thomas Betts 是IHS Markit的首席軟件工程師,具有20多年的專業(yè)軟件開發(fā)經(jīng)驗(yàn)。他一直專注于為客戶提供滿意的軟件解決方案,他曾經(jīng)在各個(gè)行業(yè)工作過,包括零售、金融、醫(yī)療、國防和旅游等。Thomas目前和他的妻子和兒子住在丹佛,他們喜歡徒步旅行和探索美麗的科羅拉多。

查看英文原文:Managing Data in Microservices

標(biāo)簽: Google 代碼 谷歌 金融 數(shù)據(jù)分析 數(shù)據(jù)庫 搜索 搜索引擎 云服務(wù)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:美國工程院院士Glynn:基于數(shù)據(jù)的決策,仿真與庫存管理

下一篇:數(shù)據(jù)處理的9大編程語言