Skip to content

RIP 27 Auto batching in producer

rongtong edited this page Jan 6, 2022 · 1 revision

Status

Background & Motivation

What do we need to do

  • Will we add a new module? No.
  • Will we add new APIs? Yes.
  • Will we add new feature? Yes.

Why should we do that

  • Are there any problems of our current project? Messages are sent in batches with very good throughput performance, but currently the business end needs to be packaged manually by itself, and the experience is not good enough.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

æ¶ˆæŻæ‰čé‡ć‘é€æœ‰ç€éžćžžć„œçš„ćžćé‡èĄšçŽ°ïŒŒäœ†æ˜Żç›źć‰éœ€èŠäžšćŠĄæ–čè‡ȘèĄŒæ‰‹ćŠšæ‰“ćŒ…ïŒŒäœ“éȘŒäžć€Ÿć„œă€‚

  • What can we benefit proposed changes?

To realize the automatic message packaging function, the business side only needs to simply call the sending interface of a single message to realize the throughput of batch sending.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

漞现侀äžȘæ¶ˆæŻè‡ȘćŠšæ‰“ćŒ…çš„ćŠŸèƒœïŒŒäžšćŠĄæ–čćȘéœ€èŠçź€ć•è°ƒç”šć•æĄæ¶ˆæŻçš„ć‘é€æŽ„ćŁïŒŒćłćŻèŸŸćˆ°æ‰čé‡ć‘é€æ—¶çš„ćžćé‡ă€‚

Goals

  • What problem is this proposal designed to solve?

Realize the auto batching function in the producer.

漞现producerçš„æ¶ˆæŻè‡ȘćŠšæ‰“ćŒ…ćŠŸèƒœă€‚

Changes

Architecture

ProduceAccumulator

  • Instructions for open

Tx31G4.png

batchMaxBytesïŒšæŻäžȘMessageAccumulationæœ€ć€§çŽŻç§Żć€§ć°ïŒŒè¶…èż‡èŻ„é˜ˆć€Œć°†äŒšæ‰“ćŒ…ć‘é€

batchMaxDelayMsïŒšæŻæĄMessagećœšæš‚ć­˜ćŒșæœ€é•żç­‰ćŸ…æ—¶é—ŽïŒŒè¶…èż‡èŻ„é˜ˆć€Œć°†äŒšæ‰“ćŒ…ć‘é€

totalBatchMaxBytes所有MessageAccumulationçŽŻç§Żć€§ć°äč‹ć’Œçš„é˜ˆć€ŒïŒŒè¶…èż‡èŻ„é˜ˆć€ŒćŽç»­èŻ·æ±‚ć°†ç›ŽæŽ„ć‘é€

Tx3adK.png

Producers with the same MQClientId shares the same ProducerAccumulator instance

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

盾搌 MQClientId 的 Producers ć…±ç”šćŒäž€äžȘ ProducerAccumulator

Tx3BJe.png

There are two MAP corresponding to two sending methods (syncSendBatchs and asyncSendBatchs). The key of Map is the smallest granularity of batch, the value is the staging area for messages.

There are two SERVICE for cooperating with two sending modes (GuardForSyncSendService and GuardForAsyncSendService), notify or send or cleanup regularly according to 'batchMaxDelayMs'.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

æŻäž€äžȘ ProducerAccumulator 䞭有䞀äžȘ MAP ćŻčćș”äž€ç§äžćŒçš„ć‘é€æšĄćŒïŒˆsyncSendBatchs、asyncSendBatchsMAP 的锼äžșæ‰čé‡ć‘é€èšćˆæ—¶çš„æœ€ć°çȒćșŠïŒˆäŸ‹ćŠ‚MessageQueueïŒ‰ïŒŒć€ŒäžșćŸ…èšćˆæ¶ˆæŻçš„çŒ“ć†ČćŒș。

ćŒæ—¶èż˜æœ‰äž€äžȘ SERVICE ç”šæ„ćè°ƒäž€ç§äžćŒçš„ć‘é€æšĄćŒïŒˆGuardForSyncSendService、GuardForAsyncSendService仄 batchMaxDelayMs äžșć‘šæœŸïŒŒć”€é†’çșżçš‹ă€ć‘é€æ¶ˆæŻæˆ–è€…æž…ç†ćŻčè±Ąă€‚

Map<String, MessageAccumulation> 侭的KeyïŒŒćœšæœȘæŒ‡ćźš MessageQueue çš„æœŸæœ›ćźƒæ˜Ż TopicïŒˆéżć…ć‡șçŽ°ć€§é‡ć°batchçš„æƒ…ć†”ïŒ‰ïŒŒćœšæŒ‡ćźšäș†ć‘é€é˜Ÿćˆ—çš„æƒ…ć†”äž‹æœŸæœ›ćźƒæ˜Ż Topic+Queueă€‚èż™é‡ŒäčŸèźžćș”èŻ„æŠœè±Ąć‡ș侀äžȘ类䌌äșŽâ€œèšćˆçȒćșŠâ€çš„æŠ‚ćż”

èż™é‡Œèż˜éœ€èŠćŻč MessageAccumulation äžȘæ•°ćšäș›é™ćˆ¶ïŒŒéąć€–ć†…ć­˜ćŒ€é”€ć€§çșŠäžș batchMaxBytes * MessageAccumulationäžȘ数

Tx3yQA.png

Assign topic, waitStoreMsgOK, and createTime every time an instance of MessageAccumulation is created. When the user calls the send interface, the getOrCreateProduceAccumulator interface is called according to the message. If a new MessageAccumulation needs to be created, mqProducer will be registered.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

æŻæŹĄćˆ›ć»ș MessageAccumulation ćźžäŸ‹æ—¶äŒšè”‹ć€Œ topic、waitStoreMsgOK 撌 createTime äżĄæŻă€‚ćœ“ç”šæˆ·è°ƒç”š send æŽ„ćŁæ—¶ïŒŒäŒšè§Šć‘ getOrCreateProduceAccumulator æŽ„ćŁïŒŒćŠ‚æžœæ­€æ—¶éœ€èŠćˆ›ć»ș MessageAccumulation ćźžäŸ‹ïŒŒćˆ™ć°†æœŹæŹĄć‘é€æ“äœœäžŠäž‹æ–‡äž­çš„ mqProducer æłšć†Œèż›ćŽ»ă€‚ïŒˆç›žćœ“äșŽéšæœșæŒ‘é€‰èŻ„ instance 例的 producerïŒŒæœ€ć€§ćŒ–ćˆ©ç”šć·Čç”łèŻ·çš„è”„æșïŒŒäŸ‹ćŠ‚çșżçš‹æ± ïŒ‰

Tx3cLt.png

When the user sends a message in sync mode, the thread calling the send will check if it is ready to send or be suspended. GuardForSyncSendService will regularly notify when it is ready to send during the batchMaxDelayMs cycle and clean up long unused MessageAccumulation.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

ćœ“ç”šæˆ·ä»„ćŒæ­„æšĄćŒć‘é€æ¶ˆæŻæ—¶ïŒŒè°ƒç”šć‘é€æŽ„ćŁçš„çșżçš‹ć°†äŒšæŁ€æ”‹æ˜ŻćŠæ»Ąè¶łć‘é€æĄä»¶ïŒŒäžæ»Ąè¶łć°†äŒšæŒ‚è”·ă€‚GuardForSyncSendService 䌚仄 batchMaxDelayMs äžșć‘šæœŸć”€é†’æ»Ąè¶łć‘é€æĄä»¶â‘ çš„çșżçš‹ïŒŒćč¶æž…理äč…æœȘäœżç”šçš„GuardForSyncSendService。

Tx3Rdf.png

When the user sends a message in async mode, it will add message and sendCallBack to the two lists of MessageAccumulation respectively, and then return directly. GuardForAsyncSendService will regularly send by mqProducer if it is ready to send during the batchMaxDelayMs cycle and clean up long unused MessageAccumulation.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

ćœ“ç”šæˆ·ä»„ćŒ‚æ­„æšĄćŒć‘é€æ¶ˆæŻæ—¶ïŒŒćŸ…ć‘é€çš„æ¶ˆæŻć’Œć›žè°ƒć‡œæ•°äŒšæ·»ćŠ ćˆ° MessageAccumulation 的䞀äžȘ list äžŠïŒŒç„¶ćŽç›ŽæŽ„èż”ć›žă€‚GuardForAsyncSendService 䌚仄 batchMaxDelayMs äžșć‘šæœŸćœšæ»Ąè¶łć‘é€æĄä»¶â‘ çš„æƒ…ć†”äž‹ç”šæłšć†Œèż›ćŽ»çš„ mqProducer ćŒ‚æ­„ć‘é€ïŒŒćč¶æž…陀äč…æœȘäœżç”šçš„ MessageAccumulation。

â‘ æ»Ąè¶łć‘é€æĄä»¶ïŒšè·çŠ» MessageAccumulation 戛ć»șæ—¶é—Ž ≄ batchMaxDelayMs或者 MessageAccumulation äž­çŽŻç§Żæ¶ˆæŻć€§ć° ≄ batchMaxBytes

慳äșŽæ¶ˆæŻèšćˆçš„æłšæ„äș‹éĄč

ćœšæ—§ç‰ˆæœŹ Broker äž­ïŒŒæœćŠĄç«ŻäŒšć°† MessageBatch è§ŁćŒ…ćŽæž„ć»șçŽąćŒ•ïŒŒæ­€æ—¶äž€äžȘ MessageBatch é‡Œçš„ć€šæĄæ•°æźćŻä»„æœ‰ć„è‡Ș侍搌的 TAG、KEYS、MsgID。

äœ†æ˜Żćœšäœżç”š BatchConsumerQueue çš„æ–°ç‰ˆæœŹ Broker 䞭䞀äžȘ MessageBatch ć°†èą«ćœ“ćšäž€æĄç‹Źç«‹çš„æ¶ˆæŻïŒŒæœ‰äž”ćȘæœ‰ć”Żäž€çš„ TAG、KEYS、MsgIDă€‚ć› æ­€éœ€èŠć…łæłšæž„ć»ș BCQ 撌 index æ—¶çš„ç»†èŠ‚ă€‚

TAGïŒšć…·æœ‰ç›žćŒ TAG çš„æ¶ˆæŻæ‰èƒœèšćˆïŒˆæœȘèźŸçœź TAG 的äčŸéœ€èŠćˆ†ćŒ€èšćˆïŒ‰ïŒˆæ–°æ—§ç‰ˆæœŹć…Œćźč

KEYS䞍仄 KEYS 䜜äžșèšćˆç»ŽćșŠé™ćˆ¶ïŒŒäœ†æ˜Żćœšæ‰“ćŒ…æˆ MessageBatch ćŽïŒŒéœ€èŠèźŸçœź MessageBatch 的 KEYS äžșæŻæĄæ¶ˆæŻ KEYS 的ćč¶é›†ă€‚ïŒˆæ–°æ—§ç‰ˆæœŹć…Œćźč

MsgID构成䞀äžȘ MessageBatch çš„æ‰€æœ‰æ¶ˆæŻć…·æœ‰ç›žćŒçš„ MsgIDă€‚ïŒˆæ—§ç‰ˆæœŹäžć…ŒćźčïŒ‰ć› æ­€éœ€èŠćŻčèż”ć›žçš„MsgIDずç‰čæźŠćˆ€æ–­ć’Œć€„ç†

Interface Design/Change

  • Method signature changes

    Nothing specific.

  • Method behavior changes

    When calling the send interface, distinguish whether it needs to be sent in batches. What is needed will go to MessageAccumulation, and the others will be sent as usual

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

调甚 send æŽ„ćŁæ—¶ćŒșćˆ†æ˜ŻćŠéœ€èŠæ‰čé‡ć‘é€ïŒŒéœ€èŠçš„ć°†äŒšèż›ć…„ MessageAccumulation ïŒŒć…¶ä»–çš„ç…§ćžžć‘é€

  • CLI command changes

    Nothing specific.

  • Log format or content changes Nothing specific.

Compatibility, Deprecation, and Migration Plan

  • Are backward and forward compatibility taken into consideration?

Reuse the ability of MessageBatch, only as an enhancement.

---------------------äž­æ–‡ćˆ†ć‰Čçșż----------------------

ć€ç”šäș† MessageBatch çš„èƒœćŠ›ïŒŒćȘ䜜äžșèƒœćŠ›ćąžćŒș

  • Are there deprecated APIs? Nothing specific.

  • How do we do migration? Upgrade on the client side.

Implementation Outline

We will implement the proposed changes by 3 phases.

Phase 1

Implement autobatch on the client-side

ćœšćźąæˆ·ç«ŻäŸ§ćźžçŽ° autobatch

æ­€é˜¶æź”çš„ćźžçŽ°ćŻčç”šæˆ·ćźŒć…šć±è”œïŒŒæ— æ„ŸçŸ„ă€‚ç”±äșŽ MessageBatch ć‘é€æ—¶ïŒŒèż”ć›žçš„ sendResult äž­äŒšć°†æŻäž€æĄæ¶ˆæŻçš„ msgId ç”šé€—ć·æ‹ŒæŽ„è”·æ„ïŒŒćˆ†ć‰ČćŽćłćŻćŸ—ćˆ°æŻäž€æĄæ¶ˆæŻć„è‡Ș的 msgId。

Phase 2

Enhance the ability of MessageBatch to support multiple partitions 汞ćŒș MessageBatch çš„èƒœćŠ›ïŒŒäœżć…¶æ”ŻæŒäžćŒćˆ†ćŒșçš„æ¶ˆæŻäž€è”·æ‰“ćŒ…

æ­€é˜¶æź”çš„ćźžçŽ°æŻ”èŸƒé€‚ç”šäșŽæ™źé€šäžšćŠĄæ¶ˆæŻçš„ć‘é€ïŒŒèƒœć€§ć€§æé«˜ćžćé‡ïŒŒæ­€æ—¶çš„ msgId 撌 Phase1 çš„æƒ…ć†”äž€è‡Žă€‚

Phase 3

Increase BatchConsumerQueue so that messages sent in the same batch share one msgId 汞抠 BatchConsumerQueue ïŒŒäœżćŒäž€æ‰čć‘é€çš„æ¶ˆæŻć…±ç”šäž€äžȘ msgId

æ­€é˜¶æź”çš„ćźžçŽ°æŻ”èŸƒé€‚ç”šäșŽ streaming ćœșæ™ŻïŒŒé’ˆćŻčäșŽç‰č漚戆ćŒșçš„æ¶ˆæŻć‘é€ïŒŒæ­€æ—¶ćŒäž€æ‰čć‘é€æ¶ˆæŻæ‹„æœ‰ćŒäž€äžȘ msgId

Rejected Alternatives

How does alternatives solve the issue you proposed?

Manual batch sending by users.

ç”šæˆ·æ‰‹ćŠšæ‰čé‡ć‘é€æ¶ˆæŻ

Pros and Cons of alternatives

Pros: higher throughput.

Cons: It is not convenient to use, users need to understand the details.

䌘ç‚čïŒšé«˜ćžć

çŒșç‚čïŒšäœżç”šäžć€Ÿć‹ć„œïŒŒç”šæˆ·éœ€èŠäș†è§Łć…·äœ“ç»†èŠ‚ïŒˆæŻ”ćŠ‚äžćŻæ‰“ćŒ…é‡èŻ•æ¶ˆæŻă€ćźšæ—¶æ¶ˆæŻäž”ćż…éĄ»ćŒtopic撌waitStoreMsgOk

Why should we reject above alternatives

Users are still allowed to manually send messages in batches, and when the send interface is called, the incoming MessageBatch will be sent directly.

ç”šæˆ·çŽ°ćœšäŸç„¶ćŻä»„æ‰‹ćŠšć‘é€æ‰čé‡æ¶ˆæŻïŒŒćœ“è°ƒç”š send æŽ„ćŁć…„ć‚äžș MessageBatch æ—¶ć°†ç›ŽæŽ„ć‘é€ïŒŒäžć—æœŹæŹĄćŠŸèƒœćœ±ć“

Clone this wiki locally