
譯者 | 楊曉娟
策劃 | 云昭
系統(tǒng)中的數(shù)據(jù)遠(yuǎn)比構(gòu)成系統(tǒng)的應(yīng)用程序本身更有價(jià)值,這似乎有點(diǎn)老生常談。應(yīng)用程序會(huì)更新、變革、失效和替換,但數(shù)據(jù)仍然存在。對(duì)許多組織來(lái)說(shuō),這些數(shù)據(jù)是他們最重要的資產(chǎn)。過(guò)去很簡(jiǎn)單,你有組織的數(shù)據(jù)庫(kù),只有一個(gè)地方存放著組織的所有信息,從這里可以獲取所有想要的內(nèi)容。一個(gè)用于管理、監(jiān)控、優(yōu)化、備份等的數(shù)據(jù)庫(kù)—負(fù)責(zé)承接整個(gè)組織的數(shù)據(jù)需求。
隨著組織的發(fā)展,數(shù)據(jù)不斷增長(zhǎng),因而越來(lái)越多的需求被添加到數(shù)據(jù)庫(kù)中。在某一時(shí)刻,就會(huì)觸及極限。使用單一數(shù)據(jù)庫(kù)的做法已經(jīng)力不從心,必須將系統(tǒng)和數(shù)據(jù)庫(kù)分解為獨(dú)立的組件。在本文中,將討論如何管理數(shù)據(jù)范圍和大小的增長(zhǎng)。
1.共享數(shù)據(jù)庫(kù)的消亡,為什么不能使用更大的機(jī)器
雖然并不常見,但目前有數(shù)十億條記錄達(dá)到萬(wàn)億字節(jié)范圍的數(shù)據(jù)庫(kù)并不少見。那么有什么問(wèn)題呢?問(wèn)題不在于特定數(shù)據(jù)庫(kù)引擎的技術(shù)限制。而是組織將所有東西放入單個(gè)數(shù)據(jù)庫(kù)。例如,在我工作過(guò)的一家公司,數(shù)據(jù)庫(kù)中有超過(guò)30,000多張表,視圖和存儲(chǔ)過(guò)程的數(shù)量更多,這還沒(méi)說(shuō)觸發(fā)器的數(shù)量。
沒(méi)有哪個(gè)數(shù)據(jù)庫(kù)工具能夠處理如此數(shù)量的表。GUI工具每次連接數(shù)據(jù)庫(kù)時(shí)總會(huì)導(dǎo)致該工具卡頓幾分鐘,同時(shí)它會(huì)在短時(shí)間內(nèi)讀取模式描述。沒(méi)有人清楚數(shù)據(jù)庫(kù)內(nèi)部發(fā)生了什么,但是數(shù)據(jù)和圍繞它的流程對(duì)組織的成功至關(guān)重要。最后的結(jié)果:要么停滯不前,要么開始將數(shù)據(jù)庫(kù)分成可管理的組成部分。
那是多年前的事了,行業(yè)格局已經(jīng)發(fā)生了改變。今天,當(dāng)我們考慮數(shù)據(jù)時(shí),有更多問(wèn)題需要考慮,例如:
- 屬于歐洲公民的個(gè)人數(shù)據(jù),這意味著與他們相關(guān)的任何數(shù)據(jù)也必須實(shí)際存儲(chǔ)于歐盟,并受GDPR規(guī)則的約束。
- 醫(yī)療保健信息(直接或間接),需要遵循一套全新的規(guī)則(例如,HIPAA、HITECH或ENISA規(guī)則)。
數(shù)據(jù)隱私和出處等問(wèn)題更為重要,比如能夠?qū)徲?jì)和分析誰(shuí)訪問(wèn)了某個(gè)特定數(shù)據(jù)項(xiàng),以及為什么它在許多領(lǐng)域都是一個(gè)硬性要求。組織中的所有信息都駐留在一個(gè)存儲(chǔ)桶中的概念已不再可行。
另一個(gè)重要的巨變是常見的架構(gòu)模式。我們現(xiàn)在不再使用單一的龐大系統(tǒng)來(lái)管理組織中的一切內(nèi)容,而是將系統(tǒng)分解成更小的組件。這些組件有不同的需要和需求,按不同的時(shí)間表發(fā)布,使用不同的技術(shù)。當(dāng)你想更改自己的系統(tǒng)時(shí),嘗試在所有這些團(tuán)隊(duì)之間進(jìn)行協(xié)調(diào)的巨大開銷是你想要在系統(tǒng)中進(jìn)行更改的一個(gè)大障礙。跨這么多團(tuán)隊(duì)和組件進(jìn)行協(xié)調(diào)的成本太高了。
通常的想法是使用獨(dú)立應(yīng)用程序數(shù)據(jù)庫(kù),而非單個(gè)共享數(shù)據(jù)庫(kù)。這是一個(gè)更大的架構(gòu)概念的重要組成部分。通常會(huì)在微服務(wù)和面向服務(wù)的體系結(jié)構(gòu)中碰到這種情況。
2.應(yīng)用程序數(shù)據(jù)庫(kù)作為實(shí)現(xiàn)決策
從單個(gè)共享數(shù)據(jù)庫(kù)遷移到一組應(yīng)用程序數(shù)據(jù)庫(kù)之間一個(gè)最重要的區(qū)別是沒(méi)有拆分共享數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)級(jí)別的適當(dāng)分離是關(guān)鍵。一組共享數(shù)據(jù)庫(kù)也會(huì)有完全相同的協(xié)調(diào)問(wèn)題,因?yàn)閺N房里有太多的廚師。應(yīng)用程序數(shù)據(jù)庫(kù)被正確地分離,就能夠?yàn)槊總€(gè)任務(wù)選擇最佳的數(shù)據(jù)庫(kù)引擎,本地化更改,減少溝通更改的開銷。這種方法的缺點(diǎn)是在生產(chǎn)中要支持更多系統(tǒng)。
我們來(lái)更深入地討論下共享數(shù)據(jù)庫(kù)與應(yīng)用程序數(shù)據(jù)庫(kù)之間的區(qū)別。很容易弄錯(cuò),例如圖1所示:

圖1:從單個(gè)共享數(shù)據(jù)庫(kù)到多個(gè)(仍然共享)數(shù)據(jù)庫(kù)的錯(cuò)誤遷移路徑
雖然共享數(shù)據(jù)庫(kù)是你實(shí)現(xiàn)的,因?yàn)闆](méi)有其他選擇,但應(yīng)用程序數(shù)據(jù)庫(kù)是內(nèi)部選擇,除了應(yīng)用程序沒(méi)有人能訪問(wèn)。與面向?qū)ο缶幊痰姆庋b有相同的含義,使用私有變量隱藏狀態(tài),非常確定的是,應(yīng)用程序數(shù)據(jù)庫(kù)是應(yīng)用程序之外任何事物都不必關(guān)心的問(wèn)題。我對(duì)此深有同感。
編寫代碼時(shí),直接使用其他對(duì)象的私有狀態(tài)是錯(cuò)誤的。如果違反了不變性,未來(lái)的維護(hù)和開發(fā)都會(huì)變復(fù)雜。這已經(jīng)被大量事實(shí)敲定,因此大多數(shù)開發(fā)人員幾乎本能地不會(huì)這么做。直接訪問(wèn)另一個(gè)應(yīng)用程序的數(shù)據(jù)庫(kù)也會(huì)發(fā)生完全相同的狀況,但卻非常常見。
在某些情況下,我對(duì)數(shù)據(jù)庫(kù)中所有表和列的名稱進(jìn)行了加密,以表明你不應(yīng)該查看我的數(shù)據(jù)庫(kù)。應(yīng)用程序數(shù)據(jù)庫(kù)應(yīng)該僅僅是應(yīng)用程序的內(nèi)部關(guān)注點(diǎn)。這個(gè)想法很簡(jiǎn)單。如果應(yīng)用程序之外的任何實(shí)體需要一些數(shù)據(jù),則需要向應(yīng)用程序請(qǐng)求。他們不應(yīng)該直接進(jìn)入應(yīng)用程序數(shù)據(jù)庫(kù)獲取。這是詢問(wèn)“你在和誰(shuí)說(shuō)話”與查看他們所有的交流記錄及留言之間的區(qū)別。理論上,這是一個(gè)好方法,但是需要考慮到,你的應(yīng)用程序不僅是系統(tǒng)的應(yīng)用程序,還必須與生態(tài)系統(tǒng)的其他部分集成。問(wèn)題是你如何做到這一點(diǎn)。
如果這里描述的系統(tǒng)聽起來(lái)很熟悉,那是因?yàn)槟憧赡芤郧奥犝f(shuō)過(guò)。它最初是DCOM/COBRA系統(tǒng)的一部分,后來(lái)被稱為面向服務(wù)的體系架構(gòu),現(xiàn)在被稱為微服務(wù)。
假設(shè)在我們的系統(tǒng)中處理發(fā)貨的應(yīng)用程序需要訪問(wèn)一些客戶數(shù)據(jù)來(lái)完成其任務(wù)。如何獲得這些數(shù)據(jù)?使用共享數(shù)據(jù)庫(kù)時(shí),直接查詢客戶表。當(dāng)負(fù)責(zé)客戶應(yīng)用程序的團(tuán)隊(duì)需要添加列或重構(gòu)數(shù)據(jù)時(shí),你的系統(tǒng)就會(huì)遭到破壞。它們之間沒(méi)有封裝或分離。直接依賴另一個(gè)團(tuán)隊(duì)的實(shí)現(xiàn)細(xì)節(jié)的方式會(huì)導(dǎo)致破壞、停滯和不斷增加的復(fù)雜性。
3.使用全局?jǐn)?shù)據(jù)
或者,發(fā)貨應(yīng)用程序可以(通過(guò)已發(fā)布的服務(wù)接口)請(qǐng)求擁有客戶數(shù)據(jù)的應(yīng)用程序以獲取所需的詳細(xì)信息。這通常是通過(guò)從一個(gè)應(yīng)用程序到另一個(gè)應(yīng)用程序的RCP調(diào)用來(lái)完成。問(wèn)題是,如此一來(lái)就在兩個(gè)應(yīng)用程序之間建立了牢固的聯(lián)系。如果客戶的應(yīng)用程序因維護(hù)而停機(jī),則運(yùn)輸應(yīng)用程序?qū)o(wú)法工作。再加上幾十個(gè)這樣的應(yīng)用程序及其相互依賴關(guān)系,你就有可能陷入僵局。我們需要考慮一種更好的方法來(lái)處理這種情況。
我的建議是從另一個(gè)方向著手整個(gè)過(guò)程。發(fā)貨應(yīng)用程序不必查詢客戶應(yīng)用程序的相關(guān)數(shù)據(jù),而是進(jìn)行相反的操作。作為客戶應(yīng)用程序服務(wù)接口的一部分,完全可以決定要向組織的其他部分公開什么樣的信息。
需要注意的是,發(fā)布的數(shù)據(jù)絕對(duì)是服務(wù)契約的一部分。不提供對(duì)數(shù)據(jù)庫(kù)的直接訪問(wèn)。應(yīng)用程序應(yīng)該向外界發(fā)布其數(shù)據(jù)。可以是上傳到FTP站點(diǎn)或GraphQL端點(diǎn)的每日CSV文件,以選擇兩種截然不同的技術(shù)和語(yǔ)義。
我在FTP上包含了CSV,以特別表明數(shù)據(jù)共享的方式是無(wú)關(guān)緊要的。重要的是,有一種從應(yīng)用程序發(fā)布數(shù)據(jù)的既定方式,因?yàn)檫@種架構(gòu)風(fēng)格的一個(gè)關(guān)鍵方面是不必在需要的時(shí)候查詢數(shù)據(jù)。相反,我們將其攝取到自己的系統(tǒng)中。我想很明顯,為什么發(fā)貨應(yīng)用程序不會(huì)打開一個(gè)FTP連接到客戶的每日CSV轉(zhuǎn)儲(chǔ)文件以查找詳細(xì)信息。同樣的,它也不應(yīng)該將查詢GraphQL端點(diǎn)作為其常規(guī)例程的一部分。
相反,我們有一個(gè)既定的機(jī)制,通過(guò)該機(jī)制發(fā)布客戶的數(shù)據(jù)(客戶應(yīng)用程序已向組織的其他部分公開)。這由系統(tǒng)中的其它應(yīng)用程序攝取,當(dāng)他們需要查詢客戶的詳細(xì)信息時(shí),可以從自己的系統(tǒng)中進(jìn)行查詢。如圖2所示:

圖2:客戶應(yīng)用程序發(fā)布數(shù)據(jù)以供運(yùn)輸應(yīng)用程序使用
在每個(gè)應(yīng)用程序中,數(shù)據(jù)可以以不同的方式存儲(chǔ)和表示。在每種情況下,都是最適合他們的。
發(fā)布應(yīng)用程序還可以以他們選擇的任何方式處理數(shù)據(jù)。數(shù)據(jù)庫(kù)和數(shù)據(jù)發(fā)布方式之間的服務(wù)邊界允許自由修改內(nèi)部細(xì)節(jié),而無(wú)需與外部系統(tǒng)協(xié)調(diào)。
另一個(gè)選擇是采用兩階段的流程,如圖3所示。客戶應(yīng)用程序不必將其更新發(fā)送給發(fā)貨應(yīng)用程序,而是將其發(fā)送到組織數(shù)據(jù)湖。通過(guò)這種方式,每個(gè)應(yīng)用程序?qū)⑾M_的數(shù)據(jù)發(fā)送到一個(gè)中心位置。其他應(yīng)用程序可以將需要的數(shù)據(jù)從數(shù)據(jù)湖復(fù)制到自己的數(shù)據(jù)庫(kù)中。

圖3:每個(gè)應(yīng)用程序發(fā)布數(shù)據(jù)到數(shù)據(jù)湖并拉取數(shù)據(jù)到各應(yīng)用程序
最終結(jié)果是一個(gè)共享數(shù)據(jù)的系統(tǒng),但是沒(méi)有應(yīng)用程序和服務(wù)之間的時(shí)間依賴關(guān)系。它還確保了不同團(tuán)隊(duì)和系統(tǒng)之間的邊界。只要發(fā)布的接口保持不變,就不需要協(xié)調(diào)增加復(fù)雜性。
4.實(shí)踐中的幾個(gè)建議
我們深入探討關(guān)于如何應(yīng)用這種體系架構(gòu)方法的一些具體建議。可以通過(guò)在服務(wù)總線上發(fā)出事件或發(fā)布每日文件來(lái)全局發(fā)布數(shù)據(jù)。可以發(fā)布特定場(chǎng)景的數(shù)據(jù),例如從客戶數(shù)據(jù)庫(kù)到發(fā)貨數(shù)據(jù)庫(kù)的ETL流程。只要有適當(dāng)?shù)倪吔纾植康姆椒ǖ母淖儗?duì)整體的影響度很低。
這種操作方式只在需要引用數(shù)據(jù)或?qū)εc一致性無(wú)關(guān)的數(shù)據(jù)做出決策時(shí)有效。如果需要對(duì)數(shù)據(jù)進(jìn)行更改或協(xié)調(diào)更改,則此方法不適用。一致性無(wú)關(guān)緊要的一個(gè)很好的例子就是根據(jù)客戶的ID查找他們的名字,如果我們有舊名字,那不是什么大問(wèn)題。很快就會(huì)自行修復(fù),我們不會(huì)根據(jù)客戶的名字來(lái)做決定。同時(shí),我們可以在應(yīng)用程序范圍內(nèi)完全本地運(yùn)行所有的計(jì)算和任務(wù),這是一個(gè)很大的優(yōu)勢(shì)。
當(dāng)我們需要做出決定或修改數(shù)據(jù)時(shí),一致性很重要。例如,在發(fā)貨場(chǎng)景中,如果要收取超重費(fèi),需要確保客戶賬戶中有足夠的資金。在這種情況下,我們并不擁有賬戶中的資金,不能對(duì)自己的數(shù)據(jù)進(jìn)行操作。如此一來(lái),需要向客戶發(fā)起應(yīng)用程序申請(qǐng),要求扣除這些資金,如果資金不足,則報(bào)告錯(cuò)誤。注意,如果客戶無(wú)法付款,更合理的結(jié)果應(yīng)該是:發(fā)貨操作失敗。
應(yīng)用程序不應(yīng)該再部署到單個(gè)服務(wù)器甚至單個(gè)數(shù)據(jù)中心。如今,在邊緣系統(tǒng)上運(yùn)行應(yīng)用程序(如移動(dòng)應(yīng)用程序或物聯(lián)網(wǎng)設(shè)備)已經(jīng)非常常見。將所有這些數(shù)據(jù)推送到自己的系統(tǒng)中可能會(huì)導(dǎo)致存儲(chǔ)不可承受的巨量數(shù)據(jù)。數(shù)據(jù)封裝和僅公開希望公開的細(xì)節(jié)這種架構(gòu)風(fēng)格在這個(gè)場(chǎng)景中發(fā)揮得非常好。
無(wú)需將所有信息復(fù)制到中心位置,而是將數(shù)據(jù)存儲(chǔ)在邊緣,并從邊緣設(shè)備接收足夠的數(shù)據(jù),以便能夠做出決策并操作系統(tǒng)的全局狀態(tài)。除其他優(yōu)點(diǎn)外,這種方法讓用戶可以掌控他們所有的數(shù)據(jù),我認(rèn)為這是一個(gè)主要的優(yōu)點(diǎn)
5.寫在最后
在架構(gòu)中使用應(yīng)用程序數(shù)據(jù)庫(kù)和顯式數(shù)據(jù)發(fā)布有幾個(gè)原因。首先,它意味著操作是以本地資源和最少的協(xié)調(diào)運(yùn)行的。反過(guò)來(lái),意味著這些操作更快、更可靠。其次,它減少了整個(gè)系統(tǒng)的協(xié)調(diào)開銷,這表明可以根據(jù)需要獨(dú)立部署和更改每個(gè)應(yīng)用程序。
最后,它意味著可以獨(dú)立地為每個(gè)場(chǎng)景選擇最佳選項(xiàng)。可以為每個(gè)選項(xiàng)選擇最好的品種,而不是迎合最低公分母。例如,可以使用文檔數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)發(fā)貨清單,而將歷史數(shù)據(jù)放入數(shù)據(jù)湖中。
每個(gè)應(yīng)用程序都是獨(dú)立的,彼此隔離,可以為每個(gè)場(chǎng)景做出最佳的技術(shù)選擇,而不必考慮任何全局約束。其結(jié)果是一個(gè)更易修改的系統(tǒng),由更小的組件組成(因而更容易理解),并且更加敏捷。
譯者介紹
楊曉娟,51CTO社區(qū)編輯,資深研發(fā)工程師,信息系統(tǒng)項(xiàng)目管理師。
原文鏈接:
??https://dzone.com/articles/data-management-in-complex-systems???
























