精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

我用Kafka兩年踩過(guò)的一些非比尋常的坑

開(kāi)發(fā) 架構(gòu) Kafka
我的上家公司是做餐飲系統(tǒng)的,每天中午和晚上用餐高峰期,系統(tǒng)的并發(fā)量不容小覷。為了保險(xiǎn)起見(jiàn),公司規(guī)定各部門(mén)都要在吃飯的時(shí)間輪流值班,防止出現(xiàn)線(xiàn)上問(wèn)題時(shí)能夠及時(shí)處理。

[[382627]]

本文轉(zhuǎn)載自微信公眾號(hào)「蘇三說(shuō)技術(shù)」,作者因?yàn)闊釔?ài)所以堅(jiān)持ing。轉(zhuǎn)載本文請(qǐng)聯(lián)系蘇三說(shuō)技術(shù)公眾號(hào)。  

前言

我的上家公司是做餐飲系統(tǒng)的,每天中午和晚上用餐高峰期,系統(tǒng)的并發(fā)量不容小覷。為了保險(xiǎn)起見(jiàn),公司規(guī)定各部門(mén)都要在吃飯的時(shí)間輪流值班,防止出現(xiàn)線(xiàn)上問(wèn)題時(shí)能夠及時(shí)處理。

我當(dāng)時(shí)在后廚顯示系統(tǒng)團(tuán)隊(duì),該系統(tǒng)屬于訂單的下游業(yè)務(wù)。用戶(hù)點(diǎn)完菜下單后,訂單系統(tǒng)會(huì)通過(guò)發(fā)kafka消息給我們系統(tǒng),系統(tǒng)讀取消息后,做業(yè)務(wù)邏輯處理,持久化訂單和菜品數(shù)據(jù),然后展示到劃菜客戶(hù)端。這樣廚師就知道哪個(gè)訂單要做哪些菜,有些菜做好了,就可以通過(guò)該系統(tǒng)出菜。系統(tǒng)自動(dòng)通知服務(wù)員上菜,如果服務(wù)員上完菜,修改菜品上菜狀態(tài),用戶(hù)就知道哪些菜已經(jīng)上了,哪些還沒(méi)有上。這個(gè)系統(tǒng)可以大大提高后廚到用戶(hù)的效率。

事實(shí)證明,這一切的關(guān)鍵是消息中間件:kafka,如果它有問(wèn)題,將會(huì)直接影響到后廚顯示系統(tǒng)的功能。

接下來(lái),我跟大家一起聊聊使用kafka兩年時(shí)間踩過(guò)哪些坑?

順序問(wèn)題

1. 為什么要保證消息的順序?

剛開(kāi)始我們系統(tǒng)的商戶(hù)很少,為了快速實(shí)現(xiàn)功能,我們沒(méi)想太多。既然是走消息中間件kafka通信,訂單系統(tǒng)發(fā)消息時(shí)將訂單詳細(xì)數(shù)據(jù)放在消息體,我們后廚顯示系統(tǒng)只要訂閱topic,就能獲取相關(guān)消息數(shù)據(jù),然后處理自己的業(yè)務(wù)即可。

不過(guò)這套方案有個(gè)關(guān)鍵因素:要保證消息的順序。

為什么呢?

訂單有很多狀態(tài),比如:下單、支付、完成、撤銷(xiāo)等,不可能下單的消息都沒(méi)讀取到,就先讀取支付或撤銷(xiāo)的消息吧,如果真的這樣,數(shù)據(jù)不是會(huì)產(chǎn)生錯(cuò)亂?

好吧,看來(lái)保證消息順序是有必要的。

2.如何保證消息順序?

我們都知道kafka的topic是無(wú)序的,但是一個(gè)topic包含多個(gè)partition,每個(gè)partition內(nèi)部是有序的。

如此一來(lái),思路就變得清晰了:只要保證生產(chǎn)者寫(xiě)消息時(shí),按照一定的規(guī)則寫(xiě)到同一個(gè)partition,不同的消費(fèi)者讀不同的partition的消息,就能保證生產(chǎn)和消費(fèi)者消息的順序。

我們剛開(kāi)始就是這么做的,同一個(gè)商戶(hù)編號(hào)的消息寫(xiě)到同一個(gè)partition,topic中創(chuàng)建了4個(gè)partition,然后部署了4個(gè)消費(fèi)者節(jié)點(diǎn),構(gòu)成消費(fèi)者組,一個(gè)partition對(duì)應(yīng)一個(gè)消費(fèi)者節(jié)點(diǎn)。從理論上說(shuō),這套方案是能夠保證消息順序的。

一切規(guī)劃得看似“天衣無(wú)縫”,我們就這樣”順利“上線(xiàn)了。

3.出現(xiàn)意外

該功能上線(xiàn)了一段時(shí)間,剛開(kāi)始還是比較正常的。

但是,好景不長(zhǎng),很快就收到用戶(hù)投訴,說(shuō)在劃菜客戶(hù)端有些訂單和菜品一直看不到,無(wú)法劃菜。

我定位到了原因,公司在那段時(shí)間網(wǎng)絡(luò)經(jīng)常不穩(wěn)定,業(yè)務(wù)接口時(shí)不時(shí)報(bào)超時(shí),業(yè)務(wù)請(qǐng)求時(shí)不時(shí)會(huì)連不上數(shù)據(jù)庫(kù)。

這種情況對(duì)順序消息的打擊,可以說(shuō)是毀滅性的。

為什么這么說(shuō)?

假設(shè)訂單系統(tǒng)發(fā)了:”下單“、”支付“、”完成“ 三條消息。

而”下單“消息由于網(wǎng)絡(luò)原因我們系統(tǒng)處理失敗了,而后面的兩條消息的數(shù)據(jù)是無(wú)法入庫(kù)的,因?yàn)橹挥?rdquo;下單“消息的數(shù)據(jù)才是完整的數(shù)據(jù),其他類(lèi)型的消息只會(huì)更新?tīng)顟B(tài)。

加上,我們當(dāng)時(shí)沒(méi)有做失敗重試機(jī)制,使得這個(gè)問(wèn)題被放大了。問(wèn)題變成:一旦”下單“消息的數(shù)據(jù)入庫(kù)失敗,用戶(hù)就永遠(yuǎn)看不到這個(gè)訂單和菜品了。

那么這個(gè)緊急的問(wèn)題要如何解決呢?

4.解決過(guò)程

最開(kāi)始我們的想法是:在消費(fèi)者處理消息時(shí),如果處理失敗了,立馬重試3-5次。但如果有些請(qǐng)求要第6次才能成功怎么辦?不可能一直重試呀,這種同步重試機(jī)制,會(huì)阻塞其他商戶(hù)訂單消息的讀取。

顯然用上面的這種同步重試機(jī)制在出現(xiàn)異常的情況,會(huì)嚴(yán)重影響消息消費(fèi)者的消費(fèi)速度,降低它的吞吐量。

如此看來(lái),我們不得不用異步重試機(jī)制了。

如果用異步重試機(jī)制,處理失敗的消息就得保存到重試表下來(lái)。

但有個(gè)新問(wèn)題立馬出現(xiàn):只存一條消息如何保證順序?

存一條消息的確無(wú)法保證順序,假如:”下單“消息失敗了,還沒(méi)來(lái)得及異步重試。此時(shí),”支付“消息被消費(fèi)了,它肯定是不能被正常消費(fèi)的。

此時(shí),”支付“消息該一直等著,每隔一段時(shí)間判斷一次,它前面的消息都有沒(méi)有被消費(fèi)?

如果真的這么做,會(huì)出現(xiàn)兩個(gè)問(wèn)題:

  1. ”支付“消息前面只有”下單“消息,這種情況比較簡(jiǎn)單。但如果某種類(lèi)型的消息,前面有N多種消息,需要判斷多少次呀,這種判斷跟訂單系統(tǒng)的耦合性太強(qiáng)了,相當(dāng)于要把他們系統(tǒng)的邏輯搬一部分到我們系統(tǒng)。
  2. 影響消費(fèi)者的消費(fèi)速度

這時(shí)有種更簡(jiǎn)單的方案浮出水面:消費(fèi)者在處理消息時(shí),先判斷該訂單號(hào)在重試表有沒(méi)有數(shù)據(jù),如果有則直接把當(dāng)前消息保存到重試表。如果沒(méi)有,則進(jìn)行業(yè)務(wù)處理,如果出現(xiàn)異常,把該消息保存到重試表。

后來(lái)我們用elastic-job建立了失敗重試機(jī)制,如果重試了7次后還是失敗,則將該消息的狀態(tài)標(biāo)記為失敗,發(fā)郵件通知開(kāi)發(fā)人員。

終于由于網(wǎng)絡(luò)不穩(wěn)定,導(dǎo)致用戶(hù)在劃菜客戶(hù)端有些訂單和菜品一直看不到的問(wèn)題被解決了。現(xiàn)在商戶(hù)頂多偶爾延遲看到菜品,比一直看不菜品好太多。

消息積壓

隨著銷(xiāo)售團(tuán)隊(duì)的市場(chǎng)推廣,我們系統(tǒng)的商戶(hù)越來(lái)越多。隨之而來(lái)的是消息的數(shù)量越來(lái)越大,導(dǎo)致消費(fèi)者處理不過(guò)來(lái),經(jīng)常出現(xiàn)消息積壓的情況。對(duì)商戶(hù)的影響非常直觀,劃菜客戶(hù)端上的訂單和菜品可能半個(gè)小時(shí)后才能看到。一兩分鐘還能忍,半個(gè)消息的延遲,對(duì)有些暴脾氣的商戶(hù)哪里忍得了,馬上投訴過(guò)來(lái)了。我們那段時(shí)間經(jīng)常接到商戶(hù)投訴說(shuō)訂單和菜品有延遲。

雖說(shuō),加服務(wù)器節(jié)點(diǎn)就能解決問(wèn)題,但是按照公司為了省錢(qián)的慣例,要先做系統(tǒng)優(yōu)化,所以我們開(kāi)始了消息積壓?jiǎn)栴}解決之旅。

1. 消息體過(guò)大

雖說(shuō)kafka號(hào)稱(chēng)支持百萬(wàn)級(jí)的TPS,但從producer發(fā)送消息到broker需要一次網(wǎng)絡(luò)IO,broker寫(xiě)數(shù)據(jù)到磁盤(pán)需要一次磁盤(pán)IO(寫(xiě)操作),consumer從broker獲取消息先經(jīng)過(guò)一次磁盤(pán)IO(讀操作),再經(jīng)過(guò)一次網(wǎng)絡(luò)IO。

一次簡(jiǎn)單的消息從生產(chǎn)到消費(fèi)過(guò)程,需要經(jīng)過(guò)2次網(wǎng)絡(luò)IO和2次磁盤(pán)IO。如果消息體過(guò)大,勢(shì)必會(huì)增加IO的耗時(shí),進(jìn)而影響kafka生產(chǎn)和消費(fèi)的速度。消費(fèi)者速度太慢的結(jié)果,就會(huì)出現(xiàn)消息積壓情況。

除了上面的問(wèn)題之外,消息體過(guò)大,還會(huì)浪費(fèi)服務(wù)器的磁盤(pán)空間,稍不注意,可能會(huì)出現(xiàn)磁盤(pán)空間不足的情況。

此時(shí),我們已經(jīng)到了需要優(yōu)化消息體過(guò)大問(wèn)題的時(shí)候。

如何優(yōu)化呢?

我們重新梳理了一下業(yè)務(wù),沒(méi)有必要知道訂單的中間狀態(tài),只需知道一個(gè)最終狀態(tài)就可以了。

如此甚好,我們就可以這樣設(shè)計(jì)了:

訂單系統(tǒng)發(fā)送的消息體只用包含:id和狀態(tài)等關(guān)鍵信息。

后廚顯示系統(tǒng)消費(fèi)消息后,通過(guò)id調(diào)用訂單系統(tǒng)的訂單詳情查詢(xún)接口獲取數(shù)據(jù)。

后廚顯示系統(tǒng)判斷數(shù)據(jù)庫(kù)中是否有該訂單的數(shù)據(jù),如果沒(méi)有則入庫(kù),有則更新。

果然這樣調(diào)整之后,消息積壓?jiǎn)栴}很長(zhǎng)一段時(shí)間都沒(méi)再出現(xiàn)。

2. 路由規(guī)則不合理

還真別高興的太早,有天中午又有商戶(hù)投訴說(shuō)訂單和菜品有延遲。我們一查kafka的topic竟然又出現(xiàn)了消息積壓。

但這次有點(diǎn)詭異,不是所有partition上的消息都有積壓,而是只有一個(gè)。

剛開(kāi)始,我以為是消費(fèi)那個(gè)partition消息的節(jié)點(diǎn)出了什么問(wèn)題導(dǎo)致的。但是經(jīng)過(guò)排查,沒(méi)有發(fā)現(xiàn)任何異常。

這就奇怪了,到底哪里有問(wèn)題呢?

后來(lái),我查日志和數(shù)據(jù)庫(kù)發(fā)現(xiàn),有幾個(gè)商戶(hù)的訂單量特別大,剛好這幾個(gè)商戶(hù)被分到同一個(gè)partition,使得該partition的消息量比其他partition要多很多。

這時(shí)我們才意識(shí)到,發(fā)消息時(shí)按商戶(hù)編號(hào)路由partition的規(guī)則不合理,可能會(huì)導(dǎo)致有些partition消息太多,消費(fèi)者處理不過(guò)來(lái),而有些partition卻因?yàn)橄⑻伲M(fèi)者出現(xiàn)空閑的情況。

為了避免出現(xiàn)這種分配不均勻的情況,我們需要對(duì)發(fā)消息的路由規(guī)則做一下調(diào)整。

我們思考了一下,用訂單號(hào)做路由相對(duì)更均勻,不會(huì)出現(xiàn)單個(gè)訂單發(fā)消息次數(shù)特別多的情況。除非是遇到某個(gè)人一直加菜的情況,但是加菜是需要花錢(qián)的,所以其實(shí)同一個(gè)訂單的消息數(shù)量并不多。

調(diào)整后按訂單號(hào)路由到不同的partition,同一個(gè)訂單號(hào)的消息,每次到發(fā)到同一個(gè)partition。

調(diào)整后,消息積壓的問(wèn)題又有很長(zhǎng)一段時(shí)間都沒(méi)有再出現(xiàn)。我們的商戶(hù)數(shù)量在這段時(shí)間,增長(zhǎng)的非常快,越來(lái)越多了。

3. 批量操作引起的連鎖反應(yīng)

在高并發(fā)的場(chǎng)景中,消息積壓?jiǎn)栴},可以說(shuō)如影隨形,真的沒(méi)辦法從根本上解決。表面上看,已經(jīng)解決了,但后面不知道什么時(shí)候,就會(huì)冒出一次,比如這次:

有天下午,產(chǎn)品過(guò)來(lái)說(shuō):有幾個(gè)商戶(hù)投訴過(guò)來(lái)了,他們說(shuō)菜品有延遲,快查一下原因。

這次問(wèn)題出現(xiàn)得有點(diǎn)奇怪。

為什么這么說(shuō)?

首先這個(gè)時(shí)間點(diǎn)就有點(diǎn)奇怪,平常出問(wèn)題,不都是中午或者晚上用餐高峰期嗎?怎么這次問(wèn)題出現(xiàn)在下午?

根據(jù)以往積累的經(jīng)驗(yàn),我直接看了kafka的topic的數(shù)據(jù),果然上面消息有積壓,但這次每個(gè)partition都積壓了十幾萬(wàn)的消息沒(méi)有消費(fèi),比以往加壓的消息數(shù)量增加了幾百倍。這次消息積壓得極不尋常。

我趕緊查服務(wù)監(jiān)控看看消費(fèi)者掛了沒(méi),還好沒(méi)掛。又查服務(wù)日志沒(méi)有發(fā)現(xiàn)異常。這時(shí)我有點(diǎn)迷茫,碰運(yùn)氣問(wèn)了問(wèn)訂單組下午發(fā)生了什么事情沒(méi)?他們說(shuō)下午有個(gè)促銷(xiāo)活動(dòng),跑了一個(gè)JOB批量更新過(guò)有些商戶(hù)的訂單信息。

這時(shí),我一下子如夢(mèng)初醒,是他們?cè)贘OB中批量發(fā)消息導(dǎo)致的問(wèn)題。怎么沒(méi)有通知我們呢?實(shí)在太坑了。

雖說(shuō)知道問(wèn)題的原因了,倒是眼前積壓的這十幾萬(wàn)的消息該如何處理呢?

此時(shí),如果直接調(diào)大partition數(shù)量是不行的,歷史消息已經(jīng)存儲(chǔ)到4個(gè)固定的partition,只有新增的消息才會(huì)到新的partition。我們重點(diǎn)需要處理的是已有的partition。

直接加服務(wù)節(jié)點(diǎn)也不行,因?yàn)閗afka允許同組的多個(gè)partition被一個(gè)consumer消費(fèi),但不允許一個(gè)partition被同組的多個(gè)consumer消費(fèi),可能會(huì)造成資源浪費(fèi)。

看來(lái)只有用多線(xiàn)程處理了。

為了緊急解決問(wèn)題,我改成了用線(xiàn)程池處理消息,核心線(xiàn)程和最大線(xiàn)程數(shù)都配置成了50。

調(diào)整之后,果然,消息積壓數(shù)量不斷減少。

但此時(shí)有個(gè)更嚴(yán)重的問(wèn)題出現(xiàn):我收到了報(bào)警郵件,有兩個(gè)訂單系統(tǒng)的節(jié)點(diǎn)down機(jī)了。

不久,訂單組的同事過(guò)來(lái)找我說(shuō),我們系統(tǒng)調(diào)用他們訂單查詢(xún)接口的并發(fā)量突增,超過(guò)了預(yù)計(jì)的好幾倍,導(dǎo)致有2個(gè)服務(wù)節(jié)點(diǎn)掛了。他們把查詢(xún)功能單獨(dú)整成了一個(gè)服務(wù),部署了6個(gè)節(jié)點(diǎn),掛了2個(gè)節(jié)點(diǎn),再不處理,另外4個(gè)節(jié)點(diǎn)也會(huì)掛。訂單服務(wù)可以說(shuō)是公司最核心的服務(wù),它掛了公司損失會(huì)很大,情況萬(wàn)分緊急。

為了解決這個(gè)問(wèn)題,只能先把線(xiàn)程數(shù)調(diào)小。

幸好,線(xiàn)程數(shù)是可以通過(guò)zookeeper動(dòng)態(tài)調(diào)整的,我把核心線(xiàn)程數(shù)調(diào)成了8個(gè),核心線(xiàn)程數(shù)改成了10個(gè)。

后面,運(yùn)維把訂單服務(wù)掛的2個(gè)節(jié)點(diǎn)重啟后恢復(fù)正常了,以防萬(wàn)一,再多加了2個(gè)節(jié)點(diǎn)。為了確保訂單服務(wù)不會(huì)出現(xiàn)問(wèn)題,就保持目前的消費(fèi)速度,后廚顯示系統(tǒng)的消息積壓?jiǎn)栴},1小時(shí)候后也恢復(fù)正常了。

后來(lái),我們開(kāi)了一次復(fù)盤(pán)會(huì),得出的結(jié)論是:

  1. 訂單系統(tǒng)的批量操作一定提前通知下游系統(tǒng)團(tuán)隊(duì)。
  2. 下游系統(tǒng)團(tuán)隊(duì)多線(xiàn)程調(diào)用訂單查詢(xún)接口一定要做壓測(cè)。
  3. 這次給訂單查詢(xún)服務(wù)敲響了警鐘,它作為公司的核心服務(wù),應(yīng)對(duì)高并發(fā)場(chǎng)景做的不夠好,需要做優(yōu)化。
  4. 對(duì)消息積壓情況加監(jiān)控。

順便說(shuō)一下,對(duì)于要求嚴(yán)格保證消息順序的場(chǎng)景,可以將線(xiàn)程池改成多個(gè)隊(duì)列,每個(gè)隊(duì)列用單線(xiàn)程處理。

4. 表過(guò)大

為了防止后面再次出現(xiàn)消息積壓?jiǎn)栴},消費(fèi)者后面就一直用多線(xiàn)程處理消息。

但有天中午我們還是收到很多報(bào)警郵件,提醒我們kafka的topic消息有積壓。我們正在查原因,此時(shí)產(chǎn)品跑過(guò)來(lái)說(shuō):又有商戶(hù)投訴說(shuō)菜品有延遲,趕緊看看。這次她看起來(lái)有些不耐煩,確實(shí)優(yōu)化了很多次,還是出現(xiàn)了同樣的問(wèn)題。

在外行看來(lái):為什么同一個(gè)問(wèn)題一直解決不了?

其實(shí)技術(shù)心里的苦他們是不知道的。

表面上問(wèn)題的癥狀是一樣的,都是出現(xiàn)了菜品延遲,他們知道的是因?yàn)橄⒎e壓導(dǎo)致的。但是他們不知道深層次的原因,導(dǎo)致消息積壓的原因其實(shí)有很多種。這也許是使用消息中間件的通病吧。

我沉默不語(yǔ),只能硬著頭皮定位原因了。

后來(lái)我查日志發(fā)現(xiàn)消費(fèi)者消費(fèi)一條消息的耗時(shí)長(zhǎng)達(dá)2秒。以前是500毫秒,現(xiàn)在怎么會(huì)變成2秒呢?

奇怪了,消費(fèi)者的代碼也沒(méi)有做大的調(diào)整,為什么會(huì)出現(xiàn)這種情況呢?

查了一下線(xiàn)上菜品表,單表數(shù)據(jù)量竟然到了幾千萬(wàn),其他的劃菜表也是一樣,現(xiàn)在單表保存的數(shù)據(jù)太多了。

我們組梳理了一下業(yè)務(wù),其實(shí)菜品在客戶(hù)端只展示最近3天的即可。

這就好辦了,我們服務(wù)端存著多余的數(shù)據(jù),不如把表中多余的數(shù)據(jù)歸檔。于是,DBA幫我們把數(shù)據(jù)做了歸檔,只保留最近7天的數(shù)據(jù)。

如此調(diào)整后,消息積壓?jiǎn)栴}被解決了,又恢復(fù)了往日的平靜。

主鍵沖突

別高興得太早了,還有其他的問(wèn)題,比如:報(bào)警郵件經(jīng)常報(bào)出數(shù)據(jù)庫(kù)異常: Duplicate entry '6' for key 'PRIMARY',說(shuō)主鍵沖突。

出現(xiàn)這種問(wèn)題一般是由于有兩個(gè)以上相同主鍵的sql,同時(shí)插入數(shù)據(jù),第一個(gè)插入成功后,第二個(gè)插入的時(shí)候會(huì)報(bào)主鍵沖突。表的主鍵是唯一的,不允許重復(fù)。

我仔細(xì)檢查了代碼,發(fā)現(xiàn)代碼邏輯會(huì)先根據(jù)主鍵從表中查詢(xún)訂單是否存在,如果存在則更新?tīng)顟B(tài),不存在才插入數(shù)據(jù),沒(méi)得問(wèn)題。

這種判斷在并發(fā)量不大時(shí),是有用的。但是如果在高并發(fā)的場(chǎng)景下,兩個(gè)請(qǐng)求同一時(shí)刻都查到訂單不存在,一個(gè)請(qǐng)求先插入數(shù)據(jù),另一個(gè)請(qǐng)求再插入數(shù)據(jù)時(shí)就會(huì)出現(xiàn)主鍵沖突的異常。

解決這個(gè)問(wèn)題最常規(guī)的做法是:加鎖。

我剛開(kāi)始也是這樣想的,加數(shù)據(jù)庫(kù)悲觀鎖肯定是不行的,太影響性能。加數(shù)據(jù)庫(kù)樂(lè)觀鎖,基于版本號(hào)判斷,一般用于更新操作,像這種插入操作基本上不會(huì)用。

剩下的只能用分布式鎖了,我們系統(tǒng)在用redis,可以加基于redis的分布式鎖,鎖定訂單號(hào)。

但后面仔細(xì)思考了一下:

  1. 加分布式鎖也可能會(huì)影響消費(fèi)者的消息處理速度。
  2. 消費(fèi)者依賴(lài)于redis,如果redis出現(xiàn)網(wǎng)絡(luò)超時(shí),我們的服務(wù)就悲劇了。

所以,我也不打算用分布式鎖。

而是選擇使用mysql的INSERT INTO ...ON DUPLICATE KEY UPDATE語(yǔ)法:

  1. INSERT INTO table (column_list) 
  2. VALUES (value_list) 
  3. ON DUPLICATE KEY UPDATE 
  4. c1 = v1,  
  5. c2 = v2, 
  6. ...; 

它會(huì)先嘗試把數(shù)據(jù)插入表,如果主鍵沖突的話(huà)那么更新字段。

把以前的insert語(yǔ)句改造之后,就沒(méi)再出現(xiàn)過(guò)主鍵沖突問(wèn)題。

數(shù)據(jù)庫(kù)主從延遲

不久之后的某天,又收到商戶(hù)投訴說(shuō)下單后,在劃菜客戶(hù)端上看得到訂單,但是看到的菜品不全,有時(shí)甚至訂單和菜品數(shù)據(jù)都看不到。

這個(gè)問(wèn)題跟以往的都不一樣,根據(jù)以往的經(jīng)驗(yàn)先看kafka的topic中消息有沒(méi)有積壓,但這次并沒(méi)有積壓。

再查了服務(wù)日志,發(fā)現(xiàn)訂單系統(tǒng)接口返回的數(shù)據(jù)有些為空,有些只返回了訂單數(shù)據(jù),沒(méi)返回菜品數(shù)據(jù)。

這就非常奇怪了,我直接過(guò)去找訂單組的同事。他們仔細(xì)排查服務(wù),沒(méi)有發(fā)現(xiàn)問(wèn)題。這時(shí)我們不約而同的想到,會(huì)不會(huì)是數(shù)據(jù)庫(kù)出問(wèn)題了,一起去找DBA。果然,DBA發(fā)現(xiàn)數(shù)據(jù)庫(kù)的主庫(kù)同步數(shù)據(jù)到從庫(kù),由于網(wǎng)絡(luò)原因偶爾有延遲,有時(shí)延遲有3秒。

如果我們的業(yè)務(wù)流程從發(fā)消息到消費(fèi)消息耗時(shí)小于3秒,調(diào)用訂單詳情查詢(xún)接口時(shí),可能會(huì)查不到數(shù)據(jù),或者查到的不是最新的數(shù)據(jù)。

這個(gè)問(wèn)題非常嚴(yán)重,會(huì)導(dǎo)致直接我們的數(shù)據(jù)錯(cuò)誤。

為了解決這個(gè)問(wèn)題,我們也加了重試機(jī)制。調(diào)用接口查詢(xún)數(shù)據(jù)時(shí),如果返回?cái)?shù)據(jù)為空,或者只返回了訂單沒(méi)有菜品,則加入重試表。

調(diào)整后,商戶(hù)投訴的問(wèn)題被解決了。

重復(fù)消費(fèi)

kafka消費(fèi)消息時(shí)支持三種模式:

  • at most onece模式 最多一次。保證每一條消息commit成功之后,再進(jìn)行消費(fèi)處理。消息可能會(huì)丟失,但不會(huì)重復(fù)。
  • at least onece模式 至少一次。保證每一條消息處理成功之后,再進(jìn)行commit。消息不會(huì)丟失,但可能會(huì)重復(fù)。
  • exactly onece模式 精確傳遞一次。將offset作為唯一id與消息同時(shí)處理,并且保證處理的原子性。消息只會(huì)處理一次,不丟失也不會(huì)重復(fù)。但這種方式很難做到。

kafka默認(rèn)的模式是at least onece,但這種模式可能會(huì)產(chǎn)生重復(fù)消費(fèi)的問(wèn)題,所以我們的業(yè)務(wù)邏輯必須做冪等設(shè)計(jì)。

而我們的業(yè)務(wù)場(chǎng)景保存數(shù)據(jù)時(shí)使用了INSERT INTO ...ON DUPLICATE KEY UPDATE語(yǔ)法,不存在時(shí)插入,存在時(shí)更新,是天然支持冪等性的。

多環(huán)境消費(fèi)問(wèn)題

我們當(dāng)時(shí)線(xiàn)上環(huán)境分為:pre(預(yù)發(fā)布環(huán)境) 和 prod(生產(chǎn)環(huán)境),兩個(gè)環(huán)境共用同一個(gè)數(shù)據(jù)庫(kù),并且共用同一個(gè)kafka集群。

需要注意的是,在配置kafka的topic的時(shí)候,要加前綴用于區(qū)分不同環(huán)境。pre環(huán)境的以pre_開(kāi)頭,比如:pre_order,生產(chǎn)環(huán)境以prod_開(kāi)頭,比如:prod_order,防止消息在不同環(huán)境中串了。

但有次運(yùn)維在pre環(huán)境切換節(jié)點(diǎn),配置topic的時(shí)候,配錯(cuò)了,配成了prod的topic。剛好那天,我們有新功能上pre環(huán)境。結(jié)果悲劇了,prod的有些消息被pre環(huán)境的consumer消費(fèi)了,而由于消息體做了調(diào)整,導(dǎo)致pre環(huán)境的consumer處理消息一直失敗。

其結(jié)果是生產(chǎn)環(huán)境丟了部分消息。不過(guò)還好,最后生產(chǎn)環(huán)境消費(fèi)者通過(guò)重置offset,重新讀取了那一部分消息解決了問(wèn)題,沒(méi)有造成太大損失。

后記

除了上述問(wèn)題之外,我還遇到過(guò):

  • kafka的consumer使用自動(dòng)確認(rèn)機(jī)制,導(dǎo)致cpu使用率100%。
  • kafka集群中的一個(gè)broker節(jié)點(diǎn)掛了,重啟后又一直掛。

這兩個(gè)問(wèn)題說(shuō)起來(lái)有些復(fù)雜,我就不一一列舉了,有興趣的朋友可以關(guān)注我的公眾號(hào),加我的微信找我私聊。

非常感謝那兩年使用消息中間件kafka的經(jīng)歷,雖說(shuō)遇到過(guò)挺多問(wèn)題,踩了很多坑,走了很多彎路,但是實(shí)打?qū)嵉淖屛曳e累了很多寶貴的經(jīng)驗(yàn),快速成長(zhǎng)了。

其實(shí)kafka是一個(gè)非常優(yōu)秀的消息中間件,我所遇到的絕大多數(shù)問(wèn)題,都并非kafka自身的問(wèn)題(除了cpu使用率100%是它的一個(gè)bug導(dǎo)致的之外)。

 

責(zé)任編輯:武曉燕 來(lái)源: 蘇三說(shuō)技術(shù)
相關(guān)推薦

2020-07-21 08:00:44

架構(gòu)師BAT線(xiàn)程

2022-12-21 11:37:34

開(kāi)發(fā)云原生

2024-05-06 00:00:00

緩存高并發(fā)數(shù)據(jù)

2024-04-01 08:05:27

Go開(kāi)發(fā)Java

2023-12-14 17:34:22

Kubernetes集群K8s

2017-07-17 15:46:20

Oracle并行機(jī)制

2025-10-16 08:10:59

2021-06-08 06:13:16

React開(kāi)發(fā)開(kāi)發(fā)技術(shù)

2018-01-10 13:40:03

數(shù)據(jù)庫(kù)MySQL表設(shè)計(jì)

2019-10-30 14:44:41

Prometheus開(kāi)源監(jiān)控系統(tǒng)

2025-11-06 02:55:00

2015-12-30 11:14:57

前端工具

2019-02-19 09:46:58

美圖容器化Kubernetes

2011-11-30 09:32:41

互聯(lián)網(wǎng)經(jīng)濟(jì)大會(huì)

2020-11-18 10:16:23

人工智能機(jī)器學(xué)習(xí)技術(shù)

2021-06-30 07:19:35

微服務(wù)業(yè)務(wù)MySQL

2017-10-23 12:22:58

Android編程基礎(chǔ)總結(jié)

2015-03-24 16:29:55

默認(rèn)線(xiàn)程池java

2025-05-15 09:31:15

2022-11-27 17:21:04

ClickHouseJDBC函數(shù)
點(diǎn)贊
收藏

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

成人美女av在线直播| 亚洲欧美国产视频| 伊人久久在线观看| 亚洲av无码国产综合专区| 亚洲精品社区| 一区二区欧美在线| 亚洲一区二区三区三州| 欧美激情网站| 中文字幕五月欧美| 国产精品美女久久久久av福利| 久久久久久久久精| 国产影视一区| 精品国产电影一区二区| 嫩草av久久伊人妇女超级a| 天堂аⅴ在线地址8| 国产乱国产乱300精品| 538国产精品一区二区在线 | 在线观看18视频网站| 蜜臀久久99精品久久久| 蜜桃久久精品一区二区| 久久久久久有精品国产| 最近中文字幕免费视频| 欧州一区二区三区| 色综合亚洲欧洲| 玖玖精品在线视频| 国产中文字幕在线播放| 国产成人精品1024| 国产欧美在线视频| 91久久国产综合久久91| 韩国精品一区二区三区| 日韩中文字幕在线视频播放| 成人免费av片| 给我免费播放日韩视频| 在线不卡中文字幕| 天天干天天干天天干天天干天天干| 大香伊人久久| **欧美大码日韩| 日韩一本精品| 欧美孕妇孕交xxⅹ孕妇交| 国产成人精品1024| 91免费视频国产| 亚洲av无码不卡| 一本久道久久综合狠狠爱| 欧美老少配视频| 99久久久无码国产精品不卡| 伊人成综合网yiren22| 亚洲第一在线视频| 久久久久亚洲av成人网人人软件| 激情不卡一区二区三区视频在线| 欧美色网站导航| 超碰影院在线观看| 久久人体大尺度| 精品久久久久久中文字幕| 男女猛烈激情xx00免费视频| 精精国产xxxx视频在线中文版| 专区另类欧美日韩| 亚洲图色在线| 日本不卡在线| 亚洲丝袜美腿综合| 综合视频在线观看| 日本在线视频网| 国产精品高清亚洲| 亚洲一区二区三区涩| av午夜在线| 国产精品久久久久久久久晋中| 亚洲精品乱码视频| 97电影在线看视频| 国产精品第一页第二页第三页| 天天人人精品| 麻豆av在线免费看| 亚洲色图.com| 蜜桃视频一区二区在线观看| 性欧美1819sex性高清大胸| 一区二区三区欧美| 丁香花在线影院观看在线播放| 波多野一区二区| 欧美性猛交视频| 亚洲精品高清无码视频| 精品69视频一区二区三区| 欧美日韩成人综合天天影院| 天天操精品视频| 1204国产成人精品视频| 亚洲国产成人精品久久| 亚洲第一成人网站| 欧美三级美国一级| 久久精品国产一区| 国产在线综合网| 噜噜噜躁狠狠躁狠狠精品视频| 国产精品91久久久久久| 91成品人影院| 成人综合婷婷国产精品久久蜜臀 | 亚洲一区二区视频在线观看| 欧美日韩在线一| 成人黄色视屏网站| 91精品蜜臀在线一区尤物| 中文字幕99页| 大色综合视频网站在线播放| 欧美成人免费小视频| 国产免费观看av| 免费成人av在线播放| 古典武侠综合av第一页| 女人偷人在线视频| 亚洲精品菠萝久久久久久久| 日本成年人网址| 96sao精品免费视频观看| 亚洲精品97久久| 国产大屁股喷水视频在线观看| 国产精品99免费看| 国产精品久久久久久久久久久久久久 | 欧美日韩亚洲一区在线观看| 国产99久久久欧美黑人| www夜片内射视频日韩精品成人| 久久先锋影音av鲁色资源| 咪咪色在线视频| 欧美大片1688| 精品欧美一区二区在线观看| 男人舔女人下部高潮全视频| 精久久久久久| 91精品国产综合久久男男 | 国产亚洲xxx| 国产精品99精品无码视| 九九精品视频在线看| 久久久婷婷一区二区三区不卡| 麻豆视频免费在线观看| 欧美在线观看视频一区二区三区| 亚洲一区和二区| 婷婷成人基地| 国产精品久久综合av爱欲tv| 婷婷丁香一区二区三区| 一区二区三区精品久久久| 在线观看免费成人av| 老牛国内精品亚洲成av人片| 欧美精品在线看| 国产乡下妇女三片| 久久久久久一级片| 国产中文字幕二区| 99re91这里只有精品| 久久精视频免费在线久久完整在线看| 亚洲色成人www永久网站| 成人精品视频一区二区三区尤物| 免费观看黄色大片| 色综合视频一区二区三区日韩 | 91久久国产综合久久蜜月精品| 国产小视频在线观看| 欧美色另类天堂2015| 美女黄色一级视频| 亚洲大片av| 国产精品视频免费一区| 欧美激情成人动漫| 日韩欧美国产一区二区三区 | 亚洲成人综合网站| 男男受被啪到高潮自述| 中文字幕亚洲综合久久五月天色无吗'' | 欧美裸体网站| 欧美7777| 国产亚洲人成a一在线v站| 天堂网中文字幕| 久久夜色精品国产噜噜av| 久久国产成人精品国产成人亚洲| 青草久久视频| 青青青国产精品一区二区| 免费看男男www网站入口在线| 色域天天综合网| 先锋影音av在线| 蜜芽一区二区三区| 婷婷视频在线播放| 精品国产亚洲一区二区在线观看 | 日韩一本精品| 亚洲我射av| 九九热视频这里只有精品| 亚洲精品久久久久久动漫器材一区 | 亚洲天堂黄色片| 岛国av在线一区| 欧美 日韩 国产在线观看| 久久不见久久见免费视频7| 国产成人午夜视频网址| 日韩专区在线| 日韩精品一区二| 粉嫩aⅴ一区二区三区| 久久免费美女视频| 国产精品久久久毛片| 亚洲欧美偷拍自拍| 国产精品一区视频网站| 日韩pacopacomama| 久久午夜a级毛片| 欧美视频在线观看一区二区三区| 欧美日韩免费观看中文| 一二三四在线观看视频| 国产91精品精华液一区二区三区 | 波多野结衣爱爱视频| 成人污污视频在线观看| 亚洲精品一二三四五区| 欧美 日韩 国产一区二区在线视频| 91原创国产| 玛雅亚洲电影| 粗暴蹂躏中文一区二区三区| 色wwwwww| 欧美精品一二三| 国产成人无码一区二区三区在线| 日本一区二区视频在线观看| 中文字幕一二三区| 天堂精品中文字幕在线| 国产午夜精品视频一区二区三区| 深爱激情久久| y111111国产精品久久婷婷| 色婷婷综合久久久中字幕精品久久| 久久精品电影网站| 免费a在线观看| 日韩欧美国产精品一区| 真实新婚偷拍xxxxx| 午夜影院在线观看欧美| 久草福利资源在线| 91蜜桃在线观看| 中文字幕avav| 蜜桃精品视频在线观看| 无码精品国产一区二区三区免费| 亚洲xxx拳头交| 欧美日韩另类丝袜其他| 99久久人爽人人添人人澡| 国产精品天天狠天天看| 欧美成人h版| 性欧美长视频免费观看不卡| av香蕉成人| 中文精品99久久国产香蕉| 日韩亚洲视频在线观看| 精品久久国产老人久久综合| 一区二区不卡视频在线观看| 色香色香欲天天天影视综合网| 久久亚洲av午夜福利精品一区| 国产精品免费av| 九色porny自拍视频| av在线综合网| 年下总裁被打光屁股sp| 国产一区二区三区四| 亚洲综合日韩欧美| 日本在线不卡一区| 黄色国产精品视频| 中文国产一区| 免费国产黄色网址| 亚洲先锋成人| avav在线播放| 国内综合精品午夜久久资源| 久久精品在线免费视频| 外国成人激情视频| 久久免费视频2| 99视频精品全部免费在线视频| 亚洲v国产v在线观看| 欧美综合在线视频观看| 欧美日韩精品免费看 | 日韩成人av网| 少妇性bbb搡bbb爽爽爽欧美| 日韩av在线不卡| 天堂中文在线8| 日韩精品在线观看一区| 免费一级在线观看播放网址| 亚洲色图五月天| 国产日本在线视频| 在线视频亚洲欧美| 免费网站黄在线观看| 日韩亚洲欧美成人| 成人午夜在线影视| 欧美—级高清免费播放| 成人超碰在线| 欧美洲成人男女午夜视频| 婷婷午夜社区一区| 国产精品偷伦免费视频观看的| 亚洲18在线| 91九色蝌蚪成人| 米奇精品关键词| 欧美一级爽aaaaa大片| 精品freesex老太交| 一本久道久久综合| 久久久久蜜桃| 久久国产精品视频在线观看| 久久中文精品| 亚洲黄色片免费看| 99久久国产综合色|国产精品| 91久久免费视频| 国产精品成人免费在线| 久视频在线观看| 日韩欧美a级成人黄色| 中文字幕 亚洲视频| 日韩一区二区视频| 性插视频在线观看| 色哟哟入口国产精品| 婷婷在线播放| 国产va免费精品高清在线观看| 久久91视频| 国产精品一 二 三| 日产精品一区二区| www.亚洲视频.com| 日本亚洲天堂网| 国产成人精品一区二区三区在线观看| 久久网站最新地址| 国产免费美女视频| 疯狂欧美牲乱大交777| 亚洲天堂999| 亚洲精品国产免费| 久草中文在线| 浅井舞香一区二区| 日韩精品中文字幕一区二区| 精品视频高清无人区区二区三区| 色999日韩| 成人综合视频在线| 国内精品久久久久影院薰衣草| 国产xxxxxxxxx| 综合精品久久久| 久久久久久久久黄色| 欧美刺激午夜性久久久久久久| 国产在线观看黄| 国语自产在线不卡| **欧美日韩在线| 欧美精品亚洲| 国内精品福利| 视频免费1区二区三区| 久久久噜噜噜久久人人看| 久久精品波多野结衣| 欧美日韩国产电影| 国产中文字幕在线播放| 91精品国产91久久久久久| 精品一区二区三区视频在线播放| 神马欧美一区二区| 亚洲精选一区| 绯色av蜜臀vs少妇| 亚洲欧美综合在线精品| 成年人晚上看的视频| 亚洲国产欧美自拍| 秋霞在线午夜| 成人在线视频网| 久久成人综合| 超碰在线人人爱| 国产欧美一二三区| av图片在线观看| 日韩av网站在线| 成人国产电影在线观看| 国产精品三区四区| 激情综合中文娱乐网| 天天干天天曰天天操| 中文字幕一区视频| 亚洲手机在线观看| 色99之美女主播在线视频| 深夜视频一区二区| 视频一区二区精品| 日本亚洲天堂网| 美国黑人一级大黄| 欧美在线观看你懂的| 丁香婷婷在线| 国产精品久久久久久久久久99| 精品久久电影| 嫩草av久久伊人妇女超级a| 欧美经典一区二区三区| 老熟妇一区二区三区啪啪| 深夜成人在线观看| 亚洲我射av| 丰满人妻一区二区三区53号| 国产高清精品网站| 劲爆欧美第一页| 亚洲成人免费网站| 免费观看一级欧美片| 欧美日韩综合精品| 日韩电影免费在线观看网站| 俄罗斯毛片基地| 欧美二区三区的天堂| 91精选在线| 国产精品区一区二区三在线播放| 亚洲欧洲一区二区天堂久久| 亚洲乱码国产乱码精品精大量| 欧美日韩免费网站| 春暖花开成人亚洲区| 成人www视频在线观看| 欧美aⅴ99久久黑人专区| 污污免费在线观看| 欧美丝袜美女中出在线| av资源种子在线观看| 成人午夜在线观看| 一区二区三区导航| 微拍福利一区二区| 91麻豆精品久久久久蜜臀| 青青在线视频| 日本免费一区二区三区| 国产在线精品一区二区不卡了| 久久久久久久久久91| 亚洲女人被黑人巨大进入| 色999韩欧美国产综合俺来也| 777久久精品一区二区三区无码| 99国产麻豆精品| 亚洲专区第一页| 国内精品久久久| 久久国产小视频| 日本不卡视频一区| 在线观看日韩毛片| 色婷婷av在线| 日韩动漫在线观看| 国产精品白丝jk黑袜喷水| 国产黄色免费观看| 欧美成人小视频| 精品国产一区探花在线观看| 美女流白浆视频| 欧美图片一区二区三区| 草草视频在线|