場景介紹
在DMS提供(gong)的(de)(de)原生Kafka SDK中,消費(fei)者(zhe)可(ke)以自定(ding)義(yi)拉取消息的(de)(de)時長(chang),如果(guo)需要長(chang)時間(jian)的(de)(de)拉取消息,只需要把(ba)poll(long)方法的(de)(de)參數設置合適的(de)(de)值(zhi)即可(ke)。但是這樣的(de)(de)長(chang)連接可(ke)能(neng)會對客(ke)戶端和服(fu)務端造成一定(ding)的(de)(de)壓力,特別是分區數較多(duo)且每個消費(fei)者(zhe)開啟多(duo)個線程的(de)(de)情況下(xia)。
如圖所(suo)示(shi),Kafka隊(dui)列含有(you)多(duo)個分區,消費(fei)組(zu)中有(you)多(duo)個消費(fei)者同時(shi)進行消費(fei),每(mei)個線程均為長連(lian)接(jie)。當隊(dui)列中消息(xi)(xi)較少或者沒有(you)時(shi),連(lian)接(jie)不斷(duan)開,所(suo)有(you)消費(fei)者不間斷(duan)地拉取消息(xi)(xi),這(zhe)樣造(zao)成(cheng)了一定的資(zi)源浪費(fei)。
圖(tu) Kafka消費(fei)者多線(xian)程消費(fei)模式

優化方案
在(zai)開了(le)多個線程(cheng)(cheng)同時訪(fang)問的(de)(de)情況(kuang)下,如果隊(dui)列里已經沒有消(xiao)息了(le),其(qi)實不(bu)需(xu)要所(suo)有的(de)(de)線程(cheng)(cheng)都(dou)在(zai)poll,只需(xu)要有一(yi)個線程(cheng)(cheng)poll各分區的(de)(de)消(xiao)息就足(zu)夠(gou)了(le),當在(zai)polling的(de)(de)線程(cheng)(cheng)發(fa)現隊(dui)列中有消(xiao)息,可以喚醒其(qi)他(ta)線程(cheng)(cheng)一(yi)起消(xiao)費(fei)消(xiao)息,以達(da)到快速響應的(de)(de)目的(de)(de)。如圖所(suo)示。
這種方案適(shi)用(yong)于對(dui)消(xiao)(xiao)費消(xiao)(xiao)息的(de)實時性要求不高的(de)應用(yong)場景(jing)。如果要求準實時消(xiao)(xiao)費消(xiao)(xiao)息,則建議保持所有(you)消(xiao)(xiao)費者處(chu)于活躍狀(zhuang)態。
圖(tu) 優化后的(de)多線(xian)程消(xiao)費(fei)方案

說明消費者(Consumer)和消息分區(Partition)并不強制數量相等,Kafka的poll(long)方法幫助實現獲取消息、分區平衡、消費者與Kafka broker節點間的心跳檢測等功能。
因此在(zai)對消(xiao)(xiao)費(fei)消(xiao)(xiao)息的(de)實(shi)時性要求不高場景下(xia),當消(xiao)(xiao)息數量不多的(de)時候,可以選擇讓一部分消(xiao)(xiao)費(fei)者處于wait狀態(tai)。