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

成本低誤差小,攜程基于 Kafka 的 Serverless 延遲隊(duì)列的實(shí)踐

開(kāi)發(fā) 新聞
由于該實(shí)現(xiàn)方案完全是基于 Serverless 的方式實(shí)現(xiàn)的,所以維護(hù)成本非常低。

作者簡(jiǎn)介

Pin,關(guān)注 RPC、Service Mesh、Serverless 等云原生技術(shù)。

一、背景

隨著上云項(xiàng)目的不斷推進(jìn),大量的應(yīng)用需要部署到 aws 上,其中有很多應(yīng)用都依賴延遲隊(duì)列的功能。而在 aws 上,我們選擇以 Kafka 作為消息隊(duì)列,但是 Kafka 本身不支持延遲隊(duì)列,這就需要思考如何基于 Kafka 來(lái)實(shí)現(xiàn)延遲隊(duì)列。

二、需求

統(tǒng)計(jì)了一下所有需要使用到延遲隊(duì)列的場(chǎng)景,有以下幾大特點(diǎn):

  • 延遲時(shí)間不固定。有的 topic 需要支持 5 分鐘的延遲,有的卻要求支持 7 天的延遲。
  • 延遲消息數(shù)量小。所有的場(chǎng)景中涉及到的每天延遲消息的數(shù)量不超過(guò) 1 億條,每條消息的大小不超過(guò) 1MB。
  • 延遲消息不能丟失,可以不保證有序。
  • 延遲誤差小。延遲誤差是指實(shí)際消費(fèi)消息的時(shí)間和希望消費(fèi)消息之間的時(shí)間差值。根據(jù)統(tǒng)計(jì)的業(yè)務(wù)場(chǎng)景來(lái)看,要求延遲誤差在 2s 以內(nèi)。
  • 生產(chǎn)延遲消息的峰值比較高。很多情況下,業(yè)務(wù)會(huì)一次性創(chuàng)建 1000 萬(wàn)條延遲消息,并且這些延遲消息的延遲時(shí)長(zhǎng)都是一致的。

三、目標(biāo)

由于實(shí)現(xiàn)延遲隊(duì)列的方式有很多,我們?cè)跐M足需求的前提下,制定了幾個(gè)目標(biāo):云上成本低、運(yùn)維成本低、開(kāi)發(fā)成本低、穩(wěn)定性高和延遲誤差小。

四、產(chǎn)品選型

在 aws 上支持消息隊(duì)列的產(chǎn)品有 RabbitMQ、Apache ActiveMQ 和 SQS。其中 RabbitMQ 和 Apache ActiveMQ aws 主要是托管其安裝部署,并非是以 Serverless 的方式對(duì)外提供服務(wù)。另外,我們當(dāng)前已經(jīng)選擇使用 Kafka 作為消息隊(duì)列,若僅僅為了滿足延遲隊(duì)列的功能而去更換消息隊(duì)列,成本顯然是巨大的。

除此之外,aws 還提供了 SQS 來(lái)支持延遲隊(duì)列,雖然 SQS 是 Serverless 的,但是 SQS 有他自身的局限性:SQS 最多支持 15 分鐘以內(nèi)的延遲,明顯無(wú)法滿足我們的需求。

可見(jiàn),僅僅基于云上已有的產(chǎn)品已無(wú)法滿足我們的需求,基于這個(gè)原因,我們開(kāi)始調(diào)研延時(shí)消息的實(shí)現(xiàn)方案,看看能否通過(guò)少量的開(kāi)發(fā)來(lái)實(shí)現(xiàn)我們的需求。

五、方案調(diào)研

業(yè)界實(shí)現(xiàn)延時(shí)隊(duì)列功能的方案比較多,我們對(duì)其進(jìn)行了簡(jiǎn)單的分析,具體如下:

5.1 RabbitMQ

RabbitMQ 是基于 TTL+ 死信隊(duì)列的方式來(lái)實(shí)現(xiàn)的。具體來(lái)說(shuō),通過(guò)設(shè)置消息的 TTL,當(dāng)達(dá)到 TTL 時(shí)消息還沒(méi)有被消費(fèi),此時(shí)會(huì)投遞到死信隊(duì)列。TTL 分兩種:

  • Queue 級(jí)別的 TTL:所有消息統(tǒng)一的 TTL
  • Message 級(jí)別的 TTL:每條消息可以是不同的 TTL,但是存在隊(duì)頭阻塞問(wèn)題

該方案的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,但是延遲誤差不確定。

5.2 Apache ActiveMQ

Apache ActiveMQ 是基于定時(shí)調(diào)度的方式來(lái)實(shí)現(xiàn)的。具體來(lái)說(shuō),配置延遲時(shí)間或者 cron 表達(dá)式表示消息的投遞策略,基于 Java 的 Timer 實(shí)現(xiàn),將消息分級(jí)存儲(chǔ)在文件和內(nèi)存中。

該方案的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,延遲誤差可控,但是可能會(huì)占用大量?jī)?nèi)存。

5.3 RocketMQ

RocketMQ 是基于定時(shí)調(diào)度+延遲等級(jí)的方式來(lái)實(shí)現(xiàn)的。具體來(lái)說(shuō),將延時(shí)消息發(fā)送到指定的延時(shí)等級(jí)隊(duì)列(一共有 18 個(gè)等級(jí)),然后通過(guò)一個(gè)定時(shí)器進(jìn)行輪詢這些 ConsumeQueue 實(shí)現(xiàn)延時(shí)的效果。具體實(shí)現(xiàn)如下:

  • 修改消息 topic 名稱和隊(duì)列信息投遞到對(duì)應(yīng)等級(jí)的延時(shí)消息的 ConsumeQueue 中
  • ScheduleMessageService消費(fèi)ConsumeQueue中的消息再重新投遞到 CommitLog 中
  • 將 CommitLog 中的消息投遞到目標(biāo) topic 中,消費(fèi)者消費(fèi)目標(biāo) topic 中的消息

該方案的優(yōu)點(diǎn)是延遲誤差可控,但是實(shí)現(xiàn)復(fù)雜。

5.4 Redis

基于 Redis 實(shí)現(xiàn)延遲隊(duì)列的方式有很多,在這里簡(jiǎn)單描述兩種:

1)定時(shí)輪詢

該方案的大致步驟如下:

  • 將消息的延時(shí)時(shí)間戳作為 zset 的 key,消息的 ID 作為 zset 的 value
  • 消息 ID 作為 key,消息體序列化成 String 作為 value 存儲(chǔ)在 Redis 中
  • 定時(shí)輪詢 zset,大于當(dāng)前時(shí)間則投遞到 Redis 的 List 中供消費(fèi)者消費(fèi)

2)Key 過(guò)期監(jiān)聽(tīng)器

每條消息設(shè)置一個(gè)過(guò)期時(shí)間,監(jiān)聽(tīng)過(guò)期事件然后將消息投遞到 target topic。

基于 Redis 實(shí)現(xiàn)延時(shí)隊(duì)列的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,但是都可能存在丟消息的情況,并且存儲(chǔ)成本高。

六、實(shí)現(xiàn)方案

既然使用單一的云上產(chǎn)品不能滿足我們的需求,那就只能考慮通過(guò)少量的開(kāi)發(fā)并結(jié)合云上產(chǎn)品的特性來(lái)實(shí)現(xiàn)基于 Kafka 的延遲隊(duì)列的功能。具體的實(shí)現(xiàn)方案有如下幾種:

6.1 RabbitMQ 或 Apache ActiveMQ

RabbitMQ 或者 Apache ActiveMQ 都是 aws 上支持的產(chǎn)品,從功能層面來(lái)看是可以滿足需求。當(dāng)前的消息隊(duì)列是基于 Kafka 實(shí)現(xiàn)的,如果再結(jié)合 RabbitMQ 或者 Apache ActiveMQ 來(lái)實(shí)現(xiàn)延遲隊(duì)列的功能,主要面臨的問(wèn)題是:缺少對(duì) RabbitMQ 或者 Apache ActiveMQ 相關(guān)的技術(shù)儲(chǔ)備,由于 aws 上對(duì) RabbitMQ 或者 Apache ActiveMQ 僅僅只是部署層面的托管,當(dāng)出現(xiàn)問(wèn)題時(shí),是需要有研發(fā)人員自己去 troubleshooting 的。所以,該方案就不考慮了。

6.2 基于 SQS 的多級(jí)隊(duì)列

既然 SQS 已經(jīng)支持 15 分鐘內(nèi)的延時(shí)隊(duì)列,那么如果要實(shí)現(xiàn)更長(zhǎng)時(shí)間的延遲隊(duì)列是不是可以考慮通過(guò)多級(jí)延遲隊(duì)列來(lái)實(shí)現(xiàn)?具體實(shí)現(xiàn)方案如下:

  1. 在延遲消息中增加一個(gè)字段 times 用來(lái)表示當(dāng)前是第幾輪(借鑒時(shí)間輪算法的思路)。
  2. 如果延遲消息的延遲時(shí)間小于 15 分鐘,將延遲消息的 times 設(shè)置為 0,直接投遞到 SQS 中。
  3. 如果延遲消息的延遲時(shí)間大于 15 分鐘,計(jì)算一下 times 的值(延遲時(shí)間/15 分鐘),然后直接投遞到 SQS 中。
  4. 如果 Consumer 從 SQS 中消費(fèi)到了一個(gè)延遲消息且 times 大于 0,則將 times 的值減去 1,再次投遞到 SQS 中。如此反復(fù),直到 times 為 0。
  5. 如果 Consumer 從 SQS 中消費(fèi)到了一個(gè)延遲消息且 times 為 0,則表示該消息已經(jīng)達(dá)到了延遲時(shí)間,則 Consumer 會(huì)直接將該消息投遞到對(duì)應(yīng)的目標(biāo) topic。

這種方案雖然能夠?qū)崿F(xiàn)延遲隊(duì)列的功能,且 SQS 本身也是 Serverless 的,維護(hù)成本也比較低。

但是我們調(diào)研了一下 SQS 的計(jì)費(fèi)標(biāo)準(zhǔn)發(fā)現(xiàn),SQS 主要是根據(jù)消息數(shù)量來(lái)收費(fèi)的。這樣一來(lái),如果延遲時(shí)間越長(zhǎng),消息數(shù)量會(huì)被放大的越嚴(yán)重。而我們實(shí)際業(yè)務(wù)中延遲時(shí)間在 15 分鐘以內(nèi)的沒(méi)有,一般是 1 小時(shí)到 7 天,所以這種方案不可行。

6.3 基于 SQS 和定時(shí)調(diào)度策略

使用基于 SQS 的多級(jí)隊(duì)列的方式最大的問(wèn)題是云上的成本問(wèn)題,更具體一點(diǎn)是云上的存儲(chǔ)成本問(wèn)題。因?yàn)樵摲桨笇⑺械难舆t消息都存儲(chǔ)在 SQS 中,這是導(dǎo)致費(fèi)用增加的最主要原因。既然如此,那我們是不是可以考慮將大于 15 分鐘延遲時(shí)間的消息寫(xiě)入到一個(gè)成本低的存儲(chǔ)上,然后在時(shí)間延遲時(shí)間小于 15 分鐘的時(shí)候?qū)⑵洳樵兂鰜?lái)投遞到 SQS 中即可。這樣一來(lái),延遲時(shí)間的長(zhǎng)短不會(huì)對(duì) SQS 的費(fèi)用有影響,僅僅只需要考慮如何選擇一個(gè)存儲(chǔ)成本低、讀寫(xiě)方便的 Serverless 產(chǎn)品作為延遲消息的存儲(chǔ)即可。

基于這一思路,設(shè)計(jì)了一個(gè)基于 SQS 和定時(shí)調(diào)度策略的實(shí)現(xiàn)方案:

圖片

具體流程如下:

  1. 生產(chǎn)者 Producers 生產(chǎn)的正常消息直接投遞到 Kafka 的目標(biāo) topic,如果是延遲消息投遞到 Kafka 的一個(gè)延遲消息的 Delay Message Topic 中。
  2. Consumer 消費(fèi) Delay Message Topic 中的消息,如果該消息的延遲時(shí)間小于 15 分鐘,直接投遞到 SQS(Delay Queue)中。如果消息的延遲時(shí)間大于 15 分鐘,直接將消息寫(xiě)入到 Message Store 中。
  3. Scheduler 會(huì)定時(shí)掃描 Message Store 中的消息,如果發(fā)現(xiàn)延遲時(shí)間小于 15 分鐘,則直接投遞到 SQS(Delay Queue)中,Scheculer 是通過(guò) Event Bridge 來(lái)觸發(fā)的。
  4. Emitter 會(huì)消費(fèi) SQS(Delay Queue)中的消息,并將該消息投遞到目標(biāo) topic 中。

整個(gè)流程不算復(fù)雜,里面涉及到的 aws 服務(wù)都是 Serverless 的,但是涉及的服務(wù)太多以后 troubleshooting 就會(huì)比較復(fù)雜。

基于以上問(wèn)題,我們對(duì)該方案的實(shí)進(jìn)行了改進(jìn)和簡(jiǎn)化,具體如下:

圖片

具體流程如下:

  1. 生產(chǎn)者 Producers 生產(chǎn)的正常消息直接投遞到 Kafka 的目標(biāo) topic,如果是延遲消息投遞到 Kafka 的一個(gè)延遲消息的 Delay Message Topic 中。
  2. Service 消費(fèi) Delay Message Topic 中的消息,如果該消息的延遲時(shí)間小于 15 分鐘,直接投遞到SQS(Delay Queue)中。如果消息的延遲時(shí)間大于 15 分鐘,直接將消息寫(xiě)入到 Message Store 中。
  3. Service 會(huì)定時(shí)掃描 Message Store 中的消息,如果發(fā)現(xiàn)延遲時(shí)間小于 15 分鐘,則直接投遞到 SQS(Delay Queue)中。
  4. Service 會(huì)消費(fèi) SQS(Delay Queue)中的消息,并將該消息投遞到目標(biāo) topic 中。

簡(jiǎn)化后的方案將 Consumer、Emitter 和 Scheduler 的邏輯都集中在 Service 這個(gè)服務(wù)中,Service 服務(wù)是集群部署的,這種方案所有的邏輯都在 Service 這個(gè)服務(wù)中,在 troubleshooting 時(shí)相對(duì)來(lái)說(shuō)要方便一些。整體實(shí)現(xiàn)方案的大方向確定好以后,還需要細(xì)化以下幾個(gè)問(wèn)題:

1)消息如何存儲(chǔ)

我們可以看到 Message Store的主要功能是存儲(chǔ)延遲時(shí)間大于 15 分鐘的延遲消息, 并供 Scheduler 進(jìn)行查詢,查詢的時(shí)候是根據(jù)時(shí)間來(lái)查詢的。支持 Serverless 方式存儲(chǔ)的服務(wù)也比較多,經(jīng)過(guò)調(diào)研最后選擇 DynamoDB。

DynamoDB 中的 partition key 是延遲時(shí)間,sorted key 選擇 message id,這樣可以保證通過(guò) partition key 和 sorted key 能夠唯一定位到一條消息,不會(huì)出現(xiàn)沖突。同時(shí),在查詢的時(shí)候只需要根據(jù) partition key 就可以查詢出該時(shí)間片段內(nèi)的所有消息,也不會(huì)出現(xiàn)熱點(diǎn)或者 partition 不均勻的問(wèn)題。

假設(shè) partition key 為 1677400776(是 2023-02-26 16:39:35 的時(shí)間戳,精確到秒),則該 partition key 中對(duì)應(yīng)的所有消息都是延遲時(shí)間從 2023-02-26 16:39:35 到 2023-02-26 16:39:36 之間的消息。因?yàn)槊總€(gè)消息都有唯一的 message id,所以將 sorted key 設(shè)置為 message id 就不會(huì)導(dǎo)致消息沖突的問(wèn)題。Scheduler 在查詢的時(shí)候只需要傳入需要查詢的時(shí)間戳就可以拉取該時(shí)間段內(nèi)所有的消息,如果沒(méi)有查詢到,則表示該時(shí)間段內(nèi)沒(méi)有延遲消息。

同時(shí),對(duì)于 DynamoDB 中的消息也設(shè)置了 TTL 用來(lái)自動(dòng)刪除數(shù)據(jù)的,設(shè)置的 TTL 時(shí)間比延遲時(shí)間大 24 小時(shí),主要是方便 troubleshooting 的。當(dāng) DynamoDB 中的延遲消息被投遞到 SQS 以后,會(huì)調(diào)用 API 去刪除該消息。DynamoDB 中消息的數(shù)據(jù)結(jié)構(gòu)還包括 topic、消息體等信息。

2)單點(diǎn)問(wèn)題

單點(diǎn)問(wèn)題主要是因?yàn)閷?duì)于存儲(chǔ)在 DynomaDB 中大于 15 分鐘的延遲消息進(jìn)行掃描的時(shí)候,接收到掃描通知的 Scheduler 出現(xiàn)了問(wèn)題,則該時(shí)間段的消息沒(méi)有被投遞到 SQS中,從而導(dǎo)致消息丟失?,F(xiàn)在 Scheduler 的功能都集成在 Service 服務(wù)中,而 Service 服務(wù)是集群部署,所以 Scheduler 不存在單點(diǎn)的問(wèn)題。

但是需要解決另外一個(gè)問(wèn)題:如何保證集群中只有一個(gè) Scheduler 掃描 DynamoDB 中的數(shù)據(jù),并且當(dāng) Scheduler 出現(xiàn)了問(wèn)題以后,集群中其他 Scheduler 也可以繼續(xù)接著執(zhí)行?

為了解決這個(gè)問(wèn)題:我們使用了 SQS 的 FIFO 隊(duì)列。SQS 支持兩種隊(duì)列,一種是 Standard 對(duì)列,一種是 FIFO 隊(duì)列。FIFO 隊(duì)列可以嚴(yán)格保證消息的有序,同時(shí)支持消息的可見(jiàn)性,也就是說(shuō)在一段時(shí)間內(nèi)該消息只能有一個(gè)消費(fèi)者可見(jiàn),其他消費(fèi)者無(wú)法訪問(wèn)。同時(shí),SQS 的 FIFO 隊(duì)列還支持去重的功能?;?SQS 的 FIFI 隊(duì)列的這些特性,解決單點(diǎn)問(wèn)題就比較容易了。具體實(shí)現(xiàn)方案如下:

  1. 在 Service 服務(wù)中啟動(dòng)一個(gè) Timer 定時(shí)向 SQS 的 FIFO 隊(duì)列投遞通知消息,一分鐘投遞一次。通知消息的消息體是當(dāng)前時(shí)間的時(shí)間戳,精度到分鐘。這樣即使有 n 個(gè) Timer 在同一分鐘內(nèi)向 SQS 的 FIFO 隊(duì)列投遞 n 次消息,也只會(huì)有一條消息被成功投遞到 SQS 的 FIFO 隊(duì)列中,n-1 條消息被 SQS 的 FIFO 隊(duì)列的去重功能過(guò)濾掉了。
  2. 投遞到 SQS 的 FIFO 隊(duì)列中的可見(jiàn)性設(shè)置為 5分鐘(可以配置)??梢员WC在 5 分鐘內(nèi)只有一個(gè) Scheduler 可以消費(fèi)到通知消息,如果該 Scheduler 出現(xiàn)了故障,后續(xù)的其他 Scheduler 也可以接著繼續(xù)消費(fèi)。當(dāng) Scheduler 消費(fèi)到通知消息時(shí),會(huì)根據(jù)消息內(nèi)容轉(zhuǎn)換成時(shí)間戳,并在 DynamoDB 中查詢這一時(shí)間戳范圍內(nèi)的所有消息,修改消息的延遲時(shí)間,投遞到 SQS 的 Standard 隊(duì)列中,最后刪除 SQS 的 FIFO 隊(duì)列中的這一條通知消息。

基于上面的方案,能夠很好的解決單點(diǎn)問(wèn)題。

3)消息丟失問(wèn)題

因?yàn)?Timer 和 Schduler 都在 Service 服務(wù)中,都是集群?jiǎn)栴},不存在單點(diǎn)問(wèn)題。并且,SQS 的 FIFO 隊(duì)列能夠保證消息嚴(yán)格有序,所以不存在消息丟失的問(wèn)題。唯一可能存在的問(wèn)題是,因?yàn)橄⒘看蠓e壓導(dǎo)致的消息延遲過(guò)長(zhǎng)。

4)如何查詢延遲消息

Scheduler 查詢的消息要滿足該消息的延遲時(shí)間小于 15 分鐘,所以在接收到通知消息并轉(zhuǎn)換成對(duì)應(yīng)的時(shí)間戳以后,查詢當(dāng)前時(shí)間戳 +14 分鐘(延遲消息不能超過(guò) 15 分鐘)的消息即可。

5)如何部署 Service 服務(wù)

對(duì)于 Service 服務(wù),我們采用了 ECS+Fargate 的方式來(lái)部署。整個(gè)代碼的部署都是通過(guò) Terraform 腳本來(lái)創(chuàng)建 Code Pipeline、DynamoDB、SQS 和 ECS 等資源實(shí)現(xiàn)的,所有的資源都是通過(guò)代碼來(lái)實(shí)現(xiàn)的,整個(gè)部署方案的設(shè)計(jì)全部都是基于 gitOps 的思想。

經(jīng)過(guò)多以上方案的綜合評(píng)估,最后我們選擇基于 SQS 和定時(shí)調(diào)度策略的方案來(lái)實(shí)現(xiàn)延遲消息。

6.4 性能優(yōu)化

以上方案在實(shí)踐的過(guò)程中,做了很多優(yōu)化,大致可以歸納成以下幾點(diǎn):

1)消息積壓

由于需要處理的延遲消息會(huì)因?yàn)橄M(fèi)能力不足的情況導(dǎo)致消息積壓的問(wèn)題。優(yōu)化這一問(wèn)題主要從以下幾個(gè)方面入手:

  • Delay Message Topic 的 partition 設(shè)置成 64 個(gè)。提高 Kafka 消費(fèi)的消費(fèi)能力可以通過(guò)增加 consumer 來(lái)實(shí)現(xiàn),但是前提是要保證 partition 的數(shù)量大于等于 consumer 的數(shù)量。
  • 降低 Service 的服務(wù)配置,增加 Service 服務(wù)的副本數(shù)。Service 集群消費(fèi) Delay Message Topic 中的消息,副本數(shù)越多,消費(fèi)能力越強(qiáng)。

2)DynamoDB 中 WCU 和 RCU

DynamoDB 的費(fèi)用有很大一部分是通過(guò) WCU 和 RCU 來(lái)統(tǒng)計(jì)的。WCU 是指單位時(shí)間內(nèi)消息寫(xiě)入的數(shù)量,RCU 是指單位時(shí)間內(nèi)消息讀取的數(shù)量。如果單位時(shí)間內(nèi)寫(xiě)入消息的數(shù)量超過(guò)了 WCU 的限制會(huì)導(dǎo)致消息寫(xiě)入失敗,同理也會(huì)導(dǎo)致讀取消息失敗。

如果將 WCU 和 RCU 都設(shè)置成峰值肯定不會(huì)導(dǎo)致讀寫(xiě)失敗的問(wèn)題,但是會(huì)產(chǎn)生巨大的成本浪費(fèi)。為此,我們將 WCU 和 RCU 設(shè)置成動(dòng)態(tài)擴(kuò)縮容的方式。在擴(kuò)容期間如果產(chǎn)生失敗,則進(jìn)行重試。經(jīng)過(guò)相關(guān)參數(shù)的優(yōu)化,現(xiàn)在已經(jīng)可以達(dá)到一個(gè)最佳現(xiàn)狀。

3)ECS 擴(kuò)縮容設(shè)置

ECS 中最小的運(yùn)行單元是 task,對(duì)于每一個(gè) task 要求擴(kuò)容要快,縮容要緩慢。task 快速擴(kuò)容遇到的最大的問(wèn)題是,拉起 Service 的耗時(shí)比較長(zhǎng)。對(duì)于 Service 服務(wù)我們采用 golang 來(lái)實(shí)現(xiàn),擴(kuò)一個(gè) task 能夠基本上可以在 8s 內(nèi)完成。擴(kuò)縮容是基于 CPU 的使用峰值來(lái)設(shè)置的,每次擴(kuò)容會(huì)擴(kuò) 4 個(gè) task,每次所容會(huì)縮 1 個(gè) task。

4)消息平滑處理

由于寫(xiě)入 Delay Message Topic 中的消息峰值可能會(huì)比較大,如果快速消費(fèi)這些消息,會(huì)導(dǎo)致后續(xù)對(duì) DynamoDB 的讀寫(xiě)壓力比較大。因此,在消費(fèi) Kafka 的 Delay Message Topic 中的消息時(shí),會(huì)將控制每個(gè) Service 消費(fèi)消息的數(shù)量。盡管有多個(gè) Service 會(huì)同時(shí)消費(fèi),但是對(duì)于單個(gè) Service 來(lái)說(shuō),寫(xiě)入消息的數(shù)量較少,對(duì) DynamoDB 來(lái)說(shuō),每一次的寫(xiě)入比較平穩(wěn),并非一次性寫(xiě)入大量的數(shù)據(jù),從而寫(xiě)入失敗的概率會(huì)小很多。

6.5 實(shí)踐效果

目前已經(jīng)在生產(chǎn)環(huán)境穩(wěn)定運(yùn)行了 6 個(gè)月,各項(xiàng)指標(biāo)都比較健康,拉取了最近 4 周的數(shù)據(jù)。

1)延遲消息成功率

圖片

如上圖所示,延遲誤差在 2 秒以內(nèi)的延遲消息成功率基本上是 100%。

2)延遲消息的數(shù)量

圖片

如果上圖所示,延遲消息在 5 分鐘內(nèi)的峰值達(dá)到 15 萬(wàn),也就是峰值每秒處理 500 個(gè)延遲消息。

3)DynamoDB 性能指標(biāo)

圖片

從 PutItem ThrottledRequests 這個(gè)指標(biāo)可以看出,通過(guò) DynamoDB 寫(xiě)入消息沒(méi)有發(fā)生寫(xiě)入失敗的情況。從 QueryThrottledRequests 這個(gè)指標(biāo)可以看出,通過(guò) DynamoDB 查詢消息也沒(méi)有發(fā)生查詢失敗的情況。從 QueryReturnedItemCount 指標(biāo)可以看出,延遲消息的峰值是 5 分鐘內(nèi) 3350 條,每秒低于 60 條。這是因?yàn)槲覀冊(cè)?Service 中對(duì)寫(xiě)入消息進(jìn)行了緩沖,從而降低了并發(fā)讀寫(xiě)壓力。

4)Kafka 消息積壓

圖片

如上圖所示,Kafka 在 5 分鐘內(nèi)消息積壓的峰值是 6 萬(wàn),積壓的消息都能很快被消費(fèi)掉。

5)Timer 性能指標(biāo)

圖片

Timer 會(huì)每分鐘向 SQS 的 FIFO 隊(duì)列中投遞一個(gè)消息,消息的數(shù)量與 Service 的副本數(shù)相同。從上圖可以看出,5 分鐘內(nèi)最多投遞了 300 個(gè)消息(因?yàn)?Service 的副本數(shù)最大為 64)。但是最后接收的消息是5分鐘內(nèi)僅僅接收了 5 個(gè)消息,也就是 1 分鐘接收 1 條消息。

七、總結(jié)

由于該實(shí)現(xiàn)方案完全是基于 Serverless 的方式實(shí)現(xiàn)的,所以維護(hù)成本非常低。盡管開(kāi)發(fā)起來(lái)有些復(fù)雜,但這是一次性的成本投入。從近幾個(gè)月的數(shù)據(jù)來(lái)看,云上的使用成本大約每個(gè)月不超過(guò) 200 美元,誤差延遲比較小,到目前為止整體運(yùn)行起來(lái)比較穩(wěn)定。

責(zé)任編輯:張燕妮 來(lái)源: 攜程技術(shù)
相關(guān)推薦

2022-05-19 17:50:31

bookie集群延遲消息存儲(chǔ)服務(wù)

2023-11-06 09:56:10

研究代碼

2023-01-13 08:35:29

告警降噪系統(tǒng)

2023-04-14 10:29:24

小程序實(shí)踐

2022-06-27 09:42:55

攜程金融nebula圖平臺(tái)

2016-09-04 15:14:09

攜程實(shí)時(shí)數(shù)據(jù)數(shù)據(jù)平臺(tái)

2022-06-27 09:36:29

攜程度假GraphQL多端開(kāi)發(fā)

2019-09-22 19:57:38

極簡(jiǎn)代碼開(kāi)發(fā)代碼

2011-05-11 12:19:41

應(yīng)用交付服務(wù)器

2023-06-06 11:49:24

2025-01-03 14:33:41

2023-11-17 10:03:45

攜程開(kāi)源

2023-06-28 14:01:13

攜程實(shí)踐

2022-08-20 07:46:03

Dynamo攜程數(shù)據(jù)庫(kù)

2023-07-07 12:26:39

攜程開(kāi)發(fā)

2023-11-24 09:44:07

數(shù)據(jù)攜程

2009-08-28 09:33:03

云計(jì)算成本

2022-05-13 09:27:55

Widget機(jī)票業(yè)務(wù)App

2022-05-26 10:25:19

PythonWeb框架

2024-07-05 15:05:00

點(diǎn)贊
收藏

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