16.報(bào)文分發(fā)庫(kù)
DPDK報(bào)文分發(fā)器是一種庫(kù),用于在一次 操作中獲取單個(gè)數(shù)據(jù)包,以支持流量的動(dòng)態(tài)負(fù)載均衡。當(dāng)使用這個(gè)庫(kù)時(shí),需要考慮兩種角色的邏輯核:首先是負(fù)責(zé)負(fù)載均衡及分發(fā)數(shù)據(jù)包的分發(fā)邏輯核,另一個(gè)是一組工作邏輯核,負(fù)責(zé)接收來(lái)自分發(fā)邏輯核的數(shù)據(jù)包并對(duì)其進(jìn)行操作。
操作模式如下圖所示:

在報(bào)文分發(fā)器庫(kù)中有兩種API操作模式:一種是使用32bit的flow_id,一次向一個(gè)worker發(fā)送一個(gè)報(bào)文;另一種優(yōu)化模式是一次性最多發(fā)送8個(gè)數(shù)據(jù)包給worker,使用15bit的flow_id。該模式由rte_distributor_create()函數(shù)中的類型字段指定。
16.1.分發(fā)邏輯核操作
分發(fā)邏輯核執(zhí)行了大部分的處理以確保數(shù)據(jù)包在worker之間公平分發(fā)。分發(fā)邏輯核的運(yùn)作情況如下:
- 分發(fā)邏輯核的lcore線程通過(guò)調(diào)用rte_distributor_process()來(lái)獲取數(shù)據(jù)包。
- 所有的worker lcore與distributor lcore共享一條緩存線行,以便在worker和distributor之間傳遞消息和數(shù)據(jù)包。執(zhí)行API調(diào)用將輪詢所有worker的緩存行,以查看哪些worker正在請(qǐng)求數(shù)據(jù)包。
- 當(dāng)有worker請(qǐng)求數(shù)據(jù)包時(shí),distributor從第一步中傳過(guò)來(lái)的一組數(shù)據(jù)包中取出數(shù)據(jù)包,并將其分發(fā)給worker。它檢查每個(gè)數(shù)據(jù)包中存儲(chǔ)在mbuf中RSS哈希字段中的“tag”,并記錄每個(gè)worker正在處理的tag。
- 如果輸入報(bào)文集中的下一個(gè)數(shù)據(jù)包有一個(gè)已經(jīng)被worker處理的tag,則該數(shù)據(jù)包將排隊(duì)等待worker的處理,并在下一個(gè)worker請(qǐng)求數(shù)據(jù)包時(shí),優(yōu)先考慮其他的數(shù)據(jù)包。這可以確保不會(huì)并發(fā)處理具有相同tag的兩個(gè)報(bào)文,并且,具有相同tag的兩個(gè)報(bào)文按輸入順序被處理。
- 一旦傳遞給執(zhí)行API的所有報(bào)文已經(jīng)分發(fā)給worker,或者已經(jīng)排隊(duì)等待給定tag的worker處理,則執(zhí)行API返回給調(diào)用者。
Distributor lcore可以使用的其他功能有:
- rte_distributor_returned_pkts()
- rte_distributor_flush()
- rte_distributor_clear_returns()
其中最重要的API調(diào)用是“rte_distributor_returned_pkts()”,它只能在調(diào)用進(jìn)程API的lcore上調(diào)用。 它將所有worker core完成處理的所有數(shù)據(jù)包返回給調(diào)用者。在這組返回的數(shù)據(jù)包中,共享相同標(biāo)簽的所有數(shù)據(jù)包將按原始順序返回。
注意:
如果worker lcore在內(nèi)部緩存數(shù)據(jù)包進(jìn)行批量傳輸,則共享tag的數(shù)據(jù)包可能會(huì)出現(xiàn)故障。一旦一個(gè)worker lcore請(qǐng)求一個(gè)新的數(shù)據(jù)包,distributor就會(huì)假定它已經(jīng)完成了先前的數(shù)據(jù)包,因此具有相同tag的附加數(shù)據(jù)包可以安全地分配給其他worker,然后他們可能會(huì)更早地刷新緩沖的數(shù)據(jù)包,使數(shù)據(jù)包發(fā)生故障。
注意:對(duì)于不共享公共數(shù)據(jù)包tag的數(shù)據(jù)包,不提供數(shù)據(jù)包排序保證。
使用上述執(zhí)行過(guò)程及returned_pkts API,可以使用以下應(yīng)用程序工作流,同時(shí)允許維護(hù)由tag識(shí)別的數(shù)據(jù)包流中的數(shù)據(jù)包順序。

之前提到的flush和clear_returns API調(diào)用可能不太用于進(jìn)程和returned_pkts APIS,并且主要用于幫助對(duì)庫(kù)進(jìn)行單元測(cè)試。可以在DPDK API參考文檔中找到這些功能及其用途的描述。
16.2.Worker Operation
Worker lcore是對(duì)distributor分發(fā)的數(shù)據(jù)包進(jìn)行實(shí)際操作的lcore。 Worker調(diào)用rte_distributor_get_pkt() API在完成處理前一個(gè)數(shù)據(jù)包時(shí)請(qǐng)求一個(gè)新的數(shù)據(jù)包。前一個(gè)數(shù)據(jù)包應(yīng)通過(guò)將其作為最終參數(shù)傳遞給該API調(diào)用而返回給分發(fā)器組件。
有時(shí)候可能需要改變worker lcore的數(shù)量,這取決于業(yè)務(wù)負(fù)載,即在較輕的負(fù)載時(shí)節(jié)省功率,可以worker通過(guò)調(diào)用rte_distributor_return_pkt()接口停止處理報(bào)文,以指示在完成當(dāng)前數(shù)據(jù)包處理后,不需要新的數(shù)據(jù)包。