微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案_第1頁
微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案_第2頁
微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案_第3頁
微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案_第4頁
微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 微服務(wù)的數(shù)據(jù)一致性分發(fā)問題解決方案 介紹系統(tǒng)架構(gòu)微服務(wù)化以后,根據(jù)微服務(wù)獨(dú)立數(shù)據(jù)源的思想,每個(gè)微服務(wù)一般具有各自獨(dú)立的數(shù)據(jù)源,但是不同微服務(wù)之間難免需要通過數(shù)據(jù)分發(fā)來共享一些數(shù)據(jù),這個(gè)就是微服務(wù)的數(shù)據(jù)分發(fā)問題。Netflix/Airbnb等一線互聯(lián)網(wǎng)公司的實(shí)踐參考附錄1/2/3表明,數(shù)據(jù)一致性分發(fā)能力,是構(gòu)建松散耦合、可擴(kuò)展和高性能的微服務(wù)架構(gòu)的基礎(chǔ)。本文解釋分布式微服務(wù)中的數(shù)據(jù)一致性分發(fā)問題,應(yīng)用場(chǎng)景,并給出常見的解決方法。本文主要面向互聯(lián)網(wǎng)分布式系統(tǒng)架構(gòu)師和研發(fā)經(jīng)理。為啥要分發(fā)數(shù)據(jù)?場(chǎng)景?我們還是要從具體業(yè)務(wù)場(chǎng)景出發(fā),為啥要分發(fā)數(shù)據(jù)?有哪些場(chǎng)景?在實(shí)際企業(yè)中,數(shù)據(jù)分發(fā)的場(chǎng)景其實(shí)是非常多的

2、。假設(shè)某電商企業(yè)有這樣一個(gè)訂單服務(wù)Order Service,它有一個(gè)獨(dú)立的數(shù)據(jù)庫(kù)。同時(shí),周邊還有不少系統(tǒng)需要訂單的數(shù)據(jù),上圖給出了一些例子:一個(gè)是緩存系統(tǒng),為了提升訂單數(shù)據(jù)的訪問性能,我們可以把頻繁訪問的訂單數(shù)據(jù),通過Redis緩存起來;第二個(gè)是Fulfillment Service,也就是訂單履行系統(tǒng),它也需要一份訂單數(shù)據(jù),借此實(shí)現(xiàn)訂單履行的功能;第三個(gè)是ElasticSearch搜索引擎系統(tǒng),它也需要一份訂單數(shù)據(jù),可以支持前臺(tái)用戶、或者是后臺(tái)運(yùn)營(yíng)快速查詢訂單信息;第四個(gè)是傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng),它也需要一份訂單數(shù)據(jù),支持對(duì)訂單數(shù)據(jù)的分析和挖掘。當(dāng)然,為了獲得一份訂單數(shù)據(jù),這些系統(tǒng)可以定期去訂單

3、服務(wù)查詢最新的數(shù)據(jù),也就是拉模式,但是拉模式有兩大問題:一個(gè)是拉數(shù)據(jù)通常會(huì)有延遲,也就是說拉到的數(shù)據(jù)并不實(shí)時(shí);如果頻繁拉的話,考慮到外圍系統(tǒng)眾多(而且可能還會(huì)增加),勢(shì)必會(huì)對(duì)訂單數(shù)據(jù)庫(kù)的性能造成影響,嚴(yán)重時(shí)還可能會(huì)把訂單數(shù)據(jù)庫(kù)給拉掛。所以,當(dāng)企業(yè)規(guī)模到了一定階段,還是需要考慮數(shù)據(jù)分發(fā)技術(shù),將業(yè)務(wù)數(shù)據(jù)同步分發(fā)到對(duì)數(shù)據(jù)感興趣的其它服務(wù)。除了上面提到的一些數(shù)據(jù)分發(fā)場(chǎng)景,其實(shí)還有很多其它場(chǎng)景,例如:第一個(gè)是數(shù)據(jù)復(fù)制(replication)。為了實(shí)現(xiàn)高可用,一般要將數(shù)據(jù)復(fù)制多分存儲(chǔ),這個(gè)時(shí)候需要采用數(shù)據(jù)分發(fā)。第二個(gè)是支持?jǐn)?shù)據(jù)庫(kù)的解耦拆分。在單體數(shù)據(jù)庫(kù)解耦拆分的過程中,為了實(shí)現(xiàn)不停機(jī)拆分,在一段時(shí)間內(nèi),

4、需要將遺留老數(shù)據(jù)同步復(fù)制到新的數(shù)據(jù)存儲(chǔ),這個(gè)時(shí)候也需要數(shù)據(jù)分發(fā)技術(shù)。第三個(gè)是實(shí)現(xiàn)CQRS,還有去數(shù)據(jù)庫(kù)Join。這兩個(gè)場(chǎng)景我后面有單獨(dú)文章解釋,這邊先說明一下,實(shí)現(xiàn)CQRS和數(shù)據(jù)庫(kù)去Join的底層技術(shù),其實(shí)也是數(shù)據(jù)分發(fā)。第四個(gè)是實(shí)現(xiàn)分布式事務(wù)。這個(gè)場(chǎng)景我后面也有單獨(dú)文章講解,這邊先說明一下,解決分布式事務(wù)問題的一些方案,底層也是依賴于數(shù)據(jù)分發(fā)技術(shù)的。其它還有流式計(jì)算、大數(shù)據(jù)BI/AI,還有審計(jì)日志和歷史數(shù)據(jù)歸檔等場(chǎng)景,一般都離不開數(shù)據(jù)分發(fā)技術(shù)??傊úㄕJ(rèn)為,數(shù)據(jù)分發(fā),是構(gòu)建現(xiàn)代大規(guī)模分布式系統(tǒng)、微服務(wù)架構(gòu)和異步事件驅(qū)動(dòng)架構(gòu)的底層基礎(chǔ)技術(shù)。雙寫?對(duì)于數(shù)據(jù)分發(fā)這個(gè)問題,乍一看,好像并不復(fù)雜,稍有

5、開發(fā)經(jīng)驗(yàn)的同學(xué)會(huì)說,我在應(yīng)用層做一個(gè)雙寫不就可以了嗎?比方說,請(qǐng)看上圖右邊,這里有一個(gè)微服務(wù)A,它需要把數(shù)據(jù)寫入DB,同時(shí)還要把數(shù)據(jù)寫到MQ,對(duì)于這個(gè)需求,我在A服務(wù)中弄一個(gè)雙寫,不就搞定了嗎?其實(shí)這個(gè)問題并沒有那么簡(jiǎn)單,關(guān)鍵是你如何才能保證雙寫的事務(wù)性?請(qǐng)看上圖左邊的代碼,這里有一個(gè)方法updateDbThenSendMsgInTransaction,這個(gè)方法上加了事務(wù)性標(biāo)注,也就是說,如果拋異常的話,數(shù)據(jù)庫(kù)操作會(huì)回滾。我們來看這個(gè)方法的執(zhí)行步驟:第一步先更新數(shù)據(jù)庫(kù),如果更新成功,那么result設(shè)為true,如果更新失敗,那么result設(shè)為false;第二步,如果result為true,

6、也就是說DB更新成功,那么我們就繼續(xù)做第三步,向mq發(fā)送消息如果發(fā)消息也成功,那么我們的流程就走到第四步,整個(gè)雙寫事務(wù)就成功了。如果發(fā)消息拋異常,也就是發(fā)消息失敗,那么容器會(huì)執(zhí)行該方法的事務(wù)性回滾,上面的數(shù)據(jù)庫(kù)更新操作也會(huì)回滾。初看這個(gè)雙寫流程沒有問題,可以保證事務(wù)性。但是深入研究會(huì)發(fā)現(xiàn)它其實(shí)是有問題的。比方說在第三步,如果發(fā)消息拋異常了,并不保證說發(fā)消息失敗了,可能只是由于網(wǎng)絡(luò)異常抖動(dòng)而造成的拋異常,實(shí)際消息可能是已經(jīng)發(fā)到MQ中,但是拋異常會(huì)造成上面數(shù)據(jù)庫(kù)更新操作的回滾,結(jié)果造成兩邊數(shù)據(jù)不一致。模式一:事務(wù)性發(fā)件箱(Transactional Outbox)對(duì)于事務(wù)性雙寫這個(gè)問題,業(yè)界沉淀下

7、來比較實(shí)踐的做法,其中一種,就是采用所謂事務(wù)性發(fā)件箱模式,英文叫Transactional Outbox。據(jù)說這個(gè)模式是eBay最早發(fā)明和使用的。事務(wù)性發(fā)件箱模式不難理解,請(qǐng)看上圖。我們?nèi)匀灰杂唵蜲rder服務(wù)為例。在數(shù)據(jù)庫(kù)中,除了訂單Order表,為了實(shí)現(xiàn)事務(wù)性雙寫,我們還需增加了一個(gè)發(fā)件箱Outbox表。Order表和Outbox表都在同一個(gè)數(shù)據(jù)庫(kù)中,對(duì)它們進(jìn)行同時(shí)更新的話,通過數(shù)據(jù)庫(kù)的事務(wù)機(jī)制,是可以實(shí)現(xiàn)事務(wù)性更新的。下面我們通過例子來展示這個(gè)流程,我們這里假定Order Service要添加一個(gè)新訂單。首先第一步,Order Service先將新訂單數(shù)據(jù)寫入Order表,然后它再向Ou

8、tbox表中寫入一條訂單新增記錄,這兩個(gè)DB操作可以包在一個(gè)DB事務(wù)里頭,也就是可以實(shí)現(xiàn)事務(wù)性寫入。然后第二步,我們?cè)僖胍粋€(gè)稱為消息中繼Message Relay的角色,它負(fù)責(zé)定期Poll拉取Outbox中的新數(shù)據(jù),然后第三步再Publish發(fā)送到MQ。如果寫入MQ確認(rèn)成功,Message Relay就可以將Outbox中的對(duì)應(yīng)記錄標(biāo)記為已消費(fèi)。這里可能會(huì)出現(xiàn)一種異常情況,就是Message Relay在將消息發(fā)送到MQ時(shí),發(fā)生了網(wǎng)絡(luò)抖動(dòng),實(shí)際消息可能已經(jīng)寫入MQ,但是Message Relay并沒有得到確認(rèn),這時(shí)候它會(huì)重發(fā),直到明確成功為止。所以,這里也是一個(gè)At Least Once,也

9、就是至少交付一次的消費(fèi)語義,消息可能被重復(fù)投遞。因此,MQ之后的消費(fèi)方要做消息去重或冪等處理??傊聞?wù)性發(fā)件箱模式可以保證,對(duì)Order表的修改,然后將對(duì)應(yīng)事件發(fā)送到MQ,這兩個(gè)動(dòng)作可以實(shí)現(xiàn)事務(wù)性,也就是實(shí)現(xiàn)數(shù)據(jù)分發(fā)的事務(wù)性。注意,這里的Message Relay角色既可以是一個(gè)獨(dú)立部署的服務(wù),也可以和Order Service住在一起。生產(chǎn)實(shí)踐中,需要考慮Message Relay的高可用部署,還有監(jiān)控和告警,否則如果Message Relay掛了,消息就發(fā)不出來,然后,依賴于消息的各種消費(fèi)方也將無法正常工作。Transactional Outbox參考實(shí)現(xiàn) Killbill Common

10、 Queue事務(wù)性發(fā)件箱的原理簡(jiǎn)單,實(shí)現(xiàn)起來也不復(fù)雜,波波這邊推薦一個(gè)生產(chǎn)級(jí)的參考實(shí)現(xiàn)。這個(gè)實(shí)現(xiàn)源于一個(gè)叫killbill的項(xiàng)目,killbill是美國(guó)高朋(GroupOn)公司開源的訂閱計(jì)費(fèi)和支付平臺(tái),這個(gè)項(xiàng)目已經(jīng)有超過89年的歷史,在高朋等公司已經(jīng)有不少落地案例,是一個(gè)比較成熟的產(chǎn)品。killbill項(xiàng)目里頭有一些公共庫(kù),單獨(dú)放在一個(gè)叫killbill-commons的子項(xiàng)目里頭,其中有一個(gè)叫killbill common queue,它其實(shí)是事務(wù)性發(fā)件箱的一個(gè)生產(chǎn)級(jí)實(shí)現(xiàn)。上圖有給出這個(gè)queue的github鏈接。Killbill common queue也是一個(gè)基于DB實(shí)現(xiàn)的分布式的隊(duì)

11、列,它上層還包裝了EventBus事件總線機(jī)制。killbill common queue的總體設(shè)計(jì)思路不難理解,請(qǐng)看上圖:在上圖的左邊,killbill common queue提供發(fā)送消息API,并且是支持事務(wù)的。比方說圖上的postFromTransaction方法,它可以發(fā)送一個(gè)BusEvent事件到DB Queue當(dāng)中,這個(gè)方法還接受一個(gè)數(shù)據(jù)庫(kù)連接Connection參數(shù),killbill common queue可以保證對(duì)事件event的數(shù)據(jù)庫(kù)寫入,和使用同一個(gè)Connection的其它數(shù)據(jù)庫(kù)寫入操作,發(fā)生在同一個(gè)事務(wù)中。這個(gè)做法其實(shí)就是一種事務(wù)性發(fā)件箱的實(shí)現(xiàn),這里的發(fā)件箱存的就是

12、事件event。除了POST寫入API,killbill common queue還支持類似前面提到的Message Relay的功能,并且是包裝成EeventBus + Handler方式來實(shí)現(xiàn)的。開發(fā)者只需要實(shí)現(xiàn)事件處理器,并且注冊(cè)訂閱在EventBus上,就可以接收到DB Queue,也就是發(fā)件箱當(dāng)中的新事件,并進(jìn)行消費(fèi)處理。如果事件處理成功,那么EvenbBus會(huì)將對(duì)應(yīng)的事件從發(fā)件箱中移走;如果事件處理不成功,那么EventBus會(huì)負(fù)責(zé)重試,直到處理成功,或者超過最大重試次數(shù),那么它會(huì)將該事件標(biāo)記為處理失敗,并移到歷史歸檔表中,等待后續(xù)人工檢查和干預(yù)。這個(gè)EventBus的底層,其實(shí)有

13、一個(gè)Dispatcher派遣線程,它負(fù)責(zé)定期掃描DB Queue(也就是發(fā)件箱)中的新事件,有的話就批量拉取出來,并發(fā)送到內(nèi)部EventBus的隊(duì)列中,如果內(nèi)部隊(duì)列滿了,那么Dispather Thread也會(huì)暫停拉取新事件。在killbill common queue的設(shè)計(jì)中,每個(gè)節(jié)點(diǎn)上的Dispather線程只負(fù)責(zé)通過自己這個(gè)節(jié)點(diǎn)寫入的事件,并且在一個(gè)節(jié)點(diǎn)上,Dispather線程也只有一個(gè),這樣才能保證消息消費(fèi)的順序性,并且也不會(huì)重復(fù)消費(fèi)。Reaper機(jī)制killbill common queue,其實(shí)是一個(gè)基于集中式數(shù)據(jù)庫(kù)實(shí)現(xiàn)的分布式隊(duì)列,為什么說它是分布式隊(duì)列呢?請(qǐng)看上圖,killb

14、ill common queue的設(shè)計(jì)是這樣的,它的每個(gè)節(jié)點(diǎn),只負(fù)責(zé)消費(fèi)處理從自己這個(gè)節(jié)點(diǎn)寫入的事件。比方說上圖中有藍(lán)色/黃色和綠色3個(gè)節(jié)點(diǎn),那么藍(lán)色節(jié)點(diǎn),只負(fù)責(zé)從藍(lán)色節(jié)點(diǎn)寫入,在數(shù)據(jù)庫(kù)中標(biāo)記為藍(lán)色的事件。同樣,黃色節(jié)點(diǎn),只負(fù)責(zé)從黃色節(jié)點(diǎn)寫入,在數(shù)據(jù)庫(kù)中標(biāo)記為黃色的事件。綠色節(jié)點(diǎn)也是類似。這是一種分布式的設(shè)計(jì),如果處理容量不夠,只需按需添加更多節(jié)點(diǎn),就可以實(shí)現(xiàn)負(fù)載分?jǐn)?。這里有個(gè)問題,如果其中某個(gè)節(jié)點(diǎn)掛了,比方說上圖的藍(lán)色節(jié)點(diǎn)掛了,那么誰來繼續(xù)消費(fèi)數(shù)據(jù)庫(kù)中藍(lán)色的,還沒有來得及處理的事件呢?為了解決這個(gè)問題,killbill common queue設(shè)計(jì)了一種稱為reaper收割機(jī)的機(jī)制。每個(gè)節(jié)點(diǎn)

15、上都還住了一個(gè)收割機(jī)線程,它們會(huì)定期檢查數(shù)據(jù)庫(kù),看有沒有長(zhǎng)時(shí)間無人處理的事件,如果有,就搶占標(biāo)記為由自己負(fù)責(zé)。比方說上圖的右邊,最終黃色節(jié)點(diǎn)上的收割機(jī)線程搶到了原來由藍(lán)色節(jié)點(diǎn)負(fù)責(zé)的事件,那么它會(huì)把這些事件標(biāo)記為黃色,也就是由自己來負(fù)責(zé)。收割機(jī)機(jī)制,保證了killbill common queue的高可用性,相當(dāng)于保證了事務(wù)性發(fā)件箱中的Message Relay的高可用性。Killbill PersistentBus表結(jié)構(gòu)基于killbill common queue的EventBus,也被稱為killbill PersistentBus。上圖給出了它的數(shù)據(jù)庫(kù)表結(jié)構(gòu),其中bus_events就是

16、用來存放待處理事件的,相當(dāng)于發(fā)件箱,主要的字段包括:event_json,存放json格式的原始數(shù)據(jù)。creating_owner,記錄創(chuàng)建節(jié)點(diǎn),也就是事件是由哪個(gè)節(jié)點(diǎn)寫入的。processingowner,記錄處理節(jié)點(diǎn),也就是事件最終是由哪個(gè)節(jié)點(diǎn)處理的;通常由creatingowner自己處理,但也可能被收割,由其它節(jié)點(diǎn)處理。processing_state,當(dāng)前的處理狀態(tài)。error_count,處理錯(cuò)誤計(jì)數(shù),超過一定計(jì)數(shù)會(huì)被標(biāo)記為處理失敗。當(dāng)前處理狀態(tài)主要包括6種:AVAILABLE,表示待處理IN_PROCESSING,表示已經(jīng)被dispatcher線程取走,正在處理中PROCESSE

17、D,表示已經(jīng)處理REMOVED,表示已經(jīng)被刪除FAILED,表示處理失敗REPEATED,表示被其它節(jié)點(diǎn)收割了除了bus_events待處理事件表,還有一個(gè)對(duì)應(yīng)的bus-events-history事件歷史記錄表。不管成功還是失敗,最終,事件會(huì)被寫入歷史記錄表進(jìn)行歸檔,作為事后審計(jì)或者人工干預(yù)的依據(jù)。上圖下方給出了數(shù)據(jù)庫(kù)表的github鏈接,你可以進(jìn)一步參考學(xué)習(xí)。Killbill PersistentBus處理狀態(tài)遷移上圖給出了killbill PersistentBus的事件處理狀態(tài)遷移圖。剛開始事件處于AVAILABLE待處理狀態(tài);之后事件被dispatcher線程拉取,進(jìn)入IN_PROC

18、ESSING處理中狀態(tài);之后,如果事件處理器成功處理了事件,那么事件就進(jìn)入PROCESSED已經(jīng)處理狀態(tài);如果事件處理器處理事件失敗,那么事件的錯(cuò)誤計(jì)數(shù)會(huì)被增加1,如果錯(cuò)誤計(jì)數(shù)還沒有超過最大失敗重試閥值,那么事件就會(huì)重新進(jìn)入AVAILABLE狀態(tài);如果事件的錯(cuò)誤數(shù)量超過了最大失敗重試閥值,那么事件就會(huì)進(jìn)入FAILED失敗狀態(tài);如果負(fù)責(zé)待處理事件的節(jié)點(diǎn)掛了,那么到達(dá)一定的時(shí)間間隔,對(duì)應(yīng)的事件會(huì)被收割進(jìn)入REAPED被收割狀態(tài)。上圖有一個(gè)通過API觸發(fā)進(jìn)入的REMOVED移除狀態(tài),這個(gè)是給通知隊(duì)列用的,用戶可以通過API移除對(duì)應(yīng)的通知消息。順便提一下,除了事件/消息隊(duì)列,Killbill queu

19、e也是支持通知隊(duì)列(或者說延遲消息隊(duì)列)的。模式二:變更數(shù)據(jù)捕獲(Change Data Capture, CDC)對(duì)于事務(wù)性雙寫這個(gè)問題,業(yè)界沉淀下來比較實(shí)踐的做法,其中第二種,就是所謂的變更數(shù)據(jù)捕獲,英文稱為Change Data Capture,簡(jiǎn)稱CDC。變更數(shù)據(jù)捕獲的原理也不復(fù)雜,它利用了數(shù)據(jù)庫(kù)的事務(wù)日志記錄。一般數(shù)據(jù)庫(kù),對(duì)于變更提交操作,都記錄所謂事務(wù)日志Transaction Log,也稱為提交日志Commit Log,比方說MySQL支持binlog,Postgres支持Write Ahead log。事務(wù)日志可以簡(jiǎn)單理解為數(shù)據(jù)庫(kù)本地的一個(gè)文件隊(duì)列,它記錄了按時(shí)間順序發(fā)生的對(duì)數(shù)

20、據(jù)庫(kù)表的變更提交記錄。下面我們通過例子來展示這個(gè)變更數(shù)據(jù)捕獲的流程,我們這里假定Order Service要添加一個(gè)新訂單。第一步,Order Service將新訂單記錄寫入Order表,并且提交。因?yàn)檫@是一次表變更操作,所以這次變更會(huì)被記錄到數(shù)據(jù)庫(kù)的事務(wù)日志當(dāng)中,其中內(nèi)容包括發(fā)生的變更數(shù)據(jù)。第二步,我們還需要引入一個(gè)稱為Transaction Log Miner這樣的角色,這個(gè)Miner負(fù)責(zé)訂閱在事務(wù)日志隊(duì)列上,如果有新的變更記錄,Miner就會(huì)捕獲到變更記錄。然后第三步,Miner會(huì)將變更記錄發(fā)送到MQ消息隊(duì)列。同之前的Message Relay一樣,這里的發(fā)送到MQ也是At Least

21、Once語義,消息可能會(huì)被重復(fù)發(fā)送,所以MQ之后的消費(fèi)者需要做去重或者冪等處理??傊?,CDC技術(shù)同樣可以保證,對(duì)Order表的修改,然后將對(duì)應(yīng)事件發(fā)送到MQ,這兩個(gè)動(dòng)作可以實(shí)現(xiàn)事務(wù)性,也就是實(shí)現(xiàn)數(shù)據(jù)分發(fā)的事務(wù)性。注意,這里的CDC一般是一個(gè)獨(dú)立部署的服務(wù),生產(chǎn)中需要做好高可用部署,并且做好監(jiān)控告警。否則如果CDC掛了,消息也就發(fā)不出來,然后,依賴于消息的各種消費(fèi)方也將無法正常工作。CDC開源項(xiàng)目(企業(yè)級(jí))當(dāng)前,有幾個(gè)比較成熟的企業(yè)級(jí)的CDC開源項(xiàng)目,我這邊收集了一些,供大家學(xué)習(xí)參考:第一個(gè)是阿里開源的Canal,目前在github上有超過1.4萬顆星,這個(gè)項(xiàng)目在國(guó)內(nèi)用得比較多,之前在拍拍貸的實(shí)

22、時(shí)數(shù)據(jù)場(chǎng)景,Canal也有不少成功的應(yīng)用。Canal主要支持MySQL binlog的增量訂閱和消費(fèi)。它是基于MySQL的Master/Slave機(jī)制,它的Miner角色是通過偽裝成Slave來實(shí)現(xiàn)的。這個(gè)項(xiàng)目的使用文檔相對(duì)比較完善,建議大家一步參考學(xué)習(xí)。第二個(gè)是Redhat開源的Debezium,目前在github上有超過3.2k星,這個(gè)項(xiàng)目在國(guó)外用得較多。Debezium主要是在Kafka Connect的基礎(chǔ)上開發(fā)的,它不僅支持mysql數(shù)據(jù)庫(kù),還支持postgres/sqlserver/mongodb等數(shù)據(jù)庫(kù)。第三個(gè)是Zendesk開源的Maxwell,目前在github上有超過2.1

23、k星。Maxwell是一個(gè)輕量級(jí)的CDC Deamon,主要支持MySQL binlog的變更數(shù)據(jù)捕獲和處理。第四個(gè)是Airbnb開源的SpinalTap,目前在github上有兩百多顆星。SpinalTap主要支持MySQL binlog的變更捕獲和處理。這個(gè)項(xiàng)目的星雖然不多,但是它是在Airbnb SOA服務(wù)化過程中,通過實(shí)踐落地出來的一個(gè)項(xiàng)目,值得參考。對(duì)于上面的這些項(xiàng)目,如果你想生產(chǎn)使用的話,波波推薦的是阿里的Canal,因?yàn)檫@個(gè)項(xiàng)目畢竟是國(guó)內(nèi)大廠阿里落地出來,而且在國(guó)內(nèi)已經(jīng)有不少企業(yè)落地案例。其它幾個(gè)項(xiàng)目,你也可以參考研究。學(xué)習(xí)參考 Eventuate-Tram既然談到這個(gè)CDC,這

24、里有必要提到一個(gè)人和一本書,這個(gè)人叫Chris Chardson,他是美國(guó)的老一輩的技術(shù)大牛,曾今是第一代的Cloud Foundry項(xiàng)目的創(chuàng)始人(后來Cloud Foundry被Pivotal所收購(gòu))。近幾年,Chris Chardson開始轉(zhuǎn)戰(zhàn)微服務(wù)領(lǐng)域,這兩年,他還專門寫了一本書,叫微服務(wù)設(shè)計(jì)模式,英文名是Microservices Patterns。這本書主要是講微服務(wù)架構(gòu)和設(shè)計(jì)模式的,內(nèi)容還不錯(cuò),是我推薦大家閱讀的。Charis Chardson還專門開發(fā)了一個(gè)叫Eventuate-Tram的開源項(xiàng)目(這個(gè)項(xiàng)目也有商業(yè)版),另外他的微服務(wù)書里頭也詳細(xì)介紹了這個(gè)項(xiàng)目。這個(gè)項(xiàng)目可以說是一

25、個(gè)大集成框架,它不僅實(shí)現(xiàn)了DDD領(lǐng)域驅(qū)動(dòng)開發(fā)模式,CQRS命令查詢職責(zé)分離模式,事件溯源模式,還實(shí)現(xiàn)了Saga事務(wù)狀態(tài)機(jī)模式。當(dāng)然,這個(gè)項(xiàng)目的底層也實(shí)現(xiàn)了CDC變更數(shù)據(jù)捕獲模式。波波認(rèn)為,Charis的項(xiàng)目,作為學(xué)習(xí)研究還是有價(jià)值的,但是暫不建議生產(chǎn)級(jí)使用,因?yàn)樗臇|西不是一線企業(yè)落地出來的,主要是他個(gè)人開發(fā)的。至于說Charis的項(xiàng)目能否在一線企業(yè)落地,還有待時(shí)間的進(jìn)一步檢驗(yàn)。Transactional Outbox vs CDC好的,前面我介紹了解決數(shù)據(jù)的事務(wù)性分發(fā)的兩種落地模式,一種是事務(wù)性發(fā)件箱模式,另外一種是變更數(shù)據(jù)捕獲模式,這兩種模式其實(shí)各有優(yōu)劣,為了幫助大家做選型決策,我這邊對(duì)這

26、兩種模式進(jìn)行一個(gè)比較,請(qǐng)看上面的比較表格:首先比較一下復(fù)雜性,事務(wù)性發(fā)件箱相對(duì)比較簡(jiǎn)單,簡(jiǎn)單做法只需要在數(shù)據(jù)庫(kù)中增加一個(gè)發(fā)件箱表,然后再啟一個(gè)Poller線程拉消息和發(fā)消息就可以了。CDC技術(shù)相對(duì)比較復(fù)雜,需要你深入理解數(shù)據(jù)庫(kù)的事務(wù)日志格式和協(xié)議。另外Miner的實(shí)現(xiàn)也不簡(jiǎn)單,要保證不丟消息,如果生產(chǎn)部署的話,還要考慮Miner的高可以部署,還有監(jiān)控告警等環(huán)節(jié)。第二個(gè)比較的是Polling延遲和開銷。事務(wù)性發(fā)件箱的Polling是近實(shí)時(shí)的,同時(shí)如果頻繁拉數(shù)據(jù)庫(kù)表,難免會(huì)有性能開銷。CDC是比較實(shí)時(shí)的,同時(shí)它不侵入數(shù)據(jù)庫(kù)和表,所以它的性能開銷相對(duì)小。第三個(gè)比較的是應(yīng)用侵入性。事務(wù)性發(fā)件箱是有一定的應(yīng)用侵入性的,應(yīng)用在更新業(yè)務(wù)數(shù)據(jù)的同時(shí),還要單獨(dú)發(fā)送消息。CDC對(duì)應(yīng)用是無侵入的,因?yàn)樗〉氖菙?shù)據(jù)庫(kù)事務(wù)日志,這個(gè)和應(yīng)用是不直接耦合的。當(dāng)然,CDC和事務(wù)性發(fā)件箱模式并不排斥,你可以在應(yīng)用層采用事務(wù)性發(fā)件箱模式,同時(shí)仍然采用CDC到數(shù)據(jù)庫(kù)去捕獲和發(fā)件箱中的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論