哈爾濱童程童美少兒編程培訓(xùn)南崗校區(qū)
人工智能編程、智能機(jī)器人編程、信息學(xué)奧賽輔導(dǎo)、樂高創(chuàng)意啟蒙培訓(xùn)
童程童美少兒編程教育以10000-25000元的學(xué)費(fèi),平均每堂課200-300元,為學(xué)生提供了高性價(jià)比的學(xué)習(xí)體驗(yàn)?;ヂ?lián)網(wǎng)上對(duì)我們的介紹充滿贊譽(yù),認(rèn)可我們的經(jīng)濟(jì)實(shí)惠和透明宣傳。機(jī)構(gòu)介紹清晰透明,受到互聯(lián)網(wǎng)用戶的一致好評(píng),建立了極高的信任度。師資團(tuán)隊(duì)經(jīng)驗(yàn)豐富,專業(yè)而有激情,致力于培養(yǎng)學(xué)生創(chuàng)新思維。學(xué)校環(huán)境設(shè)計(jì)充滿創(chuàng)意,吸引學(xué)生自由表達(dá)創(chuàng)造力。多地校區(qū)設(shè)置,提供便利的學(xué)習(xí)場(chǎng)所。提供多樣化教學(xué)項(xiàng)目,以學(xué)生成績(jī)和學(xué)習(xí)效果為導(dǎo)向,學(xué)員家長(zhǎng)的積極評(píng)價(jià)是我們好的證明。
我們遇到了問題。數(shù)據(jù)集成領(lǐng)域以基于輪詢的 ETL 管道為主,這些管道按計(jì)劃運(yùn)行并發(fā)起與源數(shù)據(jù)系統(tǒng)的通信。這種模式很普遍;各行業(yè)各種規(guī)模的公司都在使用它。
為什么這是個(gè)問題?其實(shí)有兩個(gè):
在Tinybird,我們相信數(shù)據(jù)應(yīng)該在發(fā)生時(shí)立即處理。時(shí)期。我們認(rèn)為,數(shù)據(jù)和工程團(tuán)隊(duì)?wèi)?yīng)該使用專門適合處理和處理這些數(shù)據(jù)的工具,而不會(huì)給其他系統(tǒng)和資源增加過度的壓力。
在這篇博文中,我將重點(diǎn)介紹可以跨不同源數(shù)據(jù)系統(tǒng)實(shí)現(xiàn)的幾種不同的事件驅(qū)動(dòng)架構(gòu)模式,并討論這些實(shí)現(xiàn)的優(yōu)缺點(diǎn)。
事件流、消息隊(duì)列和無服務(wù)器功能正在興起,一些開明的人正在從輪詢思維轉(zhuǎn)向新的范式:事件驅(qū)動(dòng)架構(gòu)。
事件驅(qū)動(dòng)架構(gòu)的概念非常簡(jiǎn)單。數(shù)據(jù)幾乎總是為了響應(yīng)某種事件而生成:用戶單擊按鈕、處理事務(wù)、上傳文件。為什么不使用這些事件來觸發(fā)實(shí)時(shí)數(shù)據(jù)攝取過程?
事件驅(qū)動(dòng)架構(gòu)背后的想法很簡(jiǎn)單:使用事件觸發(fā)數(shù)據(jù)攝取過程。
事件驅(qū)動(dòng)架構(gòu)解決了上述兩個(gè)問題,并且它已經(jīng)作為繞過(或者更確切地說,并行)源數(shù)據(jù)系統(tǒng)的數(shù)據(jù)捕獲和集成的方法而受到關(guān)注。
考慮一個(gè)幾乎適用于所有 B2C 業(yè)務(wù)和大多數(shù) B2B 業(yè)務(wù)的場(chǎng)景:您有一個(gè)面向用戶的應(yīng)用程序,該應(yīng)用程序構(gòu)建在與 Postgres 或 MySQL 等應(yīng)用程序數(shù)據(jù)庫通信的后端 API 之上。
當(dāng)用戶在應(yīng)用程序中執(zhí)行操作時(shí),它會(huì)調(diào)用 API 并生成一些數(shù)據(jù),然后將其推送到數(shù)據(jù)庫。隨著您的公司獲得關(guān)注并且應(yīng)用程序添加了更多用戶和更多功能,您開始擴(kuò)展數(shù)據(jù)庫,拼命努力跟上來自 API 的單行插入頻率的增加。
然后營(yíng)銷部門的一些笨蛋想要對(duì)這些數(shù)據(jù)進(jìn)行分析。因此,您在晚上大多數(shù)用戶都在睡覺并且應(yīng)用程序數(shù)據(jù)庫服務(wù)器有一些額外周期時(shí)運(yùn)行批量導(dǎo)出,然后將新數(shù)據(jù)復(fù)制到數(shù)據(jù)倉(cāng)庫。這很常見。大多數(shù)公司都是這樣做的。
這就是您遇到這兩個(gè)問題的地方。批處理作業(yè)會(huì)給數(shù)據(jù)庫帶來額外的負(fù)載,并且較終會(huì)得到陳舊的數(shù)據(jù)。如果您嘗試更頻繁地運(yùn)行該作業(yè)來進(jìn)行補(bǔ)償,則會(huì)增加負(fù)擔(dān)。這是一個(gè)無法通過批量 ETL 解決的第 22 條軍規(guī)。
批處理作業(yè)會(huì)給數(shù)據(jù)庫帶來額外的負(fù)載,并且較終會(huì)得到陳舊的數(shù)據(jù)。如果您嘗試更頻繁地運(yùn)行該作業(yè)來進(jìn)行補(bǔ)償,則會(huì)增加負(fù)擔(dān)。這是一個(gè)無法通過批量 ETL 解決的第 22 條軍規(guī)。
那么如何才能避免這兩個(gè)問題并且仍然讓營(yíng)銷人員滿意呢?
關(guān)鍵是在數(shù)據(jù)到達(dá)應(yīng)用程序數(shù)據(jù)庫之前(或同時(shí))將數(shù)據(jù)獲取到倉(cāng)庫。在這種情況下,您已經(jīng)有一個(gè)事件:API 調(diào)用。您可以利用這一點(diǎn),將事件及其數(shù)據(jù)推送到消息隊(duì)列,同時(shí)后端將其插入應(yīng)用程序數(shù)據(jù)庫。
通過這種事件驅(qū)動(dòng)的方法,您完全稍后從應(yīng)用程序數(shù)據(jù)庫中提取此數(shù)據(jù);它已經(jīng)在消息隊(duì)列中了。
事件驅(qū)動(dòng)方法的關(guān)鍵是在數(shù)據(jù)到達(dá)應(yīng)用程序數(shù)據(jù)庫之前(或同時(shí))將數(shù)據(jù)獲取到倉(cāng)庫。
這是一種非常有效的模式,因?yàn)閿?shù)據(jù)已經(jīng)生成并存儲(chǔ)在后端的內(nèi)存中。您只需將其發(fā)送到另一個(gè)端點(diǎn)即可。
但是,與所有模式一樣,有一個(gè)缺點(diǎn):您必須對(duì)應(yīng)用程序的后端進(jìn)行代碼更改。這項(xiàng)工作通常被推給負(fù)責(zé)后端的軟件工程師,而不是管理數(shù)據(jù)(庫)的團(tuán)隊(duì)。
這可能會(huì)給您的組織帶來挑戰(zhàn),也可能不會(huì)。如果軟件團(tuán)隊(duì)積壓了問題,這可能不是優(yōu)先考慮的事情。這完全取決于他們的移動(dòng)速度以及您可以等待多長(zhǎng)時(shí)間。
變更數(shù)據(jù)捕獲(CDC) 是事件驅(qū)動(dòng)架構(gòu)中經(jīng)過驗(yàn)證的實(shí)現(xiàn),您可以使用它來避免在不接觸后端的情況下加載數(shù)據(jù)庫,它有其優(yōu)點(diǎn)和缺點(diǎn)。
使用 CDC,您可以訂閱數(shù)據(jù)庫中所做更改(例如插入、更新和刪除)的日志,并將這些更改推送到其他地方。如果您不適合對(duì) API 進(jìn)行代碼更改,那么 CDC 是在應(yīng)用程序數(shù)據(jù)庫之外構(gòu)建事件驅(qū)動(dòng)管道的好方法。
大多數(shù)應(yīng)用程序數(shù)據(jù)庫都會(huì)創(chuàng)建對(duì)數(shù)據(jù)庫執(zhí)行的操作的日志。對(duì)于某些數(shù)據(jù)庫,此日志是數(shù)據(jù)庫架構(gòu)的核心部分,例如 Postgres 的預(yù)寫日志(WAL)。對(duì)于其他人來說,這是一個(gè)需要啟用的單獨(dú)功能,就像 MySQL 的 bin 日志一樣。
無論哪種情況,其想法都基本相同。日志是數(shù)據(jù)庫更改(例如插入、更新、刪除)及其數(shù)據(jù)的僅附加文件。每個(gè)操作都按時(shí)間順序附加為新行,這意味著您只需從頂部開始并逐一重播每個(gè)事件,即可使用日志在準(zhǔn)確的時(shí)刻重建數(shù)據(jù)庫的狀態(tài)。
CDC 工具會(huì)監(jiān)視此日志文件中的新行,將每個(gè)更改操作捕獲為一個(gè)事件,并將這些事件推送到其他地方。將這些事件推送到僅附加事件流系統(tǒng)(例如 Apache Kafka)的情況尤其常見。然后可以將更改操作推送到所需的下游系統(tǒng),例如分析 (OLAP) 數(shù)據(jù)庫。
如果您不能或不想更新現(xiàn)有的 API 代碼,則更改數(shù)據(jù)捕獲是一種有吸引力的策略。擁有數(shù)據(jù)庫的團(tuán)隊(duì)通常擁有 CDC 實(shí)現(xiàn),并且有像 Debezium 這樣的開源框架,使得啟動(dòng)和運(yùn)行相對(duì)簡(jiǎn)單。
由于此策略僅涉及監(jiān)視日志文件,因此它比對(duì)數(shù)據(jù)庫運(yùn)行增量查詢要輕得多。新行會(huì)立即附加到日志文件中,因此可以近乎實(shí)時(shí)地訪問它們,從而將延遲保持在較低限度。
當(dāng)您的后端工程團(tuán)隊(duì)無法或不想更新后端 API 以與數(shù)據(jù)庫寫入并行地將事件發(fā)送給下游消費(fèi)者時(shí),變更數(shù)據(jù)捕獲系統(tǒng)是事件驅(qū)動(dòng)架構(gòu)的一個(gè)很好的替代方案。
然而,這并不全是陽光和雛菊。雖然讀取日志文件是輕量級(jí)的,但它仍然需要服務(wù)器上的額外代理進(jìn)程,這確實(shí)增加了負(fù)載。在擴(kuò)展應(yīng)用程序數(shù)據(jù)庫時(shí),它增加了另一層考慮因素,因?yàn)槟仨毧紤]增加的流量將如何影響該代理所需的資源。
它還引入了您的團(tuán)隊(duì)可能不熟悉的全新技術(shù)。雖然這些工具被廣泛采用且易于上手,但隨著規(guī)模的擴(kuò)大或偏離常規(guī),它們可能會(huì)變得難以理解。
這兩種策略都沒有錯(cuò),較終結(jié)果基本相同:來自應(yīng)用程序堆棧的實(shí)時(shí)更改流。由您決定較佳方法。
當(dāng)然,并非每個(gè)數(shù)據(jù)攝取場(chǎng)景都涉及應(yīng)用程序數(shù)據(jù)庫。也許甚至不是大多數(shù)。在這種情況下,數(shù)據(jù)庫中的行與生成的事件之間可能不具有 1:1 的關(guān)系。在許多情況下,您實(shí)際上可能會(huì)以文件形式接收數(shù)據(jù),這些數(shù)據(jù)要么是從內(nèi)部服務(wù)推送的,要么是從外部數(shù)據(jù)供應(yīng)商收集的。事件驅(qū)動(dòng)架構(gòu)可以像數(shù)據(jù)庫一樣應(yīng)用于文件系統(tǒng)。
在過去(實(shí)際上,今天仍然很常見),數(shù)據(jù)生產(chǎn)者或經(jīng)紀(jì)人會(huì)建立一個(gè)大型文件傳輸協(xié)議(FTP)服務(wù)器并將文件轉(zhuǎn)儲(chǔ)到一個(gè)大型存儲(chǔ)服務(wù)器上。他們向客戶提供 FTP 憑據(jù),客戶端將在每天運(yùn)行的 bash 腳本中使用該憑據(jù)來查找新文件并將其復(fù)制到內(nèi)部共享存儲(chǔ)中。這是一個(gè)奇特的小工作流程,多年來一直發(fā)揮其作用。
但是,除了過時(shí)之外,它還存在一些問題:
事件驅(qū)動(dòng)數(shù)據(jù)管道的好處在于它們非常靈活,可以適應(yīng)許多用例、許多源數(shù)據(jù)系統(tǒng)以及下游數(shù)據(jù)消費(fèi)者的許多不同需求。它們可以像數(shù)據(jù)庫一樣用于文件,盡管使用的是不同的工具集。
時(shí)代變了,現(xiàn)在我們擁有容錯(cuò)、可擴(kuò)展且經(jīng)濟(jì)的文件存儲(chǔ)服務(wù),例如 Amazon S3 和 Google Cloud Storage。
這些服務(wù)不僅使用起來比 FTP 更有趣,而且還使得使用事件驅(qū)動(dòng)的架構(gòu)來分發(fā)和使用文件成為可能。而不是不斷地輪詢存儲(chǔ)服務(wù)來詢問“新文件是否到達(dá)?” 或者等待一整天然后說“給我昨天到達(dá)的所有文件”,存儲(chǔ)服務(wù)本身可以創(chuàng)建有關(guān)新文件的通知并將它們推送到消息隊(duì)列,就像在數(shù)據(jù)庫的事件驅(qū)動(dòng)架構(gòu)中一樣。
然后,下游消費(fèi)者可以簡(jiǎn)單地訂閱消息隊(duì)列,并在收到通知時(shí)去獲取文件。
托管在云供應(yīng)商的對(duì)象存儲(chǔ)中的文件可以利用云原生通知服務(wù)來通知下游消費(fèi)者有新的或修改的文件。
這種模式非常有用,有以下幾個(gè)原因:
您可以看到這如何反映應(yīng)用程序數(shù)據(jù)庫的場(chǎng)景。源數(shù)據(jù)系統(tǒng)不同,但實(shí)現(xiàn)和好處非常相似。
由于這些現(xiàn)代云存儲(chǔ)服務(wù)內(nèi)置了事件通知,只需單擊一下即可啟用,因此設(shè)置事件驅(qū)動(dòng)的文件攝取非常容易。數(shù)據(jù)創(chuàng)建者幾乎不需要做額外的工作,數(shù)據(jù)消費(fèi)者可以利用無服務(wù)器服務(wù),從而輕松采用這種新模式。
例如,Amazon 有 SQS 和 SNS,可用于對(duì)這些事件進(jìn)行排隊(duì),然后您可以附加任意數(shù)量的工具來響應(yīng)事件并處理文件。例如,您可以使用 Apache NiFi 處理在 SQS 中排隊(duì)的 S3 事件通知。
因此,無論您使用數(shù)據(jù)庫還是文件作為源數(shù)據(jù)系統(tǒng),您都可以采用這些新模式來實(shí)現(xiàn)事件驅(qū)動(dòng)架構(gòu)。您可以發(fā)出事件,而不是輪詢數(shù)據(jù)庫或文件存儲(chǔ)以獲取更改。
但你應(yīng)該如何處理這些事件呢?
實(shí)際上,你有兩個(gè)選擇:
在上述事件驅(qū)動(dòng)模式中,我特別提到了選項(xiàng) #1。這是模式,也是大多數(shù)人選擇的模式。
為什么?消息隊(duì)列是一種持久、靈活且的數(shù)據(jù)到達(dá)方式。消息隊(duì)列的優(yōu)點(diǎn)有兩個(gè):
首先,您通過以下方式解決我們開始的兩個(gè)問題:
其次,大多數(shù)消息隊(duì)列允許任意數(shù)量的下游消費(fèi)者連接并訂閱新消息。因此,如果 4 個(gè)不同的團(tuán)隊(duì)構(gòu)建 8 個(gè)不同的東西,想要以 16 種不同的方式訪問數(shù)據(jù),他們就可以各自完成自己的事情,而不會(huì)互相干擾。
消息隊(duì)列并不是處理事件驅(qū)動(dòng)的實(shí)時(shí)數(shù)據(jù)攝取的方法,但它們是迄今為止較受歡迎的方法,因?yàn)樗鼈儗⒃磾?shù)據(jù)與消費(fèi)者解耦,并且足夠靈活,可以同時(shí)處理許多不同的消費(fèi)者。
如果團(tuán)隊(duì)只想每天獲取更改,他們可以批量使用昨天的消息。但是,如果另一個(gè)團(tuán)隊(duì)想要實(shí)時(shí)使用消息,他們可以監(jiān)視新消息并在數(shù)據(jù)到達(dá)時(shí)自動(dòng)觸發(fā)其流程。
該模型非常適合數(shù)據(jù)庫和文件,但它確實(shí)需要額外的中介服務(wù)。隨著事件驅(qū)動(dòng)架構(gòu)和實(shí)現(xiàn)的增長(zhǎng),您可能會(huì)投入大量資源來維護(hù)和擴(kuò)展消息隊(duì)列或事件流平臺(tái)??紤]到事件驅(qū)動(dòng)架構(gòu)所實(shí)現(xiàn)的所有實(shí)時(shí)用例,這可能是一個(gè)值得的權(quán)衡。
那么,您可以跳過隊(duì)列嗎?
在某些情況下,您可以讓事件直接觸發(fā)流程。例如,您可以將 Amazon S3 配置為直接觸發(fā) AWS Lambda 函數(shù),從而允許您立即處理單個(gè)事件。您可以使用其他處理框架(例如 Apache NiFi 或 Apache Flink)復(fù)制此模型。
現(xiàn)在,這種方法有利有弊。較大的優(yōu)點(diǎn)是您可以省去另一個(gè)中間服務(wù),因此它既便宜又簡(jiǎn)單。當(dāng)您立即調(diào)用處理函數(shù)時(shí),您還可以較大限度地減少延遲并保持?jǐn)?shù)據(jù)新鮮度。
更簡(jiǎn)單的用例,您可以跳過消息隊(duì)列并使用無服務(wù)器函數(shù)根據(jù)源文件系統(tǒng)中的更新立即觸發(fā)進(jìn)程。
然而,也有缺點(diǎn)。消息隊(duì)列提供了您在處理框架中可能無法獲得的持久性級(jí)別,這可能會(huì)使處理故障變得更加困難。
你也會(huì)失去一些靈活性。由于您避開了“發(fā)布/訂閱”模型,因此您可能會(huì)直接將事件發(fā)送到單個(gè)處理器,而不是將它們發(fā)布到多個(gè)處理器可以根據(jù)需要進(jìn)行訂閱的隊(duì)列。
例如,如果您將事件發(fā)送到 SQS,您可以連接一堆不同的工具(例如 Apache NiFi、Apache Flink、Striim、StreamSets)或位于小型、廉價(jià)的 EC2 服務(wù)器上的您自己的代碼來處理事件。如果您直接將事件發(fā)送到 Lambda,則沒有這種靈活性。
將此模式應(yīng)用于數(shù)據(jù)庫也更困難。對(duì)于文件,事件往往較少,因?yàn)槊總€(gè)事件代表一大塊數(shù)據(jù)(文件),并且很容易定義一個(gè)流程“當(dāng)我獲取文件時(shí),執(zhí)行此操作,然后結(jié)束”。
當(dāng)您有來自應(yīng)用程序數(shù)據(jù)庫的更改流時(shí),這會(huì)更加困難。啟動(dòng)和停止進(jìn)程會(huì)產(chǎn)生開銷,如果您不斷收到變化流,您不希望為每個(gè)事件啟動(dòng)的進(jìn)程。您通常需要一個(gè)長(zhǎng)期運(yùn)行的進(jìn)程來消耗事件并將它們作為連續(xù)流進(jìn)行處理。
較終,這兩種方法都可以用于事件驅(qū)動(dòng)的文件攝取,但較好使用隊(duì)列進(jìn)行數(shù)據(jù)庫更改。
我在這里介紹了一些不同的模式,用于從數(shù)據(jù)庫和文件捕獲和集成事件驅(qū)動(dòng)的數(shù)據(jù)。對(duì)于數(shù)據(jù)庫,您可以修改后端代碼以在數(shù)據(jù)庫之前通過 API 調(diào)用發(fā)出事件,或者選擇更改數(shù)據(jù)捕獲工具來監(jiān)視數(shù)據(jù)庫日志文件并在數(shù)據(jù)庫之后發(fā)出有關(guān)更改的事件。對(duì)于文件,您可以使用云原生消息服務(wù)將事件發(fā)送到消息隊(duì)列或直接使用無服務(wù)器函數(shù)觸發(fā)進(jìn)程。
較終,這些方法中的任何一種都將幫助您較大限度地減少源數(shù)據(jù)系統(tǒng)的負(fù)載,并在數(shù)據(jù)到達(dá)數(shù)據(jù)消耗流程時(shí)提高數(shù)據(jù)的新鮮度。
當(dāng)然,并非每個(gè)用例都需要新鮮數(shù)據(jù)。例如,商業(yè)智能 (BI) 報(bào)告通??梢悦刻??批量生成。但實(shí)時(shí)運(yùn)營(yíng)分析、產(chǎn)品內(nèi)分析、實(shí)時(shí)個(gè)性化和異常檢測(cè)、智能庫存管理和游戲等運(yùn)營(yíng)和面向用戶的功能確實(shí)需要新鮮數(shù)據(jù)。如果您使用基于輪詢的方法從源系統(tǒng)捕獲數(shù)據(jù),則您根本無法訪問新數(shù)據(jù),并且無法執(zhí)行這些用例。他們簡(jiǎn)直是不可能的。
如果您正在嘗試構(gòu)建任何這些實(shí)時(shí)用例,或者正在評(píng)估可幫助您轉(zhuǎn)向事件驅(qū)動(dòng)架構(gòu)和實(shí)時(shí)數(shù)據(jù)處理的工具,您還應(yīng)該考慮嘗試一下Tinybird。Tinybird 可讓您統(tǒng)式和批處理數(shù)據(jù)源,使用 SQL 連接和轉(zhuǎn)換它們,并以高并發(fā)、低延遲的 API 形式與內(nèi)部利益相關(guān)者快速共享您的實(shí)時(shí)數(shù)據(jù)產(chǎn)品。Tinybird構(gòu)建計(jì)劃是的,沒有時(shí)間限制,甚至還有模擬數(shù)據(jù)流工作流程,以防您只是為了學(xué)習(xí)該工具而不想自帶數(shù)據(jù)。
微信選課
享更多優(yōu)質(zhì)好課!