多partition下無法保障訊息的順序性

2021-10-05 06:32:59 字數 1436 閱讀 2642

由於問題比較寬泛,需要針對不同場景來分析,以下所有的分析都是基於同乙個partition下的場景細化,多partition下無法保障訊息的順序性,但是碰到如下場景還是需要調整引數。

場景一:設定了retries>0,並且max.in.flight.requests.per.connection>1

先說明下這兩個引數的含義:

retries

生產者從伺服器收到的錯誤有可能是臨時性的錯誤(比如分割槽找不到首領)。在這種情況下,retries 引數的值決定了生產者可以重發訊息的次數,如果達到這個次數,生產者會放棄重試並返回錯誤。

預設情況下,生產者會在每次重試之間等待 100ms,不過可以通過 retry.backoff.ms 引數來改變這個時間間隔。建議在設定重試次數和重試時間間隔之前,先測試一下恢復乙個崩潰節點需要多少時間(比如所有分割槽選舉出首領需要多長時間),讓總的重試時間比 kafka 集群從崩潰中恢復的時間長,否則生產者會過早地放棄重試。不過有些錯誤不是臨時性錯誤,沒辦法通過重試來解決(比如「訊息太大」錯誤)。

該引數指定了生產者在收到伺服器響應之前可以傳送多少個訊息。它的值越高,就會占用越多的記憶體,不過也會提公升吞吐量。把它設為 1 可以保證訊息是按照傳送的順序寫入伺服器的,即使發生了重試。

這種場景下無法保障單一partition的有序,一般來說要保障訊息的有序性,對於訊息的可靠性也是有要求的,所以一般retries可以設定為大於0,但是max.in.flight.requests.per.connection設定為1即可,不過這樣就有乙個問題,導致了訊息的吞吐量大大降低。

再發散一下,max.in.flight.requests.per.connection保障訊息有序的邏輯原始碼時如何實現的呢?

在生產者訊息傳送執行緒sender裡面sendproducerdata方法,裡面有關於保障訊息有序的一段邏輯如下:

//如果需要保證訊息的強順序性,則快取對應 topic 分割槽物件,防止同一時間往同乙個 topic 分割槽傳送多條處於未完成狀態的訊息

if (guaranteemessageorder)

}

實際上就是將本批次訊息所在的分割槽資訊新增到乙個集合中,以保障每個topic下的該分割槽只有乙個批次傳送,如下:

public void mutepartition(topicpartition tp)
場景二:需要提公升吞吐量max.in.flight.requests.per.connection設定大於1

此場景下業務要保障訊息的吞吐量,那麼max.in.flight.requests.per.connection必然就會選擇更大的乙個閾值,但是此場景還能保障訊息有序性嗎?

答案是肯定的,可以設定enable.idempotence=true,開啟生產者的冪等生產,可以解決順序性問題,並且允許max.in.flight.requests.per.connection設定大於1

業務高可用的保障 異地多活架構

一 什麼是異地多活?異地多活 異地指不同地理位置,多活指不同地理位置的系統都是活躍的,都能夠提供業務服務。異地多活是為了解決極端場景下所有伺服器都出現故障時業務不受影響,或者業務在幾分鐘內就能夠快速恢復而設計的。異地多活的優點 功能強大 提供更好的體驗 可以減少業務中斷帶來的損失 異地多活的缺點 代...

業務高可用的保障 異地多活架構

1 引言 高可用計算架構還是高可用儲存架構,其目的都是為了解決部分伺服器故障的場景下,如何保證系統能夠繼續提供服務。但也存在一些極端的情況,導致所有或大部分伺服器出現故障,如斷電 自然災害等,業務也就會受到不同層次的影響,因此,需要設計異地多活架構。2 應用場景 異地多活架構的關鍵點就是異地 多活,...

快排光芒下被忽視的Partition函式

看到這篇標題,沒有學過快排的人自然是不知道partition函式的意思和作用,這裡附上學習的連線 lantian的快排總結 我們現在都是被快排蒙蔽了雙眼,沒有意識到快最核心的劃分函式partition,當然partition函式也就不止於快排這裡,本文就從多方面來為展示partition函式的本質和...