自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用事件驅(qū)動(dòng)架構(gòu)設(shè)計(jì)大容量系統(tǒng)

譯文 精選
開發(fā) 架構(gòu)
近些年,微服務(wù)風(fēng)格的應(yīng)用架構(gòu)正在扎根并迅速成長(zhǎng),它們可能已散布在企業(yè)生態(tài)系統(tǒng)的方方面面。在多云環(huán)境中組織以及運(yùn)維微服務(wù),圍繞微服務(wù)組織數(shù)據(jù),使數(shù)據(jù)盡可能實(shí)時(shí)傳輸,這些工作正成為我們面臨的挑戰(zhàn)。

?[[441662]]??

【51CTO.com快譯】序幕

近些年,微服務(wù)風(fēng)格的應(yīng)用架構(gòu)正在扎根并迅速成長(zhǎng),它們可能已散布在企業(yè)生態(tài)系統(tǒng)的方方面面。在多云環(huán)境中組織以及運(yùn)維微服務(wù),圍繞微服務(wù)組織數(shù)據(jù),使數(shù)據(jù)盡可能實(shí)時(shí)傳輸,這些工作正成為我們面臨的挑戰(zhàn)。

由于事件驅(qū)動(dòng)架構(gòu) (EDA) 平臺(tái)(例如 Kafka)和數(shù)據(jù)管理技術(shù)(例如 Data Meshes 和 Data Fabrics)的發(fā)展,設(shè)計(jì)基于微服務(wù)的應(yīng)用會(huì)變得更加容易。

然而,為了確保這些基于微服務(wù)的應(yīng)用在對(duì)應(yīng)的級(jí)別上運(yùn)行,必須確保在設(shè)計(jì)期間就考慮到關(guān)鍵的非功能需求(NFRs)。

在一系列博客文章中,我和我的同事 Tanmay Ambre、Harish Bharti試圖用統(tǒng)一的方法來(lái)描述NFR 設(shè)計(jì)。我們稱之為基于用例的方法。

在第一部分中,我們將聊聊“性能”的設(shè)計(jì),它是最關(guān)鍵的NFR需求。本文會(huì)介紹如何對(duì)于大容量、低延遲處理為基礎(chǔ)的架構(gòu)和設(shè)計(jì)進(jìn)行決策。

為了讓決策過程清晰易懂,我們將使用銀行轉(zhuǎn)賬作為演示用例,在簡(jiǎn)化了用例的同時(shí),將關(guān)注點(diǎn)放到性能上。

用例

電子資金轉(zhuǎn)賬 (ETF) 是當(dāng)今通過數(shù)字渠道消費(fèi)的一種非常重要的匯款和收款方式。這也是為什么我們使用該用例來(lái)解釋與性能相關(guān)的決策,因?yàn)樵谟美袝?huì)涉及到海量請(qǐng)求以及多分布式協(xié)調(diào)等諸多問題,并且不用考慮誤差范圍(包括:可靠性和容錯(cuò)問題)。

在過去,資金轉(zhuǎn)賬需要數(shù)天時(shí)間。還會(huì)涉及前往銀行或者開支票的過程。然而,隨著數(shù)字化、新支付機(jī)制、支付網(wǎng)關(guān)的出現(xiàn)以及相關(guān)規(guī)定的影響下,資金轉(zhuǎn)賬在瞬間就可以完成。例如,2021 年 9 月,在 UPI 網(wǎng)絡(luò)上就發(fā)生了 36 億筆交易,交易總價(jià)值 約合6.5 萬(wàn)億印度盧比??蛻舾呄蛴谕ㄟ^各種渠道進(jìn)行實(shí)時(shí)支付。PSD2、開放銀行和特定國(guó)家/地區(qū)已經(jīng)通過相關(guān)法規(guī),法規(guī)明確規(guī)定向受信任的第三方應(yīng)用程序開發(fā)人員公開其支付機(jī)制。

通常,銀行客戶會(huì)使用任意渠道(例如,移動(dòng)應(yīng)用程序、在線門戶或訪問機(jī)構(gòu))發(fā)起轉(zhuǎn)賬請(qǐng)求。當(dāng)收到轉(zhuǎn)賬請(qǐng)求后,需要執(zhí)行以下操作,如圖1 所示:

1. 鑒定轉(zhuǎn)賬資格(Entitlement)——檢查客戶是否具備轉(zhuǎn)賬的資格

2. 檢查操作權(quán)限(Operational limits)(是否具備使用轉(zhuǎn)賬通道和傳輸模式的權(quán)利)

3. 檢查余額并鎖定轉(zhuǎn)賬金額(Account Balance checks)

4. 制裁檢查(Sanctions Check) —— 交易是否符合法規(guī)以及制裁檢查

5. 欺詐檢查(Fraud Checks) —— 檢查交易是否具有欺詐性

6. 在支付網(wǎng)關(guān)中創(chuàng)建支付請(qǐng)求(Payment Gateway)

下圖對(duì)此進(jìn)行了概述:

???

圖1 收到轉(zhuǎn)賬請(qǐng)求需要執(zhí)行的操作

注意:就本文而言,以上用例所涉及到的操作會(huì)在發(fā)起請(qǐng)求的金融機(jī)構(gòu)內(nèi)部完成。它依賴于已存在的轉(zhuǎn)賬網(wǎng)關(guān),支付網(wǎng)關(guān)并在此范疇內(nèi)。

關(guān)鍵的非功能性需求

以下是關(guān)鍵的 NFR(非功能性需求):

1. 性能


  • 事件的低延遲處理
  • 高吞吐量

2. 彈性


  • 可恢復(fù)性——從故障中恢復(fù)的能力。從故障點(diǎn)重新啟動(dòng)并具有重放事件的能力。最小化 RTO(恢復(fù)時(shí)間目標(biāo))
  • 零數(shù)據(jù)丟失
  • 保證結(jié)果的可靠性和一致性。

3. 可用性和可擴(kuò)展性


  • 高可用和容錯(cuò)——承擔(dān)故障(包括承擔(dān)數(shù)據(jù)中心/可用區(qū)域的中斷情況)
  • 隨著負(fù)載增加而對(duì)系統(tǒng)進(jìn)行水平擴(kuò)展
  • 能夠承受突發(fā)的流量激增(彈性可擴(kuò)展性)
  • 在符合法規(guī)的前提下持久化海量數(shù)據(jù)

4. 安全


  • 應(yīng)用中核心組件安全性——左移(Shifting left 未雨綢繆)(備注:軟件開發(fā)過程被視為一個(gè)從左到右的順序過程。例如:定義需求、分析、設(shè)計(jì)、編碼、測(cè)試和部署。左移就提前考慮某某問題,不要等到了這一步再思考這個(gè)問題,放到文中就是提前考慮核心組件安全性的問題。因此翻譯為“未雨綢繆”)
  • 認(rèn)證和授權(quán)
  • 審計(jì)
  • 傳輸層安全
  • 保證數(shù)據(jù)在傳輸狀態(tài)和靜止?fàn)顟B(tài)的安全性

架構(gòu)

云原生技術(shù)的方方面面將會(huì)貫穿本案例的實(shí)現(xiàn)模型——例如:微服務(wù)、API、容器、事件流和分布式數(shù)據(jù)管理,以及使用最終一致性風(fēng)格的數(shù)據(jù)持久化方式來(lái)保證數(shù)據(jù)的完整性。需要注意的是,基于事件驅(qū)動(dòng)的微服務(wù)架構(gòu)為本案例架構(gòu)提供了最佳實(shí)踐。

以下是為實(shí)現(xiàn)此案例需要考慮的關(guān)鍵架構(gòu)模式:

1. 分段事件驅(qū)動(dòng)架構(gòu) (SEDA Staged Event-Driven Architecture)

2. 事件流處理

3. 事件溯源

4. SAGA

5. CQRS

如圖2所示,為本案例解決方案架構(gòu)圖:

???

圖2 案例架構(gòu)圖

應(yīng)用和數(shù)據(jù)流

應(yīng)用架構(gòu)是由一組可獨(dú)立運(yùn)行的微服務(wù)組成。此外,協(xié)調(diào)器服務(wù)(Enablers)作為單獨(dú)的微服務(wù)負(fù)責(zé)協(xié)調(diào)整個(gè)事務(wù),確保端到端流程執(zhí)行到位。

資金轉(zhuǎn)賬(Fund Transfer)包含多個(gè)服務(wù),作為轉(zhuǎn)賬事件的生產(chǎn)者、處理者和消費(fèi)者它們相互連接。主要由如下 4 個(gè)主要處理器:

1. Fund Transfer Orchestrator (轉(zhuǎn)賬協(xié)調(diào)器)– 負(fù)責(zé)處理資金轉(zhuǎn)移事件并修改和維護(hù)資金轉(zhuǎn)賬請(qǐng)求的狀態(tài)。

2. Fund Transfer Request Router(轉(zhuǎn)賬請(qǐng)求路由器)–基于資金的狀態(tài)轉(zhuǎn)換請(qǐng)求生成事件,并確定事件所對(duì)應(yīng)的路由。它可以將接受到的事件以多播的形式發(fā)送到一個(gè)或者多個(gè)系統(tǒng)。同時(shí)它也是一個(gè)可選組件,如果下游消費(fèi)者不能從單個(gè)主題消費(fèi)(例如,下游消費(fèi)者是遺留服務(wù)或已經(jīng)實(shí)現(xiàn)的服務(wù),同時(shí)這些服務(wù)不能更改成從單個(gè)主題消費(fèi)),則需要使用到它。

3. Fund Transfer Statistics Aggregator(轉(zhuǎn)賬統(tǒng)計(jì)聚合器) – 基于管理 KPI 所需的多維度進(jìn)行匯總,并且維護(hù)轉(zhuǎn)賬過程中的統(tǒng)計(jì)數(shù)據(jù)。

4. Fund Transfer Exception Managements(轉(zhuǎn)賬異常管理) – 根據(jù)異常自動(dòng)觸發(fā)轉(zhuǎn)賬請(qǐng)求中的用戶行為,包括取消轉(zhuǎn)賬,轉(zhuǎn)賬重試 。簡(jiǎn)而言之是為用戶提供管理轉(zhuǎn)賬異常的功能。

5. Fund Transfer API (轉(zhuǎn)賬API)– 為不同轉(zhuǎn)賬渠道提供以下功能:(a) 請(qǐng)求轉(zhuǎn)賬,(b) 檢查轉(zhuǎn)賬狀態(tài),(c) 管理轉(zhuǎn)賬(取消、重試等)。

API 向 Fund Transfer Orchestrator 的input topic(輸入主題)發(fā)布事件,該主題是 Fund Transfer 請(qǐng)求的主要協(xié)調(diào)器。發(fā)送的事件作為“一等公民”會(huì)被持久化到Event/State Store中,同時(shí)這些時(shí)間會(huì)在Event/State Store中不斷積累(啟用事件溯源架構(gòu)模式)。根據(jù)事件上下文和有效載荷,F(xiàn)und Transfer Orchestrator將事件進(jìn)行轉(zhuǎn)換并將轉(zhuǎn)賬狀態(tài)發(fā)布到另一個(gè)topic(主題)中。同樣,轉(zhuǎn)賬記錄的狀態(tài)變更也會(huì)被持久化,在出現(xiàn)系統(tǒng)級(jí)故障時(shí),可用于恢復(fù)轉(zhuǎn)賬狀態(tài)。

接著,由Fund Transfer Request Router(轉(zhuǎn)移請(qǐng)求路由器)處理通過topic 傳遞過來(lái)的轉(zhuǎn)賬狀態(tài)信息,并由Fund Transfer Request Router決定該狀態(tài)被路由到哪個(gè)系統(tǒng)中(單個(gè)或者多個(gè))。這些系統(tǒng)(如圖2 右邊的Customer、Accounts、Sanctions等)將處理之后的結(jié)果作為事件發(fā)布到input topic(輸入主題),再由Fund Transfer Orchestrator(轉(zhuǎn)賬協(xié)調(diào)器)進(jìn)行關(guān)聯(lián)和處理,最終完成轉(zhuǎn)賬狀態(tài)的更新。Fund Transfer Orchestrator (轉(zhuǎn)賬協(xié)調(diào)器)也能夠通過input topic 接受來(lái)自Fund Transfer Exception Managements(轉(zhuǎn)賬異常管理)的異常消息,并對(duì)其進(jìn)行處理,然后更新轉(zhuǎn)賬請(qǐng)求的狀態(tài)。

Fund Transfer Statistics Aggregator(轉(zhuǎn)賬統(tǒng)計(jì)聚合器)也可以通過topic接受來(lái)自Fund Transfer Orchestrator (轉(zhuǎn)賬協(xié)調(diào)器)的轉(zhuǎn)賬事件,并且對(duì)轉(zhuǎn)賬記錄進(jìn)行實(shí)時(shí)統(tǒng)計(jì),Fund Transfer Statistics Aggregator(轉(zhuǎn)賬統(tǒng)計(jì)聚合器)還聚合了多維度的轉(zhuǎn)賬統(tǒng)計(jì)數(shù)據(jù)——以便運(yùn)營(yíng)團(tuán)隊(duì)可以實(shí)時(shí)地查看轉(zhuǎn)賬的統(tǒng)計(jì)數(shù)據(jù)。

技術(shù)構(gòu)件和技術(shù)棧

為了實(shí)現(xiàn)上述應(yīng)用架構(gòu),需要使用關(guān)鍵的技術(shù)構(gòu)件如下:

1. Event backbone——用于在服務(wù)之間的發(fā)送消息。它還將確保發(fā)送事件的排序和序列。它還提供了數(shù)據(jù)真實(shí)性的單一來(lái)源。發(fā)生故障時(shí)——系統(tǒng)可以從故障點(diǎn)重啟。它提供了構(gòu)建事件和狀態(tài)存儲(chǔ)的機(jī)制。在發(fā)生重大中斷的情況下,所存儲(chǔ)的事件和狀態(tài)存儲(chǔ)可用于狀態(tài)恢復(fù)。

2. In-memory data-grid——是一個(gè)分布式緩存可以用來(lái)提高系統(tǒng)的性能。它擁有從服務(wù)中存儲(chǔ)和查找數(shù)據(jù)的能力。它使每個(gè)服務(wù)都有自己的一組緩存,并且這些緩存是可以被持久化(可選),支持“write-through”模式(同時(shí)往內(nèi)存和磁盤寫入信息)。它具有彈性并且可以承受中斷。此外,在集群級(jí)故障(即整個(gè)緩存集群宕機(jī))的情況下,緩存可以通過Event Backbone的持久化機(jī)制恢復(fù)(但是,需要處理器停止工作一段時(shí)間)。

3. Service Mesh——提供監(jiān)控、安全和服務(wù)發(fā)現(xiàn)的能力。

我們可以通過如下技術(shù)棧來(lái)構(gòu)建系統(tǒng)。技術(shù)棧中的工具大部分是開源的,也可以使用其他技術(shù)代替。例如,Quarkus 等。

???

???

解決NFR(非功能性需求)的設(shè)計(jì)決策

為了解決高度動(dòng)態(tài)和復(fù)雜的 NFR,提出最重要的三項(xiàng)設(shè)計(jì)決策。


  • Event Backbone——為了實(shí)現(xiàn)用例和滿足架構(gòu)要求需要建立Event backbone(事件主干)。其主要原因是可以讓不同的轉(zhuǎn)賬過程并行,從而降低處理時(shí)間。此外,使用行業(yè)級(jí)的event backbone(事件主干)將提供/支持某些開箱即用的高質(zhì)量架構(gòu)(例如容錯(cuò)性、可恢復(fù)性、可擴(kuò)展性和事件排序)。
  • 數(shù)據(jù)流——使用in-memory data grid(內(nèi)存數(shù)據(jù)網(wǎng)格)可以顯著減少數(shù)據(jù)庫(kù)請(qǐng)求。此外,數(shù)據(jù)和事件被分區(qū)的設(shè)計(jì)使得系統(tǒng)更容易擴(kuò)展。為部署所有組件選擇相同的使用區(qū)域——大大減少了網(wǎng)絡(luò)延遲。
  • 安全方面的“左移”–通過強(qiáng)制的手段保證每個(gè)組件的安全性。需要為每個(gè)組件(尤其是event backbone事件主干、in-memory data grid內(nèi)存數(shù)據(jù)網(wǎng)格)實(shí)施適當(dāng)?shù)脑L問控制和身份驗(yàn)證機(jī)制。必須深入了解需要滿足的安全標(biāo)準(zhǔn)和法規(guī)(本案例包括:PCI-DSS、GDPR 等)。傳輸層的安全性對(duì)于確保數(shù)據(jù)在傳輸過程中的加密來(lái)說(shuō)至關(guān)重要。此外,必須強(qiáng)制執(zhí)行與數(shù)據(jù)(特別是敏感的私人信息)相關(guān)的控制。避免將敏感信息放入緩存中(盡管這可能會(huì)影響性能)。因此,在NFR 測(cè)試期間 – 需要對(duì)安全性進(jìn)行測(cè)試。靜態(tài)代碼質(zhì)量分析工作需要檢查代碼中的安全漏洞,針對(duì)組件鏡像的掃描也是為了檢查安全漏洞。防火墻、DMZ、VPC 需要通過適當(dāng)?shù)? IAM 解決方案進(jìn)行配置。同時(shí)云原生架構(gòu)也需要關(guān)注另一個(gè)安全方面的問題,就是機(jī)密、密鑰和證書管理。

上述三個(gè)設(shè)計(jì)決策將有助于解決以下類別的 NFR:


  • 自動(dòng)擴(kuò)展——系統(tǒng)的每個(gè)組件(包括事件主干、內(nèi)存數(shù)據(jù)網(wǎng)格)在容器化并部署在 Kubernetes 和 OpenShift 等平臺(tái)上之后都可以自動(dòng)擴(kuò)展。
  • 容錯(cuò)- 處理管道的每個(gè)組件都可以從故障點(diǎn)重新啟動(dòng)。這并不需要特殊的實(shí)現(xiàn)。事件主干如 Apache Kafka就提供上述開箱即用的功能。此外,Kafka Topics 兼作事件和狀態(tài)的存儲(chǔ)工作。因此,可以更加容易地恢復(fù)處理狀態(tài)。此外,即便在集群丟失好幾個(gè)節(jié)點(diǎn)的情況下,通過Kafka 和 Ignite 的復(fù)制和重新調(diào)整功能也讓系統(tǒng)具備持續(xù)處理事件的能力。
  • 高可觀察性- 系統(tǒng)的每個(gè)組件都被檢測(cè)起來(lái),實(shí)時(shí)性能和資源利用率指標(biāo)信息會(huì)被以流式的方式傳遞到 Prometheus 中。而 Grafana 會(huì)與Prometheus合作完成數(shù)據(jù)可視化和報(bào)警通知的工作。
  • 彈性 – 有多級(jí)部署決策來(lái)處理彈性問題。每個(gè)組件都有多個(gè)實(shí)例運(yùn)行在同一個(gè)可用區(qū)(包括 Kafka)。DR 位置維護(hù)在備用的不同可用區(qū)中。Kafka 的 active 和 dr 集群之間為 Kafka 啟用了集群級(jí)復(fù)制。

在下一節(jié),我們將圍繞頂級(jí) NFR – 性能的一些關(guān)鍵設(shè)計(jì)因素進(jìn)行深入探討。后續(xù)我們將發(fā)布其他有關(guān) NFR 的設(shè)計(jì)的文章。

滿足性能要求的設(shè)計(jì)要點(diǎn)

為了滿足性能要求,在設(shè)計(jì)和實(shí)施過程中需要考慮以下幾點(diǎn):

性能建模 ——對(duì)性能目標(biāo)有一個(gè)清晰的理解是很重要的。性能目標(biāo)會(huì)影響到架構(gòu)、技術(shù)、基礎(chǔ)設(shè)施和設(shè)計(jì)決策。隨著混合云和多云解決方案的日益普及,性能建模變得更加重要。由此產(chǎn)生了許多依賴于性能建模的架構(gòu)折中方案。性能建模應(yīng)涵蓋 – 事務(wù)/事件清單、工作負(fù)載建模(并發(fā)性、訪問峰量、不同事務(wù)/事件的預(yù)期響應(yīng)時(shí)間)和基礎(chǔ)設(shè)施建模。構(gòu)建性能模型有助于創(chuàng)建部署模型(尤其是與可擴(kuò)展性相關(guān)的模型),它有助于搭建架構(gòu)和設(shè)計(jì)優(yōu)化從而減少訪問延遲,也有助于設(shè)計(jì)性能測(cè)試并驗(yàn)證系統(tǒng)的性能和吞吐量。

避免單體怪物——單體架構(gòu)的集中處理。這意味著無(wú)法獨(dú)立縮放不同的組件。事實(shí)上,服務(wù)的實(shí)現(xiàn)也需要使用 SEDA的方式將其分解為松耦合的組件,提供擴(kuò)展每個(gè)組件的能力并使服務(wù)更具彈性。每個(gè)部署的組件都可以獨(dú)立擴(kuò)展并部署到一個(gè)集群中,以提高系統(tǒng)的并發(fā)性和彈性。

事件主干的選擇——Event backbone(事件主干)的 選擇會(huì)影響系統(tǒng)性能。從性能的角度來(lái)看,以下 5個(gè)特征顯得尤為重要:


  • 消息抽取的性能(特別是使消息持久化。即,將消息寫入到磁盤中)。此外,性能需要始終保持一致。
  • 消費(fèi)者消息消費(fèi)的性能。
  • 擴(kuò)展能力(即在集群中添加新節(jié)點(diǎn)/代理的能力)
  • 節(jié)點(diǎn)/代理失敗時(shí)重新調(diào)整所需的時(shí)間
  • 當(dāng)消費(fèi)者實(shí)例離開或加入消費(fèi)者組時(shí)重新調(diào)整所需的時(shí)間

Apache Kafka 是一個(gè)不錯(cuò)的選擇,它在性能、容錯(cuò)性、可擴(kuò)展性和可用性等方面都經(jīng)受住了考驗(yàn),因此從眾多候選者中脫穎而出。它能夠輕松面對(duì)上面提出的5個(gè)特征中的前三個(gè),對(duì)于最后 2 點(diǎn)(重新平衡時(shí)間),Kafka 的性能處理效果視主題數(shù)據(jù)量而定。雖然Apache Pulsar 試圖解決這個(gè)問題,但是鑒于 Kafka 的良好表現(xiàn)并不會(huì)立即切換方案,但我們會(huì)密切關(guān)注 Apache Pulsar 的發(fā)展動(dòng)向。

善用緩存– 數(shù)據(jù)庫(kù)查詢作為IO操作,其使用開銷是可想而知的。為了避免IO操作的開銷需要善用緩存機(jī)制。例如,Redis、Apache Ignite 等都是優(yōu)秀的緩存實(shí)踐。通過使用緩存,可以創(chuàng)建有助于數(shù)據(jù)查找的“快速數(shù)據(jù)層”。所有關(guān)于數(shù)據(jù)的讀取操作都會(huì)首先訪問緩存,而不是從數(shù)據(jù)庫(kù)或其他遠(yuǎn)程服務(wù)中獲取數(shù)據(jù)。流數(shù)據(jù)處理管道也可以實(shí)時(shí)地存放(或更新)到緩存。接下來(lái)事件處理器只需要引用緩存中的數(shù)據(jù)即可,而不用查詢數(shù)據(jù)庫(kù)或?qū)τ涗浵到y(tǒng)進(jìn)行調(diào)用。事件處理器先將事件寫入到 Ignite中,然后持久化處理器再將數(shù)據(jù)異步寫入到數(shù)據(jù)庫(kù)中。這種數(shù)據(jù)處理方式極大地提高了系統(tǒng)的性能。

在本案例中,我們選擇了 Apache Ignite,因?yàn)樗邆湟韵聨讉€(gè)特性:


  • 它提供分布式緩存(支持?jǐn)?shù)據(jù)分區(qū))
  • 水平可擴(kuò)展
  • 符合 ANSI SQL
  • 便于使用
  • 支持復(fù)制——提供一定程度的容錯(cuò)
  • Cloud-Ready(云就緒)

緩存可以持久化。即,緩存數(shù)據(jù)寫入磁盤。但它會(huì)影響性能。不使用 SSD 時(shí),性能損失非常顯著。如果緩存是非持久性的,那么架構(gòu)需要滿足從數(shù)據(jù)/事件存儲(chǔ)中重新混合緩存的需求?;謴?fù)性能對(duì)于減少平均恢復(fù)時(shí)間至關(guān)重要。在我們的架構(gòu)中——利用 Kafka 主題來(lái)補(bǔ)充緩存。它們是我們的事件/狀態(tài)存儲(chǔ)。有一個(gè)多實(shí)例恢復(fù)組件,可以從 Kafka 主題中讀取數(shù)據(jù)并對(duì)緩存進(jìn)行再水化。

配合處理——當(dāng)事件的生產(chǎn)者、消費(fèi)者和事件主干配合工作時(shí),系統(tǒng)性能處于最佳狀態(tài)。然而,這意味著如果數(shù)據(jù)中心出現(xiàn)故障——它會(huì)導(dǎo)致整個(gè)平臺(tái)癱瘓。為了避免這種情況的方式可以對(duì)事件主干設(shè)置復(fù)制/鏡像。例如,Kafka MirrorMaker 2 (MM2) 就可用于設(shè)置跨數(shù)據(jù)中心/可用區(qū)的復(fù)制。

選擇正確的消息格式——對(duì)消息進(jìn)行序列化和反序列化操作的快慢會(huì)對(duì)性能產(chǎn)生影響。雖然,消息格式有多種選擇,例如,XML、JSON、Avro、Protobuf、Thrift。但是對(duì)于本例而言,選擇 Avro的消息格式, 是因?yàn)樗木o湊性、序列化/反序列化的性能以及對(duì)消息模式演化的支持。

并發(fā)相關(guān)的決策——在本例的架構(gòu)設(shè)計(jì)中,并發(fā)的關(guān)鍵參數(shù)如下:


  • Kafka topic(主題)的分區(qū)數(shù)
  • 每個(gè)消費(fèi)組的實(shí)例數(shù)
  • 消費(fèi)者/生產(chǎn)者實(shí)例的線程數(shù)

這些參數(shù)會(huì)對(duì)系統(tǒng)吞吐量產(chǎn)生直接影響。在 Kafka 中,每個(gè)分區(qū)都可以被同一消費(fèi)組中的單個(gè)線程所消費(fèi)。在 Kafka brokers(代理)中存在多個(gè)分區(qū)和驅(qū)動(dòng)器,它們有助于事件的傳播,同時(shí)也不必?fù)?dān)心消息的順序問題。在資源利用率限制(CPU、內(nèi)存和網(wǎng)絡(luò))范圍內(nèi),擁有多線程的消費(fèi)者可以在一定程度上對(duì)性能提升有所幫助。在同一個(gè)消費(fèi)者組中擁有多個(gè)實(shí)例從而將負(fù)載分?jǐn)偟蕉鄠€(gè)節(jié)點(diǎn)/服務(wù)器上,最終提升水平可擴(kuò)展的能力。

使用分區(qū)——分區(qū)數(shù)越多,并發(fā)性越高。但是,在確定分區(qū)數(shù)時(shí)需要注意以下幾個(gè)方面的問題。重視分區(qū)鍵的選擇,它可以在不破壞事件排序的情況下在分區(qū)之間均勻分布事件。此外,在有些情況下過度分區(qū)會(huì)帶來(lái)不良后果,例如:在打開文件句柄的時(shí)候、由于broker(代理)故障造成 Kafka topic(主題)不可用的時(shí)候、端點(diǎn)延遲的時(shí)候以及消費(fèi)者對(duì)內(nèi)存有更高需要的時(shí)候。

執(zhí)行性能測(cè)試從而定義系統(tǒng)性能的標(biāo)準(zhǔn),通過測(cè)試推斷出所需的吞吐量和性能,它們有助于確定并發(fā)的 3 個(gè)關(guān)鍵參數(shù)的配置。

I/O 問題需要重視——I/O操作對(duì)系統(tǒng)延遲的影響很大,甚至說(shuō)它影響到架構(gòu)中的所有組件,包括事件主干、緩存、數(shù)據(jù)庫(kù)和應(yīng)用程序組件。

對(duì)于使用了持久化的分布式緩存組件而言,I/O操作是影響性能的關(guān)鍵因素之一。例如,對(duì)于 Apache Ignite - 強(qiáng)烈建議使用 SSD(固態(tài)硬盤)并且開啟direct(直接) I/O模式,從而獲得良好的性能。非持久性緩存無(wú)疑是最快的緩存方案——但是缺點(diǎn)也很明顯,一旦緩存集群出現(xiàn)故障,緩存數(shù)據(jù)將會(huì)丟失。雖然,可以通過恢復(fù)過程來(lái)解決該問題 - 重新恢復(fù)緩存。然而,需要引起注意的是隨著恢復(fù)時(shí)間變長(zhǎng)——流媒體管道中的延遲也會(huì)變大。除非,緩存的恢復(fù)過程必須非??臁R虼?,需要通過運(yùn)行多個(gè)恢復(fù)實(shí)例同時(shí)還要避免任何轉(zhuǎn)換/業(yè)務(wù)邏輯的操作。

Kafka 不一定需要高性能磁盤(如 SSD)。建議使用多驅(qū)動(dòng)器(和多個(gè)日志目錄)從而獲得良好的吞吐量。這里不建議與應(yīng)用程序以及操作系統(tǒng)共享驅(qū)動(dòng)器。此外,諸如配置“ noatime ”之類的掛載選項(xiàng)可以提升性能。下面鏈接討論了依賴于文件系統(tǒng)類型的其他掛載項(xiàng):??https : //kafka.apache.org/documentation.html#diskandfs??

從應(yīng)用程序的角度來(lái)看 - 將日志記錄保持在最低限度。專注于記錄異常信息而不是面面俱到。盡管大多數(shù)日志框架都能夠進(jìn)行異步記錄,但仍然會(huì)對(duì)延遲產(chǎn)生影響。

內(nèi)存調(diào)優(yōu)——事件流架構(gòu)在很大程度上依賴于內(nèi)存調(diào)優(yōu)。對(duì)于 Kafka brokers(代理)和 Apache Ignite 服務(wù)器節(jié)點(diǎn)尤為如此。因此為處理器、消費(fèi)者、Kafka 代理以及內(nèi)存數(shù)據(jù)網(wǎng)格節(jié)點(diǎn)分配足夠的內(nèi)存空間就顯得非常重要。

調(diào)整操作系統(tǒng)的內(nèi)存設(shè)置也有助于在一定程度上提高性能。關(guān)鍵參數(shù)之一是“ vm.swappiness”。它負(fù)責(zé)控制進(jìn)程在內(nèi)存中的交換。它的值介于 0 和 100 之間的值,數(shù)字越大,就表示內(nèi)存交換越積極。建議將此數(shù)字保持在較低水平以減少交換。

在 Kafka 的使用場(chǎng)景下,由于它嚴(yán)重依賴頁(yè)面緩存,因此也可以調(diào)整“ vmdirty ratio”選項(xiàng)來(lái)控制數(shù)據(jù)刷新到磁盤的比例。

網(wǎng)絡(luò)優(yōu)化 ——為了有效利用網(wǎng)絡(luò),建議對(duì)大容量消息進(jìn)行壓縮,因?yàn)檫@個(gè)大家伙會(huì)降低網(wǎng)絡(luò)利用率。但是對(duì)于大容量消息的壓縮可以提升生產(chǎn)者、消費(fèi)者以及代理的CPU 利用率。例如,Kafka 支持 4 種不同的壓縮類型(gzip、lz4、snappy、zstd)。Snappy 的壓縮類型讓CPU 使用率、壓縮率、速度和網(wǎng)絡(luò)利用率處在折中的位置,讓它們之間保持一種平衡關(guān)系。

關(guān)注相關(guān)消息——在發(fā)布訂閱機(jī)制中,消費(fèi)者有可能獲得他們不感興趣的消息,因此可以添加過濾器從而過濾掉他們不感興趣的消息,讓更多的注意力放到相關(guān)的消息上。即便如此仍然需要對(duì)事件進(jìn)行反序列化后才能對(duì)時(shí)間內(nèi)容進(jìn)行過濾,為了提高效率避免無(wú)效的反序列化操作,可以通過在事件的標(biāo)題中添加事件元數(shù)據(jù)來(lái)對(duì)事件進(jìn)行描述。消費(fèi)者通過查看事件標(biāo)頭來(lái)決定是否對(duì)事件進(jìn)行反序列化,并解析其中的內(nèi)容。這種做法明顯提高了消費(fèi)者處理事件的吞吐量并降低了對(duì)資源的使用,提升資源利用率。

解析需要的內(nèi)容(尤其是 XML)– 在金融服務(wù)行業(yè) – XML 被大量使用,事件流應(yīng)用程序的輸入很可能就是 XML。然而,解析 XML屬于CPU 和內(nèi)存密集型的操作。因此,XML 解析器的選擇是與性能和資源利用率相關(guān)的重要決策。針對(duì)大 XML 文檔的解析,建議使用 SAX 解析器。如果事件流應(yīng)用程序不需要解析完全XML文檔,可以預(yù)先配置 xpath 來(lái)定位到所需數(shù)據(jù),然后通過數(shù)據(jù)構(gòu)建事件負(fù)載,這樣可能是一個(gè)更快的選擇。但是,如果需要解析整個(gè)XML 數(shù)據(jù)——那么最好一次性解析整個(gè)文檔并將其轉(zhuǎn)換為事件流應(yīng)用程序的消息格式,解析的操作使用處理器的多個(gè)實(shí)例完成,而不是讓事件流管道中的每個(gè)處理器解析XML文檔。

監(jiān)控和識(shí)別性能瓶頸的工具——識(shí)別性能瓶頸應(yīng)該是一件很容易的事情??梢酝ㄟ^使用輕量級(jí)檢測(cè)框架(基于 AOP)來(lái)進(jìn)行識(shí)別工作。在案例中,我們將 AOP 與 Spring-Boot Actuator 和 Micrometer 進(jìn)行組合,并將接口暴露給Prometheus 端點(diǎn)。對(duì)于 Apache Kafka性能指標(biāo)的采集,使用 Prometheus 的 JMX 導(dǎo)出器來(lái)完成。接著就是用 Grafana 構(gòu)建一個(gè)內(nèi)容豐富的儀表板,上面可以顯示生產(chǎn)者、消費(fèi)者、Kafka 以及 Ignite(基本包括架構(gòu)的所有組件)的性能指標(biāo)。

上面這一系列的操作提供了快速查詢和展示瓶頸的能力,并不需要對(duì)日志進(jìn)行分析,也不用將應(yīng)用與日志進(jìn)行關(guān)聯(lián)。

對(duì)Kafka配置進(jìn)行微調(diào) ——Kafka 有大量的配置參數(shù)用于代理、生產(chǎn)者、消費(fèi)者和 Kafka 流信息。以下是用來(lái)配置Kafka 延遲和吞吐量的參數(shù):


  • Broker(代理)

  1.  log.dirs – 在不同驅(qū)動(dòng)器上設(shè)置多個(gè)目錄以加快 I/O讀寫速度。
  2. num.network.threads
  3. num.io.threads
  4. num.replica.fetchers
  5. socket.send.buffer.bytes
  6. socket.receive.buffer.bytes
  7. socket.request.max.bytes
  8. group.initial.rebalance.delay.ms

  • Producer(消息生產(chǎn)者)

  1. linger.ms
  2. batch.size
  3. buffer.memory
  4. compression.type

  • Consumer(消息消費(fèi)者)

  1. fetch.min.bytes - 如果設(shè)置為默認(rèn)值 1,它將改善延遲但吞吐量不會(huì)很好。所以一定要做好平衡。
  2. max.poll.records

  • Streams(流)

  1. num.stream.threads
  2. buffered.records.per.partition
  3. cache.max.bytes.buffering

有關(guān)調(diào)整 Kafka 代理、生產(chǎn)者和消費(fèi)者的其他信息,請(qǐng)參閱提供的參考資料。

GC調(diào)優(yōu) – 垃圾收集器的調(diào)優(yōu)對(duì)避免長(zhǎng)時(shí)間停頓和過多的 GC 開銷也顯得尤為重要。從 JDK 8 開始,建議大多數(shù)應(yīng)用程序(具有大內(nèi)存的多處理器機(jī)器)使用Garbage-First Garbage Collector (G1GC) 模式。這種模式試圖實(shí)現(xiàn)暫停時(shí)間目標(biāo)并試圖實(shí)現(xiàn)高吞吐量。此外,在啟動(dòng)的時(shí)候不需要太多的配置。

我們確保為 JVM 擁有足夠的內(nèi)存。在 使用Ignite時(shí),會(huì)通過堆外內(nèi)存來(lái)存儲(chǔ)數(shù)據(jù)。

-Xms 和 -Xmx 與“-XX:+AlwaysPreTouch”保持相同的值,以確保在啟動(dòng)期間從操作系統(tǒng)分配所有內(nèi)存。

G1GC 中還有其他參數(shù),例如以下可用于進(jìn)一步調(diào)整吞吐量(因?yàn)樵?EDA 中吞吐量很重要):


  • -XX:MaxGCPauseMillis(增加其值以提高吞吐量)
  • -XX:G1NewSizePercent, -XX:G1MaxNewSizePercent
  • -XX:ConcGCThreads

更多細(xì)節(jié)請(qǐng)參考??調(diào)優(yōu) G1GC??。

調(diào)整 Apache Ignite – Apache Ignite 調(diào)整在其??官方網(wǎng)站??上有詳細(xì)記錄。以下是我們?yōu)樘岣咂湫阅芏扇〉囊恍┐胧?/p>


  • 80%:20% 原則,同時(shí)為 Ignite 服務(wù)器節(jié)點(diǎn)分配內(nèi)存(80% 分配給 Ignite 進(jìn)程。20% 保留給操作系統(tǒng))
  • 使用 zookeeper 進(jìn)行集群發(fā)現(xiàn)
  • 使用堆外內(nèi)存來(lái)存儲(chǔ)數(shù)據(jù)
  • 至少為 JVM 堆分配了 16GB
  • 根據(jù)需求將堆外劃分為不同的數(shù)據(jù)區(qū)域(引用數(shù)據(jù)區(qū)域、輸入數(shù)據(jù)區(qū)域、輸出數(shù)據(jù)區(qū)域等)
  • 引用數(shù)據(jù)保存在“副本”緩存中
  • 輸入/輸出(即事務(wù)數(shù)據(jù))保存在“分區(qū)”緩存中。
  • 確保每個(gè)緩存都定義了一個(gè)關(guān)聯(lián)鍵,該鍵始終用于并置處理的查詢
  • 使用上一節(jié)中的配置指南調(diào)整 JVM GC
  • 將緩存組用于邏輯相關(guān)的數(shù)據(jù)
  • 在 JDBC 驅(qū)動(dòng)程序中啟用“延遲”加載
  • 正確調(diào)整不同線程池的大小以提高性能
  • 使用 JCache API 代替 SQL 查詢
  • 確保游標(biāo)關(guān)閉
  • 使用“NearCache”配置獲取引用數(shù)據(jù)——這樣查找它的時(shí)候就不需要通過客戶端從遠(yuǎn)程服務(wù)器獲取了。
  • 增加索引的內(nèi)聯(lián)大小
  • 將 vm.swappiness 減少到 1
  • 使用 Direct- IO
  • 引用數(shù)據(jù)緩存啟用了本機(jī)持久化機(jī)制。但是,事務(wù)緩存不用開啟持久化機(jī)制,因?yàn)槭聞?wù)緩存需要備份在 Kafka 上。在集群網(wǎng)絡(luò)中斷的情況下,事務(wù)數(shù)據(jù)使用單獨(dú)的恢復(fù)處理器從 Kafka 恢復(fù)到 Ignite中。

結(jié)論

在本文中,我們專注于與性能相關(guān)的架構(gòu)決策。因此保持架構(gòu)每個(gè)組件的性能顯得非常重要,因?yàn)槿魏谓M件的問題都可能導(dǎo)致流信息阻塞。因此,架構(gòu)的每個(gè)組件都需要在不影響其他 NFR 的情況下針對(duì)性能進(jìn)行調(diào)優(yōu)。所以對(duì)這些組件有深入的技術(shù)理解是必不可少的,只有這樣才能有效地進(jìn)行調(diào)優(yōu)工作。

譯者介紹

崔皓,51CTO社區(qū)編輯,資深架構(gòu)師,擁有18年的軟件開發(fā)和架構(gòu)經(jīng)驗(yàn),10年分布式架構(gòu)經(jīng)驗(yàn)。曾任惠普技術(shù)專家。樂于分享,撰寫了很多熱門技術(shù)文章,閱讀量超過60萬(wàn)。??《分布式架構(gòu)原理與實(shí)踐》??作者。

原文標(biāo)題:Designing High-Volume Systems Using Event-Driven Architectures,作者:Ram Ravishankar,Harish Bharti,Tanmay Ambre

【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】

責(zé)任編輯:華軒 來(lái)源: 51CTO
相關(guān)推薦

2022-06-02 10:35:20

架構(gòu)驅(qū)動(dòng)

2023-06-21 08:00:00

微服務(wù)架構(gòu)

2023-04-13 08:23:28

軟件架構(gòu)設(shè)計(jì)

2023-07-05 08:00:52

MetrAuto系統(tǒng)架構(gòu)

2023-12-13 10:44:57

事件驅(qū)動(dòng)事件溯源架構(gòu)

2022-06-14 11:15:09

代碼驅(qū)動(dòng)

2022-03-25 10:48:40

NBF架構(gòu)設(shè)計(jì)

2019-10-12 09:04:59

微服務(wù)架構(gòu)CAP

2023-07-12 08:30:52

服務(wù)架構(gòu)事件驅(qū)動(dòng)架構(gòu)

2023-01-09 09:00:00

樹服務(wù)架構(gòu)驅(qū)動(dòng)決策

2024-08-27 12:49:20

2011-11-21 16:49:58

日志常用事件

2014-05-19 10:08:36

IM系統(tǒng)架構(gòu)設(shè)計(jì)

2023-08-08 08:00:00

架構(gòu)Kafka

2015-10-16 14:35:05

SaaSCRM架構(gòu)設(shè)計(jì)

2017-12-12 08:40:00

2013-05-27 10:58:28

Tumblr架構(gòu)設(shè)計(jì)雅虎收購(gòu)

2024-08-16 14:01:00

2023-08-16 12:34:16

同步備份異步備份

2024-10-17 08:26:53

ELKmongodb方案
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)