Kappa Architecture將數(shù)據(jù)庫提升到新階段
亞馬遜Aurora讓數(shù)據(jù)庫可擴(kuò)展,但Kappa Architecture讓數(shù)據(jù)庫的發(fā)展無極限,管理員可以跨服務(wù)器集群創(chuàng)建數(shù)據(jù)的物化視圖。
傳統(tǒng)的數(shù)據(jù)庫有許多先進(jìn)的功能,其中對(duì)開發(fā)者最重要的就是物化視圖功能。這種存儲(chǔ)查詢會(huì)自動(dòng)緩存創(chuàng)建耗時(shí)的查詢,并將數(shù)據(jù)寫入磁盤。但傳統(tǒng)的數(shù)據(jù)庫在數(shù)據(jù)的存儲(chǔ)量和接受請(qǐng)求的吞吐方面的擴(kuò)展性不佳。雖然亞馬遜Aurora可以提高數(shù)據(jù)庫的擴(kuò)展能力,還單個(gè)數(shù)據(jù)庫的處理能力仍然有限。Kappa Architecture可以在這點(diǎn)上有所助益。
Kappa Architecture是一種軟件架構(gòu)模式加上一個(gè)只允許追加不允許修改的日志。Kappa Architecture同Lambda架構(gòu)系統(tǒng)類似,只是不支持批量處理。在數(shù)據(jù)庫中,有個(gè)細(xì)節(jié)叫做事務(wù)日志,每一次對(duì)數(shù)據(jù)庫的變更都會(huì)對(duì)日志進(jìn)行寫入。事務(wù)日志是用來重建部分?jǐn)?shù)據(jù)庫的內(nèi)容,如果出現(xiàn)問題的話可以恢復(fù)到特定的時(shí)間點(diǎn)。該日志包含底層數(shù)據(jù)的每一個(gè)原始動(dòng)作。例如,如果一個(gè)客戶要購買一件物品,事務(wù)日志可能會(huì)這樣顯示:
at 1463086280008 row 123456 old value = [ "cust-123", 50 ] new value = [ "cust-123", 25]
該值顯示在unix時(shí)間戳1463086280008的時(shí)候,123456行記錄從“cust-123”,50變更為“cust-123”,25。
這就是被稱為fact,表明在某個(gè)特定的時(shí)間,一個(gè)值被從某個(gè)值改為另一個(gè)值。這個(gè)事實(shí)是真的,不管之后會(huì)發(fā)生什么。舉例來說,即便客戶在此之后又增加了25個(gè)積分,他們?cè)谶@個(gè)特定的時(shí)間點(diǎn)仍然是減少了25積分。
數(shù)據(jù)庫常年都處理這種小細(xì)節(jié),但大多作為一個(gè)小的實(shí)現(xiàn)細(xì)節(jié)。Kappa Architecture建議將此作為記錄的主來源,其他的一切都作為數(shù)據(jù)的物化視圖。傳統(tǒng)的數(shù)據(jù)庫可以在一臺(tái)服務(wù)器上執(zhí)行這種類型的活動(dòng),而這種方法允許管理員可以***擴(kuò)展和創(chuàng)建橫跨不同服務(wù)器集群數(shù)據(jù)的物化視圖。
管理員可以使用日志流來查看跨服務(wù)器集群的數(shù)據(jù)
此日志流成為一個(gè)只能追加的系統(tǒng),只接受寫入操作,在寫入的時(shí)候加上基本的時(shí)間戳,然后將信息寫入到磁盤中。這種交互的構(gòu)想是,每一個(gè)寫操作都是按順序發(fā)生,所以該系統(tǒng)必須從頭開始按順序運(yùn)行日志中的每一個(gè)事件,才能重建數(shù)據(jù)庫當(dāng)前完整的視圖。
這使得開發(fā)人員可以在保持后臺(tái)系統(tǒng)完全運(yùn)作的同時(shí)增加額外的視圖。每個(gè)數(shù)據(jù)視圖可以在一個(gè)完全獨(dú)立的系統(tǒng)或多個(gè)完全獨(dú)立的系統(tǒng)里,只要這些系統(tǒng)有訪問整個(gè)日志流的完整權(quán)限。日志流會(huì)通知每個(gè)視圖任何一切操作以及操作發(fā)生的精確時(shí)間戳,這樣所有的操作就可以順序執(zhí)行。然后每個(gè)視圖可以獲取其需要的所有信息以確保單個(gè)視圖的正確建立。
Kappa如何在AWS上工作
創(chuàng)建Kappa這樣的架構(gòu)最顯而易見的工具是Amazon Kinesis,這是一個(gè)專門用來處理數(shù)據(jù)流的工具。當(dāng)一個(gè)進(jìn)程附加到一個(gè)Kinesis流,它可以自動(dòng)按順序讀取每一個(gè)事件,以建立自己的數(shù)據(jù)庫視圖。這可以用來將數(shù)據(jù)庫的更改復(fù)制到其它數(shù)據(jù)存儲(chǔ),如亞馬遜DynamoDB,甚至跨區(qū)域到其他的數(shù)據(jù)庫,因?yàn)閰^(qū)域鄰近優(yōu)化的關(guān)系。
Kinesis的另一種替代選擇是DynamoDB流,這對(duì)于使用DynamoDB數(shù)據(jù)庫的開發(fā)者來說使用方便。將這個(gè)想成是專門針對(duì)DynamoDB的自動(dòng)Kinesis流。不幸的是,無論來自Kinesis還是DynamoDB的流都只存儲(chǔ)最近7天的記錄。因此,要?jiǎng)?chuàng)建一個(gè)新的視圖,開發(fā)人員必須首先從一個(gè)主數(shù)據(jù)庫里讀出包含所有變更的最終結(jié)果的全部數(shù)據(jù)。
想更深入的了解如何創(chuàng)建一個(gè)Kappa風(fēng)格的視圖,現(xiàn)在假設(shè)我們有兩個(gè)DynamoDB表,Customer和Orders。公司的市場部門可能通常會(huì)問,“客戶X這個(gè)月花了多少錢?”在傳統(tǒng)的數(shù)據(jù)庫方式下,查詢?cè)摂?shù)據(jù)需要連接Customer表和Orders表,然后匯總出客戶所花費(fèi)的金額。
現(xiàn)在采用Kappa的方法,因?yàn)閿?shù)據(jù)是存儲(chǔ)在DynamoDB,而不是關(guān)系型數(shù)據(jù)庫,這種類型的查詢要么預(yù)先知曉,要么是我們?yōu)榇私⒌囊粋€(gè)新的并會(huì)不斷更新的視圖。大量的數(shù)據(jù)被存在Orders數(shù)據(jù)庫中,但營銷部門可能并不想知道一個(gè)Customer ID,而是會(huì)查找一個(gè)客戶的姓名或電子郵件地址。在這種情況下,開發(fā)人員可以創(chuàng)建一個(gè)包含Customer ID,Customer Name,Customer Email,Month和Total Spend的視圖。你可以根據(jù)姓名和電子郵件來對(duì)這個(gè)視圖建立索引。DynamoDB可以自動(dòng)處理這個(gè)問題,但如果不使用DynamoDB,開發(fā)人員還可以創(chuàng)建兩個(gè)獨(dú)立的視圖,一個(gè)根據(jù)名字建立索引和一個(gè)根據(jù)郵件索引。
Kappa Architecture結(jié)合AWS Lambda
首先,視圖的創(chuàng)建腳本需要先連接到流,并開始存儲(chǔ)DynamoDB流中的所有變更。該腳本可以從OldValue/NewValue的變化中識(shí)別出新的值。一旦腳本開始緩沖數(shù)據(jù),會(huì)將當(dāng)前數(shù)據(jù)表中所有的數(shù)據(jù)轉(zhuǎn)存出來,寫入到新表中。在所有的數(shù)據(jù)復(fù)制完畢后再開始處理事件。這種兩階段的方法有助于防止任何并發(fā)問題,以確保在數(shù)據(jù)被復(fù)制和腳本開始處理變更事件之間不會(huì)有數(shù)據(jù)丟失。
AWS Lambda是最有效的處理變更事件的方法。創(chuàng)建完用于創(chuàng)建該視圖的Lambda函數(shù)后,進(jìn)入Event Sources頁,然后選擇Add event source。
從Event Sources頁選擇‘Add event source’。
在彈出框中,選擇DynamoDB。
選擇DynamoDB作為事件源類型
接下來,填寫細(xì)節(jié),確保選擇正確的DynamoDB表(Orders),在Starting Position處填寫Trim Horizon。Batch size列出在某個(gè)時(shí)間最多有多少條記錄被發(fā)送給AWS Lambda函數(shù)的單個(gè)實(shí)例。這意味著Lambda函數(shù)需要在單次執(zhí)行中處理多個(gè)事件。
為Lambda函數(shù)配置DynamoDB表,batch size和starting position
接下來,Add Amazon DynamoDB Permissions to your role,以便Lambda函數(shù)可以訪問DynamoDB流。開發(fā)者還應(yīng)確保為角色添加AWS身份和訪問管理權(quán)限,使其能夠?qū)懭氲叫碌腄ynamoDB表,這將是新創(chuàng)建的視圖。開發(fā)人員應(yīng)該首先測試Lambda函數(shù);鉤上Enable event source,直到函數(shù)的功能驗(yàn)證成功。在確保函數(shù)工作之后,使用同樣的Event Sources控制臺(tái)暫時(shí)禁用流,直到新的視圖初始化完成。確保視圖初始化完成后再重新啟用源。
在重新啟動(dòng)流之前,***一步是將所有現(xiàn)有的記錄復(fù)制到新的視圖。這涉及到用一個(gè)外部腳本來讀取Orders數(shù)據(jù)庫中的每條記錄,并將其提交給Lambda函數(shù)。開發(fā)人員可能會(huì)想臨時(shí)增加讀取吞吐量直到新的視圖產(chǎn)生,這樣可以快速創(chuàng)建新視圖。請(qǐng)記住,DynamoDB Kinesis流將在日志中最多保留七天的事件。
***,寫一個(gè)額外的句柄來處理Customer的DynamoDB表的變更,將任何變化,如電子郵件地址或姓名,更新到與該客戶相關(guān)的新視圖是一個(gè)不錯(cuò)的主意。
Kappa Architecture是一個(gè)很好的方式將經(jīng)常請(qǐng)求的查詢進(jìn)行緩存從而給出快速高效的響應(yīng)。不幸的是,它本意不是為了同AWS一起用。AWS用戶可以運(yùn)行一個(gè)Apache Kafka實(shí)例作為數(shù)據(jù)的主存儲(chǔ),這將確保能夠建立新的視圖更簡單的能力。DynamoDB云則作為客戶的只讀源。同亞馬遜Kinesis的自動(dòng)擴(kuò)展能力相比,這種方法的缺點(diǎn)是開發(fā)人員將不得不維護(hù)Kafka以及處理關(guān)于擴(kuò)展性的一切問題。
盡管如此,使用Kafka讓企業(yè)可以避免廠商的完全鎖定,因?yàn)樗械臄?shù)據(jù)會(huì)以非專有的方法提供,能夠在別的數(shù)據(jù)存儲(chǔ)中復(fù)制,如果數(shù)據(jù)庫不得不在一個(gè)完全不同的云平臺(tái)重建的話。