国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

kafka常見問(wèn)題QA(六)

這篇具有很好參考價(jià)值的文章主要介紹了kafka常見問(wèn)題QA(六)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

六、常見問(wèn)題QA

6.1 無(wú)消息丟失如何配置

producer

  1. 調(diào)用方式

    (1)網(wǎng)絡(luò)抖動(dòng)導(dǎo)致消息丟失,Producer 端可以進(jìn)行重試。

    (2)消息大小不合格,可以進(jìn)行適當(dāng)調(diào)整,符合 Broker 承受范圍再發(fā)送。

    不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。記住,一定要使用帶有回調(diào)通知的 send 方法。在剖析 Producer 端丟失場(chǎng)景的時(shí)候, 我們得出其是通過(guò)「異步」方式進(jìn)行發(fā)送的,所以如果此時(shí)是使用「發(fā)后即焚」的方式發(fā)送,即調(diào)用 Producer.send(msg) 會(huì)立即返回,由于沒有回調(diào),可能因網(wǎng)絡(luò)原因?qū)е?Broker 并沒有收到消息,此時(shí)就丟失了。

  2. ACK 確認(rèn)機(jī)制

    request.required.acks 設(shè)置為 -1/ all。acks 是 Producer 的一個(gè)參數(shù),代表了你對(duì)“已提交”消息的定義。如果設(shè)置成 all,則表明所有副本 Broker 都要接收到消息,該消息才算是“已提交”。這是最高等級(jí)的“已提交”定義。

  3. 重試次數(shù) retries

    設(shè)置 retries 為一個(gè)較大的值。這里的 retries 同樣是 Producer 的參數(shù),對(duì)應(yīng)前面提到的 Producer 自動(dòng)重試。當(dāng)出現(xiàn)網(wǎng)絡(luò)的瞬時(shí)抖動(dòng)時(shí),消息發(fā)送可能會(huì)失敗,此時(shí)配置了 retries > 0 的 Producer 能夠自動(dòng)重試消息發(fā)送,避免消息丟失。

  4. 重試時(shí)間 retry.backoff.ms

    發(fā)送超時(shí)的時(shí)候兩次發(fā)送的間隔,避免太過(guò)頻繁重試,默認(rèn)值為100ms, 推薦設(shè)置為300ms

  5. 啟用冪等傳遞的方法配置

    enable.idempotence = true

consumer

  1. **確保消息消費(fèi)完成再提交。Consumer 端有個(gè)參數(shù) enable.auto.commit,最好把它設(shè)置成 false,并采用手動(dòng)提交位移的方式。**就像前面說(shuō)的,這對(duì)于單 Consumer 多線程處理的場(chǎng)景而言是至關(guān)重要的。

broker配置

  1. 設(shè)置 unclean.leader.election.enable = false。它控制的是哪些 Broker 有資格競(jìng)選分區(qū)的 Leader。如果一個(gè) Broker 落后原先的 Leader 太多,那么它一旦成為新的 Leader,必然會(huì)造成消息的丟失。故一般都要將該參數(shù)設(shè)置成 false,即不允許這種情況的發(fā)生。

  2. 設(shè)置 replication.factor >= 3。該參數(shù)表示分區(qū)副本的個(gè)數(shù)。建議設(shè)置 replication.factor >=3, 這樣如果 Leader 副本異常 Crash 掉,F(xiàn)ollower 副本會(huì)被選舉為新的 Leader 副本繼續(xù)提供服務(wù)。

  3. ISR配置>1, 即設(shè)置參數(shù) min.insync.replicas > 1。這依然是 Broker 端參數(shù),控制的是消息至少要被寫入到多少個(gè)副本才算是“已提交”。設(shè)置成大于 1 可以提升消息持久性。在實(shí)際環(huán)境中千萬(wàn)不要使用默認(rèn)值 1。

    我們還需要確保一下 replication.factor > min.insync.replicas, 如果相等,只要有一個(gè)副本異常 Crash 掉,整個(gè)分區(qū)就無(wú)法正常工作了,因此推薦設(shè)置成: replication.factor = min.insync.replicas +1, 最大限度保證系統(tǒng)可用性。

  4. 確保 replication.factor > min.insync.replicas。如果兩者相等,那么只要有一個(gè)副本掛機(jī),整個(gè)分區(qū)就無(wú)法正常工作了。我們不僅要改善消息的持久性,防止數(shù)據(jù)丟失,還要在不降低可用性的基礎(chǔ)上完成。推薦設(shè)置成 replication.factor = min.insync.replicas + 1。

6.2 producer在接收到ack后會(huì)刷盤嗎?有可能丟消息嗎?

producer在接收到broker的ack后不會(huì)刷盤,有可能丟消息。

  1. ack=all或-1,配置成所有ISR同步后才會(huì)返回ack,保證broker中有多個(gè)副本中都存有這條消息,即使leader掛了,也不會(huì)丟消息。
  2. 通過(guò)配置ISR>1, 至少還有一個(gè)以上的副本保存了消息。

kafka 通過(guò)「多 Partition (分區(qū))多 Replica(副本)機(jī)制」已經(jīng)可以最大限度的保證數(shù)據(jù)不丟失,如果數(shù)據(jù)已經(jīng)寫入 PageCache 中但是還沒來(lái)得及刷寫到磁盤,此時(shí)如果所在 Broker 突然宕機(jī)掛掉或者停電,極端情況還是會(huì)造成數(shù)據(jù)丟失。

更多配置見上面。

6.3 如何保證消息的順序存儲(chǔ)
  1. 全局有序只能讓一個(gè)Topic只有一個(gè)Partition??梢酝ㄟ^(guò)生產(chǎn)者在寫消息的時(shí)候指定一個(gè)key,通過(guò)partitionKey將某類消息寫入同一個(gè)Partition中。
  2. Kafka通過(guò)引入生產(chǎn)者的冪等性來(lái)解決重傳機(jī)制引起的消息亂序。每一個(gè)新的生產(chǎn)者在初始化的時(shí)候會(huì)生成一個(gè)Producer ID,即PID。對(duì)于每一個(gè)PID,該P(yáng)roducer發(fā)送消息的每個(gè)<Topic,Partition> 都對(duì)應(yīng)一個(gè)單調(diào)遞增的Sequence Number。broker端會(huì)緩存這個(gè)序號(hào)。每收到一條消息,判斷該消息的序號(hào)是否比緩存的序號(hào)大1,是則接收,不是則丟棄。
6.4 順序消費(fèi)
  1. Kafka 只保證單Partition有序,而不保證主題中不同分區(qū)的順序。每個(gè) partition 分區(qū)按照key值排序足以滿足大多數(shù)應(yīng)用程序的需求。但如果你需要總記錄在所有記錄的上面,可使用僅有一個(gè)分區(qū)的主題來(lái)實(shí)現(xiàn),這意味著每個(gè)消費(fèi)者組只有一個(gè)消費(fèi)者進(jìn)程。
  2. 使用Kafka key+offset做到業(yè)務(wù)有序,后根據(jù)key+offset存儲(chǔ)到時(shí)序數(shù)據(jù)庫(kù)或ES中。 key區(qū)分相同的業(yè)務(wù),offset區(qū)分前后進(jìn)入的順序。使用場(chǎng)景比如用戶畫像分析,用戶id做key,用戶的操作先后根據(jù)offset排序,后對(duì)用戶的行為進(jìn)行分析。
6.5 消息優(yōu)先級(jí)

實(shí)際上,這個(gè)需求也在Kafka的官方需求中(KIP-349: Priorities for Source Topics),目前的狀態(tài)是Under Vote,這個(gè)Proposal是2019年提出來(lái)的,看來(lái)官方的方案是指望不上了,只能找些第三方的輪子,或者自己來(lái)實(shí)現(xiàn)。

在每個(gè)Topic中,Kafka順序?qū)懸垣@得盡可能獲得高吞吐,使用Index文件來(lái)維護(hù)Consumer的消息拉取,維護(hù)維度是Offset。Offset不包含優(yōu)先級(jí)語(yǔ)義,但需要順序語(yǔ)義,優(yōu)先級(jí)語(yǔ)義本身包含非順序語(yǔ)義,因此就語(yǔ)義來(lái)看,以O(shè)ffset為維度的拉模型MQ和優(yōu)先級(jí)需求本質(zhì)是沖突的。所以對(duì)于單個(gè)Topic,在Kafka原生實(shí)現(xiàn)消息優(yōu)先級(jí)可行性不高。
因此很自然的,我們能夠想到,可以創(chuàng)建多個(gè)Topic,每個(gè)Topic代表一個(gè)優(yōu)先級(jí)。

在生產(chǎn)者端,引入優(yōu)先級(jí)字段,以數(shù)字來(lái)表示,數(shù)值越高優(yōu)先級(jí)越高。在向broker推消息時(shí),根據(jù)其優(yōu)先級(jí)推送到不同的topic中。
在消費(fèi)者端,通過(guò)實(shí)現(xiàn)對(duì)不同優(yōu)先級(jí)Topic的消費(fèi),以實(shí)現(xiàn)消息的優(yōu)先消費(fèi)。
對(duì)于消息的生產(chǎn),實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,問(wèn)題的難點(diǎn)在于消費(fèi)者端如何消費(fèi)不同Topic的消息,以實(shí)現(xiàn)高優(yōu)先級(jí)的消息能夠被優(yōu)先處理?

這里大致有三種方案

  1. 對(duì)于不同的topic,各個(gè)consumer分別拉取,拉去后在服務(wù)內(nèi)部使用優(yōu)先隊(duì)列進(jìn)行緩沖。

    為了避免OOM,需要使用有界優(yōu)先隊(duì)列。然而對(duì)于有界優(yōu)先隊(duì)列,在消息消費(fèi)邏輯復(fù)雜,處理速度不夠快時(shí),可能會(huì)導(dǎo)致優(yōu)先隊(duì)列的阻塞。這里一個(gè)可能的做法是不在服務(wù)內(nèi)部的優(yōu)先隊(duì)列中維護(hù),而是將消息再放到Redis Zset中進(jìn)行排序。這樣會(huì)避免OOM和阻塞的問(wèn)題,但是會(huì)增加系統(tǒng)的復(fù)雜度。

  2. 使用一個(gè)consumer,優(yōu)先拉取高優(yōu)先級(jí)消息,沒有的話再拉去次優(yōu)先級(jí)消息。

    每次都要串行的判斷各個(gè)優(yōu)先級(jí)數(shù)據(jù)是否存在,實(shí)際的場(chǎng)景中往往是高優(yōu)消息時(shí)比較少的,每次輪詢到較低優(yōu)先級(jí)才拉取到消息,一個(gè)consumer在性能上可能存在問(wèn)題。

  3. 權(quán)重消費(fèi)。使用不同的consumer分別拉取各個(gè)topic,但是拉取的消息數(shù)量不同,對(duì)于高優(yōu)先級(jí)的消息,拉取的“配額”更多。

    有一個(gè)開源的實(shí)現(xiàn)flipkart-incubator/priority-kafka-client。對(duì)于每次拉取的數(shù)量,按照優(yōu)先級(jí)的“權(quán)重”不同,分配到不同的topic上。默認(rèn)的分配策略是按照指數(shù)分配。

  4. 桶優(yōu)先級(jí)消費(fèi)。開源實(shí)現(xiàn):prioritization-kafka

權(quán)重消費(fèi)

同時(shí)拉取多Topic,“權(quán)重”不同

對(duì)于每次拉取的數(shù)量,按照優(yōu)先級(jí)的“權(quán)重”不同,分配到不同的topic上。默認(rèn)的分配策略是按照指數(shù)分配。

比如對(duì)于每次拉取50個(gè)記錄,3個(gè)優(yōu)先級(jí)的情況下,三個(gè)優(yōu)先級(jí)的比例按指數(shù)分布,為1:2:4,實(shí)際的配額即為7:14:29。
這里有一個(gè)很明顯的問(wèn)題是對(duì)于高優(yōu)先級(jí)的數(shù)據(jù),如果每次拉取不到指定的數(shù)量,這部分配額相當(dāng)于被浪費(fèi)掉了,這樣會(huì)影響整體的拉取性能。

對(duì)于這種情況,代碼中為每個(gè)優(yōu)先級(jí)維護(hù)了一個(gè)“滑動(dòng)窗口”來(lái)記錄近期拉取的數(shù)量的歷史記錄,在拉取前,會(huì)根據(jù)歷史拉取情況來(lái)進(jìn)行配額的rebalance,以此來(lái)實(shí)現(xiàn)配額的動(dòng)態(tài)分配。

kafka常見問(wèn)題QA(六)

桶優(yōu)先級(jí)實(shí)現(xiàn)

自定義一個(gè)Partitioner:BucketPriorityPartitioner, 優(yōu)先級(jí)高的有更多數(shù)量的Partition, 消費(fèi)的時(shí)候,更多的消費(fèi)者去消費(fèi)。這種模式允許消費(fèi)者在給定時(shí)間內(nèi)消費(fèi)所有優(yōu)先級(jí)消息。只有給定優(yōu)先級(jí)的消費(fèi)者數(shù)量會(huì)發(fā)生變化。

在設(shè)定優(yōu)先級(jí)時(shí),可以設(shè)置不同的topic比例

configs.setProperty(BucketPriorityConfig.BUCKETS_CONFIG, "Platinum, Gold");
configs.setProperty(BucketPriorityConfig.ALLOCATION_CONFIG, "70%, 30%");

kafka常見問(wèn)題QA(六)

6.6 kafka為什么不支持主從讀寫

主從的模式帶來(lái)的數(shù)據(jù)延遲,從節(jié)點(diǎn)總是會(huì)落后主節(jié)點(diǎn)ms級(jí)別,甚至s級(jí)別。但是在kafka除了用做削峰,異步的中間件外,它還是流式處理中間件,比如Flink,Spark,Spark的實(shí)時(shí)性要求不高,它是一批一批處理,減少批次間的間隔來(lái)完成假的實(shí)時(shí)功能;但Flink對(duì)實(shí)時(shí)性要求比較高。在實(shí)時(shí)性要求高的場(chǎng)景下,如果出現(xiàn)秒級(jí)甚至由于網(wǎng)絡(luò)的原因,出現(xiàn)了分區(qū)級(jí)別的延遲,這是不能接受的。

自Kafka 2.4版本開始,社區(qū)通過(guò)引入新的Broker端參數(shù),允許Follower副本有限度地提供讀服務(wù)。

6.7 數(shù)據(jù)積壓,如何提高吞吐量

broker端

  1. 動(dòng)態(tài)調(diào)整Broker參數(shù),調(diào)整Broker端各種線程池大小。增加網(wǎng)絡(luò)線程數(shù)和I/O線程數(shù),快速消耗一些積壓。當(dāng)突發(fā)流量過(guò)去后,我們也能將線程數(shù)調(diào)整回來(lái),減少對(duì)資源的浪費(fèi)。整個(gè)過(guò)程都不需要重啟Broker。你甚至可以將這套調(diào)整線程數(shù)的動(dòng)作,封裝進(jìn)定時(shí)任務(wù)中,以實(shí)現(xiàn)自動(dòng)擴(kuò)縮容。
  2. 考慮增長(zhǎng)partition數(shù)據(jù)

消費(fèi)者

  1. 如果是kafka的消費(fèi)能力不足,則可以考慮增加topic的分區(qū)數(shù),并且同時(shí)提升消費(fèi)組的消費(fèi)者數(shù)量,消費(fèi)者數(shù)=分區(qū)數(shù),兩者缺一不可
  2. 如果是下游的數(shù)據(jù)處理不及時(shí),提高每批次拉取的數(shù)量。 批次拉取數(shù)量過(guò)少(拉取數(shù)據(jù)/處理時(shí)間 < 生產(chǎn)速度),使處理的數(shù)據(jù)小于生產(chǎn)的數(shù)據(jù),也會(huì)造成數(shù)據(jù)積壓
6.8 消息默認(rèn)保存多久

默認(rèn)保存7天。kafka支持消息持久化,消費(fèi)端為拉模型來(lái)拉取數(shù)據(jù),消費(fèi)狀態(tài)和訂閱關(guān)系有客戶端負(fù)責(zé)維護(hù),消息消費(fèi)完后,不會(huì)立即刪除,會(huì)保留歷史消息。因此支持多訂閱時(shí),消息只會(huì)存儲(chǔ)一份就可以了。

6.9 哪些情況會(huì)落后于leader?
  • 副本是新加入的,直到它同步與leader一致才能加入ISR
  • 副本卡死,副本機(jī)器死亡或GC卡死
  • 副本同步因?yàn)榫W(wǎng)絡(luò)或其它原因?qū)е卵舆t
6.10 怎么判斷副本落后?

replica.lag.time.max.ms參數(shù):如果副本落后超過(guò)這個(gè)時(shí)間就判定為落后了,直到它回來(lái)。消息復(fù)制分為異步和同步,ISR是動(dòng)態(tài)的,有進(jìn)有出。

6.11 哪些情況consumer會(huì)發(fā)生再均衡的情形呢?
  1. 同一組中消費(fèi)者數(shù)量發(fā)生變化
  2. 主題的分區(qū)數(shù)發(fā)生變化,加減分區(qū)
  3. 組協(xié)調(diào)者節(jié)點(diǎn)下線
6.12 in-memory cache 和 in-process cache

in-memory cache(內(nèi)存緩存)是位于應(yīng)用程序和數(shù)據(jù)庫(kù)之間的數(shù)據(jù)存儲(chǔ)層,通過(guò)存儲(chǔ)來(lái)自早期請(qǐng)求的數(shù)據(jù)或直接從數(shù)據(jù)庫(kù)復(fù)制的數(shù)據(jù)來(lái)高速傳遞響應(yīng)。當(dāng)構(gòu)建在基于磁盤的數(shù)據(jù)庫(kù)上的應(yīng)用程序必須在處理之前從磁盤檢索數(shù)據(jù)時(shí),內(nèi)存中的緩存可以消除性能延遲。從內(nèi)存讀取數(shù)據(jù)比從磁盤讀取數(shù)據(jù)快。內(nèi)存緩存避免了延遲,提高了在線應(yīng)用程序的性能。

in-process cache(進(jìn)程內(nèi)緩存)是在與應(yīng)用程序相同的地址空間中構(gòu)建的對(duì)象緩存,在使用進(jìn)程內(nèi)緩存時(shí),緩存元素只存在于應(yīng)用程序的單個(gè)實(shí)例中。谷歌Guava庫(kù)提供了一個(gè)簡(jiǎn)單的進(jìn)程內(nèi)緩存API,這就是一個(gè)很好的例子。另一方面,分布式緩存位于應(yīng)用程序外部,很可能部署在多個(gè)節(jié)點(diǎn)上,形成一個(gè)大型邏輯緩存。Memcached是一種流行的分布式緩存。來(lái)自Terracotta的Ehcache是一款可以配置為任意一種功能的產(chǎn)品。

6.13 一個(gè)Partition就是一個(gè)queue嗎?

和java中的queue沒有關(guān)系,一個(gè)Partition是由一個(gè)或多個(gè)segment文件組成。

6.14 新增一個(gè)consumer是會(huì)發(fā)生什么?

What happens when a new consumer joins the group in Kafka?

6.15 一個(gè)消費(fèi)者可以訂閱和消費(fèi)多個(gè)topic?

消費(fèi)者組中的2個(gè)或多個(gè)消費(fèi)者可以訂閱不同的topic。同一個(gè)topic下的某一個(gè)分區(qū)只能被某個(gè)組中的同一個(gè)消費(fèi)者所消費(fèi)。

6.17 什么是事件流(event streaming)?

event streaming 是一個(gè)動(dòng)態(tài)的概念,它描述了一個(gè)個(gè) event ( “something happened” in the world ) 在不同主體間連續(xù)地、正確地流動(dòng)的狀態(tài)(state)。event source 產(chǎn)生 event,event source 可以是數(shù)據(jù)庫(kù)、傳感器、移動(dòng)設(shè)備、應(yīng)用程序,等等。

kafka常見問(wèn)題QA(六)

event source 產(chǎn)生 event,event source 可以是數(shù)據(jù)庫(kù)、傳感器、移動(dòng)設(shè)備、應(yīng)用程序,等等。
event broker 持久化 event,以備 event sink 可以隨時(shí)獲取它們。
event sink 實(shí)時(shí)或回顧性地從 broker 中獲取 event 進(jìn)行處理。

producer 發(fā)布 event,broker 持久化 even,consumer 訂閱 event。

事件流應(yīng)用場(chǎng)景

我們可以在很多的應(yīng)用場(chǎng)景中找到 event streaming 的身影,例如:
實(shí)時(shí)處理支付、金融交易、客戶訂單等等;
實(shí)時(shí)跟蹤和監(jiān)控物流進(jìn)度;
持續(xù)捕獲和分析來(lái)自物聯(lián)網(wǎng)設(shè)備或其他設(shè)備的傳感器數(shù)據(jù);
不同數(shù)據(jù)源的數(shù)據(jù)連接;
作為數(shù)據(jù)平臺(tái)、事件驅(qū)動(dòng)架構(gòu)和微服務(wù)等的技術(shù)基礎(chǔ);

我們來(lái)看一段英文What is Event Streaming?的關(guān)于事件流的解釋

An event is defined as a change in state such as a transaction or a prospect navigating to your website. Businesses want to be able to react to these crucial business moments in real time.

Event-processing programs aggregate information from distributed systems in real time, applying rules that reveal key patterns, relationships or trends. An “event stream” is a sequence of business events ordered by time. With event stream processing you connect to all data sources and normalize, enrich and filter the data.

Event streaming platforms process the inbound data while it is in flight, as it streams through the server. It performs ultra-fast, continuous computations against high-speed streaming data, and uses a continuous query engine that drives real time alerts and actions as well as live, user-configured visualizations.

kafka常見問(wèn)題QA(六)

事件流是一個(gè)或多個(gè)狀態(tài)的改變,它具有實(shí)時(shí)性,它的來(lái)源多種多樣,可以是事務(wù)記錄、IOT數(shù)據(jù)、業(yè)務(wù)和操作的metrics等,而這些數(shù)據(jù)來(lái)源,即事件具有一系列的連續(xù)性。

6.18 直接io和裸io區(qū)別

直接io是經(jīng)過(guò)文件系統(tǒng)但不經(jīng)過(guò)page cache,直接io的一個(gè)比較常見的用法就是在備份文件的時(shí)候會(huì)用直接io,這樣它不會(huì)污染文件系統(tǒng)的cache,造成緩存命中率的下降。

裸io是繞過(guò)了文件系統(tǒng)直接操作磁盤,數(shù)據(jù)庫(kù)實(shí)際上就是裸io ,因?yàn)樗恍枰?jīng)過(guò)文件系統(tǒng)的cache那一層,也不需要經(jīng)過(guò)文件系統(tǒng)傳遞,它能夠自己去保存這種讀取到的內(nèi)存資源。

裸io指direct io。有兩種繞過(guò)文件系統(tǒng)的方法: 1、禁止掉文件系統(tǒng)的io緩存。這種做法實(shí)際上不是繞過(guò)文件系統(tǒng),而是不采納文件系統(tǒng)的io緩存算法。因?yàn)閿?shù)據(jù)庫(kù)可能自己有自己的緩存算法,如果文件系統(tǒng)也有緩存,就比較累贅,浪費(fèi)了寶貴的內(nèi)存空間,同樣的內(nèi)存空間給數(shù)據(jù)庫(kù)擴(kuò)大緩存空間更好。 2、直接裸寫磁盤分區(qū)。這時(shí)不存在文件系統(tǒng),也就是說(shuō)磁盤分區(qū)不需要格式化。這種做法在對(duì)象存儲(chǔ)系統(tǒng)中用得更多一點(diǎn),在數(shù)據(jù)庫(kù)中用得不多。

6.19 follower如何同步leader? 如何保證數(shù)據(jù)強(qiáng)一致性?

Kafka中partition replication之間同步數(shù)據(jù),從partition的leader復(fù)制數(shù)據(jù)到follower只需要一個(gè)線程(ReplicaFetcherThread),實(shí)際上復(fù)制是follower(一個(gè)follower相當(dāng)于consumer)主動(dòng)從leader批量拉取消息的。Kafka中每個(gè)Broker啟動(dòng)時(shí)都會(huì)創(chuàng)建一個(gè)副本管理服務(wù)(ReplicaManager),該服務(wù)負(fù)責(zé)維護(hù)ReplicaFetcherThread與其他Broker鏈路連接關(guān)系,該Broker中存在多少Follower的partitions,就會(huì)創(chuàng)建相同數(shù)量的ReplicaFetcherThread線程同步對(duì)應(yīng)partition數(shù)據(jù),Kafka中partition間復(fù)制數(shù)據(jù)是由follower(扮演consumer角色)主動(dòng)向leader獲取消息,follower每次讀取消息都會(huì)更新HW狀態(tài)。

當(dāng)Producer發(fā)送消息到leader partition所在Broker時(shí),首先保證leader commit消息成功,然后創(chuàng)建一個(gè)“生產(chǎn)者延遲請(qǐng)求任務(wù)”,并判斷當(dāng)前partiton的HW是否大于等于logEndOffset,如果滿足條件即表示本次Producer請(qǐng)求partition replicas之間數(shù)據(jù)已經(jīng)一致,立即向Producer返回Ack。否則待Follower批量拉取Leader的partition消息時(shí),同時(shí)更新Leader ISR中HW,然后檢查是否滿足上述條件,如果滿足向Producer返回Ack。

6.20 堆外內(nèi)存

kafka并沒有直接使用堆外內(nèi)存,但由于kafka的網(wǎng)絡(luò)IO使用了java的nio中的DirectMemory的方式,而這個(gè)申請(qǐng)的是堆外內(nèi)存。在對(duì)于HeapByteBuffer進(jìn)行讀寫操作時(shí),需要開辟堆外內(nèi)存空間作為中間數(shù)據(jù)交換的空間。而這部分堆外內(nèi)存并非由Kafka直接申請(qǐng),而是由JVM申請(qǐng)。

如果在jvm參數(shù)里,-XX:MaxDirectMemorySize參數(shù)配置的過(guò)小,kafka可能會(huì)出現(xiàn)java.lang.OutOfMemoryError: Direct buffer memory的錯(cuò)誤。

6.21 Kafka判斷一個(gè)節(jié)點(diǎn)是否活著有兩個(gè)條件
  1. 節(jié)點(diǎn)必須可以維護(hù)和ZooKeeper的連接,Zookeeper通過(guò)心跳機(jī)制檢查每個(gè)節(jié)點(diǎn)的連接。
  2. 如果節(jié)點(diǎn)是個(gè)follower,他必須能及時(shí)的同步leader的寫操作,延時(shí)不能太久。

符合以上條件的節(jié)點(diǎn)準(zhǔn)確的說(shuō)應(yīng)該是“同步中的(in sync)”,而不是模糊的說(shuō)是“活著的”或是“失敗的”。Leader會(huì)追蹤所有“同步中”的節(jié)點(diǎn),一旦一個(gè)down掉了,或是卡住了,或是延時(shí)太久,leader就會(huì)把它移除。至于延時(shí)多久算是“太久”,是由參數(shù)replica.lag.max.messages決定的,怎樣算是卡住了,怎是由參數(shù)replica.lag.time.max.ms決定的。

6.22 Kafa consumer是否可以消費(fèi)指定分區(qū)消息?

在某些業(yè)務(wù)場(chǎng)景下,比如上游生產(chǎn)者希望通過(guò)分區(qū)將不同類型的業(yè)務(wù)數(shù)據(jù)發(fā)送到不同的分區(qū),而對(duì)下游的消費(fèi)者來(lái)說(shuō),就需要從指定的分區(qū)消費(fèi)數(shù)據(jù);或者在另一種業(yè)務(wù)情況下,消費(fèi)者希望能夠順序消費(fèi),那么就可以通過(guò)生產(chǎn)端將消息發(fā)送到指定的分區(qū)下即可;

6.23 Kafka存儲(chǔ)在硬盤上的消息格式是什么?

Segment由log、index、timeindex三個(gè)文件組成,index和timeindex分別是一些索引信息。

消息由一個(gè)固定長(zhǎng)度的頭部和可變長(zhǎng)度的字節(jié)數(shù)組組成。頭部包含了一個(gè)版本號(hào)、CRC32校驗(yàn)碼、消息長(zhǎng)度、具體的消息。

6.24 Kafka創(chuàng)建Topic時(shí)如何將分區(qū)放置到不同的Broker中

實(shí)現(xiàn)類AdminUtils

  1. 副本因?不能?于 Broker的個(gè)數(shù);
  2. 第?個(gè)分區(qū)(編號(hào)為 0 )的第?個(gè)副本放置位置是隨機(jī)從 brokerList 選擇的;
  3. 其他分區(qū)的第?個(gè)副本放置位置相對(duì)于第 0 個(gè)分區(qū)依次往后移。也就是如果我們有 5 個(gè)Broker, 5個(gè)分區(qū),假設(shè)第?個(gè)分區(qū)放在第四個(gè) Broker 上,那么第?個(gè)分區(qū)將會(huì)放在第五個(gè) Broker 上;第三個(gè)分區(qū)將會(huì)放在第?個(gè) Broker 上;第四個(gè)分區(qū)將會(huì)放在第?個(gè)Broker 上,依次類推;
  4. 剩余的副本相對(duì)于第?個(gè)副本放置位置其實(shí)是由 nextReplicaShift 決定的,? 這個(gè)數(shù)也是隨機(jī)產(chǎn)?的
6.25 Kafka新建的分區(qū)會(huì)在哪個(gè)目錄下創(chuàng)建

配置好 log.dirs 參數(shù),其值是 Kafka 數(shù)據(jù)的存放目錄。

Kafka 會(huì)在含有分區(qū)目錄最少的文件夾中創(chuàng)建新的分區(qū)目錄,分區(qū)目錄名為 Topic名+分區(qū) ID。注意,是分區(qū)文件夾總數(shù)最少的目錄,而不是磁盤使用量最少的目錄!也就是說(shuō),如果你給 log.dirs 參數(shù)新增了一個(gè)新的磁盤,新的分區(qū)目錄肯定是先在這個(gè)新的磁盤上創(chuàng)建直到這個(gè)新的磁盤目錄擁有的分區(qū)目錄不是最少為止。

6.26 Kafka再平衡機(jī)制

所謂的再平衡,指的是在kafka consumer所訂閱的topic發(fā)生變化時(shí)發(fā)生的一種分區(qū)重分配機(jī)制。一般有三種情況會(huì)觸發(fā)再平衡:

  • consumer group中的新增或刪除某個(gè)consumer,導(dǎo)致其所消費(fèi)的分區(qū)需要分配到組內(nèi)其他的consumer上;
  • consumer訂閱的topic發(fā)生變化,比如訂閱的topic采用的是正則表達(dá)式的形式,如test-*此時(shí)如果有一個(gè)新建了一個(gè)topic test-user,那么這個(gè)topic的所有分區(qū)也是會(huì)自動(dòng)分配給當(dāng)前的consumer的,此時(shí)就會(huì)發(fā)生再平衡;
  • consumer所訂閱的topic發(fā)生了新增分區(qū)的行為,那么新增的分區(qū)就會(huì)分配給當(dāng)前的consumer,此時(shí)就會(huì)觸發(fā)再平衡。

Kafka提供的再平衡策略主要有三種:Round Robin,RangeSticky,默認(rèn)使用的是Range。這三種分配策略的主要區(qū)別在于:

  • Round Robin:會(huì)采用輪詢的方式將當(dāng)前所有的分區(qū)依次分配給所有的consumer;

  • Range:首先會(huì)計(jì)算每個(gè)consumer可以消費(fèi)的分區(qū)個(gè)數(shù),然后按照順序?qū)⒅付▊€(gè)數(shù)范圍的分區(qū)分配給各個(gè)consumer;

  • Sticky:這種分區(qū)策略是最新版本中新增的一種策略,其主要實(shí)現(xiàn)了兩個(gè)目的:

    • 將現(xiàn)有的分區(qū)盡可能均衡的分配給各個(gè)consumer,存在此目的的原因在于Round RobinRange分配策略實(shí)際上都會(huì)導(dǎo)致某幾個(gè)consumer承載過(guò)多的分區(qū),從而導(dǎo)致消費(fèi)壓力不均衡;
    • 如果發(fā)生再平衡,那么重新分配之后在前一點(diǎn)的基礎(chǔ)上會(huì)盡力保證當(dāng)前未宕機(jī)的consumer所消費(fèi)的分區(qū)不會(huì)被分配給其他的consumer上;
6.27 kafka為什么比rocketmq支持的單機(jī)partion要少?

kafka是一個(gè)分區(qū)一個(gè)文件,當(dāng)topic過(guò)多,分區(qū)的總量也會(huì)增加,kafka中存在過(guò)多的文件,當(dāng)對(duì)消息刷盤時(shí),就會(huì)出現(xiàn)文件競(jìng)爭(zhēng)磁盤,出現(xiàn)性能的下降。

rocketMq中,所有的隊(duì)列都存儲(chǔ)在一個(gè)文件中,每個(gè)隊(duì)列的存儲(chǔ)的消息量也比較小,因此topic的增加對(duì)rocketMq的性能的影響較小。也從而rocketMq可以存在的topic比較多,可以適應(yīng)比較復(fù)雜的業(yè)務(wù)。

6.28 partition分區(qū)數(shù)設(shè)置多少合適

沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)答案,可以根據(jù)當(dāng)前這個(gè)topic所屬業(yè)務(wù)的某個(gè)維度來(lái),也可以按照你kafka的broker數(shù)量來(lái)決定,還可以根據(jù)kafka系統(tǒng)默認(rèn)的分區(qū)數(shù)量來(lái)。

在回答前,先說(shuō)明partition數(shù)量對(duì)業(yè)務(wù)和性能的影響:

  1. 越多的partition可以提供更高的吞吐量,同時(shí)IO壓力也會(huì)增加。越多的分區(qū)需要打開更多的文件句柄。
  2. 建立topic時(shí)最好要確定partition的數(shù)量,雖然后期可以動(dòng)態(tài)增加,但原本小的partition數(shù)改大,必定會(huì)導(dǎo)致寬依賴的產(chǎn)生,而寬依賴則一定會(huì)產(chǎn)生shuffle,既然產(chǎn)生shuffle,那數(shù)據(jù)處理效率也就必然下降。

那么可以從2方面出發(fā):

  1. 性能。如果一次有大批量的數(shù)據(jù)過(guò)來(lái),需要在短時(shí)間內(nèi)存儲(chǔ),那么在資源請(qǐng)?jiān)试S的情況下,盡量設(shè)置多一些,增加吞吐量,partition數(shù)量>=consumer數(shù)量,這些也影響comsumer的消費(fèi)速度;如果在資源有限,一旦單個(gè)broker的partition過(guò)多,則順序?qū)憣⑼嘶癁殡S機(jī)寫,Page Cache臟頁(yè)過(guò)多,頻繁觸發(fā)缺頁(yè)中斷,性能大幅下降。
  2. 業(yè)務(wù)的角度。有多少數(shù)據(jù)源,或者按業(yè)務(wù)的維度去劃分更有利于消費(fèi),比如topic省市來(lái)劃分partition等
6.28 kafka刪除topic

kafka常見問(wèn)題QA(六)

6.29 consumer 再平衡步驟

coordinator:協(xié)調(diào)者,負(fù)責(zé)消費(fèi)者組內(nèi)成員的leader選舉、組內(nèi)再平衡、組offset提交等功能。

再平衡觸發(fā)三種情況

  • 組成員發(fā)生變更(新consumer加入組、已有consumer主動(dòng)離開組或已有consumer崩潰了)
  • 訂閱主題數(shù)發(fā)生變更——這當(dāng)然是可能的,如果你使用了正則表達(dá)式的方式進(jìn)行訂閱,那么新建匹配正則表達(dá)式的topic就會(huì)觸發(fā)rebalance
  • 訂閱主題的分區(qū)數(shù)發(fā)生變更

kafka常見問(wèn)題QA(六)

consumer 再平衡步驟

  1. 每個(gè)consumer都發(fā)送JoinGroup請(qǐng)求
  2. coordinator選出一個(gè) consumer作為 leader。如果消費(fèi)組內(nèi)沒有l(wèi)eader,那么第一個(gè)加入消費(fèi)組的消費(fèi)者就是消費(fèi)者 leader,如果這個(gè)時(shí)候leader消費(fèi)者退出了消費(fèi)組,那么重新選舉一個(gè)
  3. 把要消費(fèi)的 topic 情況 發(fā)送給leader 消費(fèi)者
  4. 消費(fèi)者leader會(huì)負(fù)責(zé)制定消費(fèi)方案
  5. 把消費(fèi)方案發(fā)給 coordinator,即消費(fèi)者leader向協(xié)調(diào)者發(fā)送SyncGroup請(qǐng)求
  6. Coordinator 就把消費(fèi)方案下發(fā)給各個(gè)consumer
  7. 每個(gè)消費(fèi)者都會(huì)和 coordinator 保持心跳( 默認(rèn) 3s ),一旦超時(shí) session.timeout.ms= 45s ),該消費(fèi)者會(huì)被移除,并觸發(fā)再平衡;或者消費(fèi)者處理消息的過(guò)長(zhǎng)(max.poll.interval.ms 5 分鐘),也會(huì)觸發(fā)再 平衡

分區(qū)分配策略的選擇

每個(gè)消費(fèi)者都可以設(shè)置自己的分區(qū)分配策略,消費(fèi)組內(nèi)的各個(gè)消費(fèi)者會(huì)通過(guò)投票來(lái)決定

  1. 在joingroup階段,每個(gè)consumer都會(huì)把自己支持的分區(qū)分配策略發(fā)送到coordinator
  2. coordinator收集到所有消費(fèi)者的分配策略,組成一個(gè)候選集
  3. 每個(gè)消費(fèi)者需要從候選集里找出一個(gè)自己支持的策略,并且為這個(gè)策略投票
  4. 最終計(jì)算候選集中各個(gè)策略的選票數(shù),票數(shù)最多的就是當(dāng)前消費(fèi)組的分配策略
6.30 KafkaProducer何時(shí)創(chuàng)建TCP連接?

Apache Kafka的所有通信都是基于TCP的,而不是基于HTTP或其他協(xié)議。

try (Producer<String, String> producer = new KafkaProducer<>(props)) {
            producer.send(new ProducerRecord<String, String>(……), callback);
	……
}
  1. 生產(chǎn)者應(yīng)用在創(chuàng)建KafkaProducer實(shí)例時(shí)是會(huì)建立與Broker的TCP連接的。其實(shí)這種表述也不是很準(zhǔn)確,應(yīng)該這樣說(shuō):在創(chuàng)建KafkaProducer實(shí)例時(shí),生產(chǎn)者應(yīng)用會(huì)在后臺(tái)創(chuàng)建并啟動(dòng)一個(gè)名為Sender的線程,該Sender線程開始運(yùn)行時(shí)首先會(huì)創(chuàng)建與Broker的連接。

    社區(qū)的官方文檔中提及KafkaProducer類是線程安全的。KafkaProducer實(shí)例創(chuàng)建的線程和前面提到的Sender線程共享的可變數(shù)據(jù)結(jié)構(gòu)只有RecordAccumulator類,故維護(hù)了RecordAccumulator類的線程安全,也就實(shí)現(xiàn)了KafkaProducer類的線程安全。了解RecordAccumulator類是做什么的,你只要知道它主要的數(shù)據(jù)結(jié)構(gòu)是一個(gè)ConcurrentMap<TopicPartition, Deque>。TopicPartition是Kafka用來(lái)表示主題分區(qū)的Java對(duì)象,本身是不可變對(duì)象。而RecordAccumulator代碼中用到Deque的地方都有鎖的保護(hù),所以基本上可以認(rèn)定RecordAccumulator類是線程安全的。

  2. TCP連接還可能在兩個(gè)地方被創(chuàng)建:一個(gè)是在更新元數(shù)據(jù)后,另一個(gè)是在消息發(fā)送時(shí)

    為什么說(shuō)是可能?因?yàn)檫@兩個(gè)地方并非總是創(chuàng)建TCP連接。當(dāng)Producer更新了集群的元數(shù)據(jù)信息之后,如果發(fā)現(xiàn)與某些Broker當(dāng)前沒有連接,那么它就會(huì)創(chuàng)建一個(gè)TCP連接。同樣地,當(dāng)要發(fā)送消息時(shí),Producer發(fā)現(xiàn)尚不存在與目標(biāo)Broker的連接,也會(huì)創(chuàng)建一個(gè)。

Producer端關(guān)閉TCP連接的方式有兩種:一種是用戶主動(dòng)關(guān)閉;一種是Kafka自動(dòng)關(guān)閉。

Kafka幫你關(guān)閉,這與Producer端參數(shù)connections.max.idle.ms的值有關(guān)。默認(rèn)情況下該參數(shù)值是9分鐘,即如果在9分鐘內(nèi)沒有任何請(qǐng)求“流過(guò)”某個(gè)TCP連接,那么Kafka會(huì)主動(dòng)幫你把該TCP連接關(guān)閉。用戶可以在Producer端設(shè)置connections.max.idle.ms=-1禁掉這種機(jī)制。一旦被設(shè)置成-1,TCP連接將成為永久長(zhǎng)連接。

在第二種方式中,TCP連接是在Broker端被關(guān)閉的,但其實(shí)這個(gè)TCP連接的發(fā)起方是客戶端,因此在TCP看來(lái),這屬于被動(dòng)關(guān)閉的場(chǎng)景,即passive close。被動(dòng)關(guān)閉的后果就是會(huì)產(chǎn)生大量的CLOSE_WAIT連接,因此Producer端或Client端沒有機(jī)會(huì)顯式地觀測(cè)到此連接已被中斷。如果設(shè)置該參數(shù)=-1,那么步驟1中創(chuàng)建的TCP連接將無(wú)法被關(guān)閉,從而成為“僵尸”連接

和生產(chǎn)者不同的是,構(gòu)建KafkaConsumer實(shí)例時(shí)是不會(huì)創(chuàng)建任何TCP連接的

6.31 KafkaConsumer何時(shí)創(chuàng)建TCP連接?
  1. 發(fā)起FindCoordinator請(qǐng)求時(shí)

    消費(fèi)者程序會(huì)向集群中當(dāng)前負(fù)載最小的那臺(tái)Broker發(fā)送請(qǐng)求。就是看消費(fèi)者連接的所有Broker中,誰(shuí)的待發(fā)送請(qǐng)求最少。當(dāng)然了,這種評(píng)估顯然是消費(fèi)者端的單向評(píng)估,并非是站在全局角度,因此有的時(shí)候也不一定是最優(yōu)解。

  2. 連接協(xié)調(diào)者時(shí)

  3. 消費(fèi)數(shù)據(jù)時(shí)

    舉個(gè)例子,假設(shè)消費(fèi)者要消費(fèi)5個(gè)分區(qū)的數(shù)據(jù),這5個(gè)分區(qū)各自的領(lǐng)導(dǎo)者副本分布在4臺(tái)Broker上,那么該消費(fèi)者在消費(fèi)時(shí)會(huì)創(chuàng)建與這4臺(tái)Broker的Socket連接。

當(dāng)?shù)谌怲CP連接成功創(chuàng)建后,消費(fèi)者程序就會(huì)廢棄第一類TCP連接,之后在定期請(qǐng)求元數(shù)據(jù)時(shí),它會(huì)改為使用第三類TCP連接。也就是說(shuō),最終你會(huì)發(fā)現(xiàn),第一類TCP連接會(huì)在后臺(tái)被默默地關(guān)閉掉。對(duì)一個(gè)運(yùn)行了一段時(shí)間的消費(fèi)者程序來(lái)說(shuō),只會(huì)有后面兩類TCP連接存在。

6.32 comsumer自動(dòng)提交位移的順序

一旦設(shè)置了enable.auto.commit為true,Kafka會(huì)保證在開始調(diào)用poll方法時(shí),提交上次poll返回的所有消息。從順序上來(lái)說(shuō),poll方法的邏輯是先提交上一批消息的位移,再處理下一批消息,因此它能保證不出現(xiàn)消費(fèi)丟失的情況。但自動(dòng)提交位移的一個(gè)問(wèn)題在于,它可能會(huì)出現(xiàn)重復(fù)消費(fèi)。

6.33 KafkaConsumer是線程安全的嗎

KafkaConsumer類不是線程安全的(thread-safe)。所有的網(wǎng)絡(luò)I/O處理都是發(fā)生在用戶主線程中,因此,你在使用過(guò)程中必須要確保線程安全。簡(jiǎn)單來(lái)說(shuō),就是你不能在多個(gè)線程中共享同一個(gè)KafkaConsumer實(shí)例,否則程序會(huì)拋出ConcurrentModificationException異常。

6.34 Leader總是-1,怎么破?

在生產(chǎn)環(huán)境中,你一定碰到過(guò)“某個(gè)主題分區(qū)不能工作了”的情形。使用命令行查看狀態(tài)的話,會(huì)發(fā)現(xiàn)Leader是-1,于是,你使用各種命令都無(wú)濟(jì)于事,最后只能用“重啟大法”。不重啟集群呢?

刪除ZooKeeper節(jié)點(diǎn)/controller,觸發(fā)Controller重選舉。Controller重選舉能夠?yàn)樗兄黝}分區(qū)重刷分區(qū)狀態(tài),可以有效解決因不一致導(dǎo)致的Leader不可用問(wèn)題。

6.35 __consumer_offsets是做什么用的?

這是一個(gè)內(nèi)部主題,公開的官網(wǎng)資料很少涉及到。因此,我認(rèn)為,此題屬于面試官炫技一類的題目。你要小心這里的考點(diǎn):該主題有3個(gè)重要的知識(shí)點(diǎn),你一定要全部答出來(lái),才會(huì)顯得對(duì)這塊知識(shí)非常熟悉。

  • 它是一個(gè)內(nèi)部主題,無(wú)需手動(dòng)干預(yù),由Kafka自行管理。當(dāng)然,我們可以創(chuàng)建該主題。
  • 它的主要作用是負(fù)責(zé)注冊(cè)消費(fèi)者以及保存位移值??赡苣銓?duì)保存位移值的功能很熟悉,但其實(shí)該主題也是保存消費(fèi)者元數(shù)據(jù)的地方。千萬(wàn)記得把這一點(diǎn)也回答上。另外,這里的消費(fèi)者泛指消費(fèi)者組和獨(dú)立消費(fèi)者,而不僅僅是消費(fèi)者組。
  • Kafka的GroupCoordinator組件提供對(duì)該主題完整的管理功能,包括該主題的創(chuàng)建、寫入、讀取和Leader維護(hù)等。
6.36 分區(qū)Leader選舉策略有幾種?

分區(qū)的Leader副本選舉對(duì)用戶是完全透明的,它是由Controller獨(dú)立完成的。你需要回答的是,在哪些場(chǎng)景下,需要執(zhí)行分區(qū)Leader選舉。每一種場(chǎng)景對(duì)應(yīng)于一種選舉策略。當(dāng)前,Kafka有4種分區(qū)Leader選舉策略。

  • OfflinePartition Leader選舉:每當(dāng)有分區(qū)上線時(shí),就需要執(zhí)行Leader選舉。所謂的分區(qū)上線,可能是創(chuàng)建了新分區(qū),也可能是之前的下線分區(qū)重新上線。這是最常見的分區(qū)Leader選舉場(chǎng)景。
  • ReassignPartition Leader選舉:當(dāng)你手動(dòng)運(yùn)行kafka-reassign-partitions命令,或者是調(diào)用Admin的alterPartitionReassignments方法執(zhí)行分區(qū)副本重分配時(shí),可能觸發(fā)此類選舉。假設(shè)原來(lái)的AR是[1,2,3],Leader是1,當(dāng)執(zhí)行副本重分配后,副本集合AR被設(shè)置成[4,5,6],顯然,Leader必須要變更,此時(shí)會(huì)發(fā)生Reassign Partition Leader選舉。
  • PreferredReplicaPartition Leader選舉:當(dāng)你手動(dòng)運(yùn)行kafka-preferred-replica-election命令,或自動(dòng)觸發(fā)了Preferred Leader選舉時(shí),該類策略被激活。所謂的Preferred Leader,指的是AR中的第一個(gè)副本。比如AR是[3,2,1],那么,Preferred Leader就是3。
  • ControlledShutdownPartition Leader選舉:當(dāng)Broker正常關(guān)閉時(shí),該Broker上的所有Leader副本都會(huì)下線,因此,需要為受影響的分區(qū)執(zhí)行相應(yīng)的Leader選舉。

這4類選舉策略的大致思想是類似的,即從AR中挑選首個(gè)在ISR中的副本,作為新Leader。當(dāng)然,個(gè)別策略有些微小差異。不過(guò),回答到這種程度,應(yīng)該足以應(yīng)付面試官了。畢竟,微小差別對(duì)選舉Leader這件事的影響很小。

6.37 Kafka的哪些場(chǎng)景中使用了零拷貝(Zero Copy)?

Zero Copy是特別容易被問(wèn)到的高階題目。在Kafka中,體現(xiàn)Zero Copy使用場(chǎng)景的地方有兩處:基于mmap的索引日志文件讀寫所用的TransportLayer。

先說(shuō)第一個(gè)。索引都是基于MappedByteBuffer的,也就是讓用戶態(tài)和內(nèi)核態(tài)共享內(nèi)核態(tài)的數(shù)據(jù)緩沖區(qū),此時(shí),數(shù)據(jù)不需要復(fù)制到用戶態(tài)空間。不過(guò),mmap雖然避免了不必要的拷貝,但不一定就能保證很高的性能。在不同的操作系統(tǒng)下,mmap的創(chuàng)建和銷毀成本可能是不一樣的。很高的創(chuàng)建和銷毀開銷會(huì)抵消Zero Copy帶來(lái)的性能優(yōu)勢(shì)。由于這種不確定性,在Kafka中,只有索引應(yīng)用了mmap,最核心的日志并未使用mmap機(jī)制。

再說(shuō)第二個(gè)。TransportLayer是Kafka傳輸層的接口。它的某個(gè)實(shí)現(xiàn)類使用了FileChannel的transferTo方法。該方法底層使用sendfile實(shí)現(xiàn)了Zero Copy。對(duì)Kafka而言,如果I/O通道使用普通的PLAINTEXT,那么,Kafka就可以利用Zero Copy特性,直接將頁(yè)緩存中的數(shù)據(jù)發(fā)送到網(wǎng)卡的Buffer中,避免中間的多次拷貝。相反,如果I/O通道啟用了SSL,那么,Kafka便無(wú)法利用Zero Copy特性了。

6.38 如何調(diào)優(yōu)Kafka?

回答任何調(diào)優(yōu)問(wèn)題的第一步,就是確定優(yōu)化目標(biāo),并且定量給出目標(biāo)!這點(diǎn)特別重要。對(duì)于Kafka而言,常見的優(yōu)化目標(biāo)是吞吐量、延時(shí)、持久性和可用性。每一個(gè)方向的優(yōu)化思路都是不同的,甚至是相反的。

確定了目標(biāo)之后,還要明確優(yōu)化的維度。有些調(diào)優(yōu)屬于通用的優(yōu)化思路,比如對(duì)操作系統(tǒng)、JVM等的優(yōu)化;有些則是有針對(duì)性的,比如要優(yōu)化Kafka的TPS。我們需要從3個(gè)方向去考慮。

  • Producer端:增加batch.size、linger.ms,啟用壓縮,關(guān)閉重試等。
  • Broker端:增加num.replica.fetchers,提升Follower同步TPS,避免Broker Full GC等。
  • Consumer:增加fetch.min.bytes等
6.39 Controller發(fā)生網(wǎng)絡(luò)分區(qū)(Network Partitioning)時(shí),Kafka會(huì)怎么樣?

這道題目能夠誘發(fā)我們對(duì)分布式系統(tǒng)設(shè)計(jì)、CAP理論、一致性等多方面的思考。不過(guò),針對(duì)故障定位和分析的這類問(wèn)題,我建議你首先言明“實(shí)用至上”的觀點(diǎn),即不論怎么進(jìn)行理論分析,永遠(yuǎn)都要以實(shí)際結(jié)果為準(zhǔn)。一旦發(fā)生Controller網(wǎng)絡(luò)分區(qū),那么,第一要?jiǎng)?wù)就是查看集群是否出現(xiàn)“腦裂”,即同時(shí)出現(xiàn)兩個(gè)甚至是多個(gè)Controller組件。這可以根據(jù)Broker端監(jiān)控指標(biāo)ActiveControllerCount來(lái)判斷。

現(xiàn)在,我們分析下,一旦出現(xiàn)這種情況,Kafka會(huì)怎么樣。

由于Controller會(huì)給Broker發(fā)送3類請(qǐng)求,即LeaderAndIsrRequest、StopReplicaRequest和UpdateMetadataRequest,因此,一旦出現(xiàn)網(wǎng)絡(luò)分區(qū),這些請(qǐng)求將不能順利到達(dá)Broker端。這將影響主題的創(chuàng)建、修改、刪除操作的信息同步,表現(xiàn)為集群仿佛僵住了一樣,無(wú)法感知到后面的所有操作。因此,網(wǎng)絡(luò)分區(qū)通常都是非常嚴(yán)重的問(wèn)題,要趕快修復(fù)。

6.40 Java Consumer為什么采用單線程來(lái)獲取消息?

在回答之前,如果先把這句話說(shuō)出來(lái),一定會(huì)加分:Java Consumer是雙線程的設(shè)計(jì)。一個(gè)線程是用戶主線程,負(fù)責(zé)獲取消息;另一個(gè)線程是心跳線程,負(fù)責(zé)向Kafka匯報(bào)消費(fèi)者存活情況。將心跳單獨(dú)放入專屬的線程,能夠有效地規(guī)避因消息處理速度慢而被視為下線的“假死”情況。

單線程獲取消息的設(shè)計(jì)能夠避免阻塞式的消息獲取方式。單線程輪詢方式容易實(shí)現(xiàn)異步非阻塞式,這樣便于將消費(fèi)者擴(kuò)展成支持實(shí)時(shí)流處理的操作算子。因?yàn)楹芏鄬?shí)時(shí)流處理操作算子都不能是阻塞式的。另外一個(gè)可能的好處是,可以簡(jiǎn)化代碼的開發(fā)。多線程交互的代碼是非常容易出錯(cuò)的。

6.41 簡(jiǎn)述Follower副本消息同步的完整流程

首先,F(xiàn)ollower發(fā)送FETCH請(qǐng)求給Leader。接著,Leader會(huì)讀取底層日志文件中的消息數(shù)據(jù),再更新它內(nèi)存中的Follower副本的LEO值,更新為FETCH請(qǐng)求中的fetchOffset值。最后,嘗試更新分區(qū)高水位值。Follower接收到FETCH響應(yīng)之后,會(huì)把消息寫入到底層日志,接著更新LEO和HW值。

Leader和Follower的HW值更新時(shí)機(jī)是不同的,F(xiàn)ollower的HW更新永遠(yuǎn)落后于Leader的HW。這種時(shí)間上的錯(cuò)配是造成各種不一致的原因。

七、參考

Kafka:這次分享我只想把原理講清楚
kafka中文網(wǎng)
關(guān)于OS Page Cache的簡(jiǎn)單介紹
《圖解系統(tǒng)》筆記(一)
zookeeper和Kafka的關(guān)系
Kafka源碼深度解析-序列4 -Producer -network層核心原理
Reactor模式介紹
Reactor模型
圖解Kafka服務(wù)端網(wǎng)絡(luò)模型]
Kafka 核心技術(shù)與實(shí)戰(zhàn)
Kafka 核心源碼解讀

轉(zhuǎn)載請(qǐng)注明:arthur.dy.lee_kafka常見問(wèn)題QA(六)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-500333.html

到了這里,關(guān)于kafka常見問(wèn)題QA(六)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 消息隊(duì)列常見問(wèn)題(1)-如何保障不丟消息

    消息隊(duì)列常見問(wèn)題(1)-如何保障不丟消息

    目錄 1. 為什么消息隊(duì)列會(huì)丟消息? 2. 怎么保障消息可靠傳遞? 2.1 生產(chǎn)者不丟消息 2.2 服務(wù)端不丟消息 2.3 消費(fèi)者不丟消息 3. 消息丟失如何快速止損? 3.1 完善監(jiān)控 3.2 完善止損工具 現(xiàn)在主流的消息隊(duì)列都會(huì)提供完善的高可用解決方案,但是我們依然會(huì)有多種原因?qū)е孪G

    2024年02月14日
    瀏覽(18)
  • Kafka如何解決消息丟失的問(wèn)題

    在 Kafka 的整個(gè)架構(gòu)中可以總結(jié)出消息有三次傳遞的過(guò)程: Producer 端發(fā)送消息給 Broker 端 Broker 將消息進(jìn)行并持久化數(shù)據(jù) Consumer 端從 Broker 將消息拉取并進(jìn)行消費(fèi) 在以上這三步中每一步都可能會(huì)出現(xiàn)丟失數(shù)據(jù)的情況, 那么 Kafka 到底在什么情況下才能保證消息不丟失呢? Produ

    2024年02月12日
    瀏覽(17)
  • RabbitMQ常見問(wèn)題之消息堆積

    RabbitMQ常見問(wèn)題之消息堆積

    當(dāng)生產(chǎn)者發(fā)送消息的速度超過(guò)了消費(fèi)者處理消息的速度,就會(huì)導(dǎo)致隊(duì)列中的消息堆積,直到隊(duì)列存儲(chǔ)消息達(dá)到上限。最 早接收到的消息,可能就會(huì)成為死信,會(huì)被丟棄,這就是消息堆積問(wèn)題。 解決消息堆積有三種種思路: 增加 更多消費(fèi)者 ,提高消費(fèi)速度 在消費(fèi)者內(nèi)開啟 線程

    2024年01月18日
    瀏覽(23)
  • 消息中間件中常見問(wèn)題

    消息中間件中常見問(wèn)題

    MQ的用途 異步發(fā)送(驗(yàn)證碼,短信,郵件) MySQL,ES,Redis之間的數(shù)據(jù)同步 分布式事務(wù) 削峰填谷 消息可能丟失的環(huán)境 消息在產(chǎn)生端時(shí)候生產(chǎn)端掛掉,消息未到達(dá)交換機(jī),消息丟失 消息在交換機(jī)未到達(dá)隊(duì)列,消息丟失 消息隊(duì)列中如果隊(duì)列掛掉消息也可能丟失 消費(fèi)者未接收消

    2024年02月15日
    瀏覽(32)
  • RabbitMQ常見問(wèn)題之延遲消息

    RabbitMQ常見問(wèn)題之延遲消息

    當(dāng)一個(gè)隊(duì)列中的消息滿足下列情況之一時(shí),可以成為死信( dead letter ): 消費(fèi)者使用 basic.reject 或 basic.nack 聲明消費(fèi)失敗,并且消息的 requeue 參數(shù)設(shè)置為 false 消息是一個(gè)過(guò)期消息,超時(shí)無(wú)人消費(fèi) 要投遞的隊(duì)列消息堆積滿了,最早的消息可能成為死信 如果該隊(duì)列配置了 dead

    2024年01月18日
    瀏覽(21)
  • 《Kafka系列》Kafka常見問(wèn)題處理記錄

    《Kafka系列》Kafka常見問(wèn)題處理記錄

    1.創(chuàng)建語(yǔ)句如下所示,按照習(xí)慣在添加zookeeper參數(shù)的時(shí)候,指定了 zxy:2181/kafka ,但是卻創(chuàng)建失敗, Error while executing topic command : Replication factor: 1 larger than available brokers: 0. 2.檢查各個(gè)broker的server.properties文件 發(fā)現(xiàn)在配置參數(shù)的時(shí)候, zookeeper.connect 指定的是 zxy:2181,zxy:2182,zxy:21

    2024年02月03日
    瀏覽(35)
  • kafka常見問(wèn)題

    kafka常見問(wèn)題

    1.為什么要用mq(mq的作用)? 2.引入mq會(huì)多哪些問(wèn)題? 3. 如何解決這些問(wèn)題? 1.1實(shí)現(xiàn)異步發(fā)送 有些復(fù)雜的業(yè)務(wù)系統(tǒng),一次用戶請(qǐng)求可能會(huì)同步調(diào)用N個(gè)系統(tǒng)的接口,需要等待所有的接口都返回了,才能真正的獲取執(zhí)行結(jié)果。這種同步接口調(diào)用的方式總耗時(shí)比較長(zhǎng),非常影響用

    2024年02月11日
    瀏覽(31)
  • RabbitMQ常見問(wèn)題之消息可靠性

    RabbitMQ常見問(wèn)題之消息可靠性

    MQ 的消息可靠性,將從以下四個(gè)方面展開并實(shí)踐: 生產(chǎn)者消息確認(rèn) 消息持久化 消費(fèi)者消息確認(rèn) 消費(fèi)失敗重試機(jī)制 對(duì)于 publisher ,如果 message 到達(dá) exchange 與否, rabbitmq 提供 publiser-comfirm 機(jī)制,如果 message 達(dá)到 exchange 但是是否到達(dá) queue , rabbitmq 提供 publisher-return 機(jī)制。這兩

    2024年01月18日
    瀏覽(97)
  • kafka無(wú)消息丟失配置

    目錄 前言: ?消息丟失的場(chǎng)景 ?生產(chǎn)者消息丟失 Broker消息丟失? 消費(fèi)者消息丟失? ?消息丟失問(wèn)題排查 無(wú)消息丟失配置: 參考資料: ? ? ? 使用消息中間件時(shí),我們遇到最頭疼的事就消息丟失, 小則影響程序錯(cuò)誤,大則影響到某個(gè)重要業(yè)務(wù)失敗。如果kafka配置不當(dāng)或者使用

    2024年02月16日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包