[fix] [broker] Fix reader can not get any messages but hasMessageAvailable always return true#18808
Closed
poorbarcode wants to merge 4 commits intoapache:masterfrom
Closed
[fix] [broker] Fix reader can not get any messages but hasMessageAvailable always return true#18808poorbarcode wants to merge 4 commits intoapache:masterfrom
poorbarcode wants to merge 4 commits intoapache:masterfrom
Conversation
…lable always return true
Contributor
Author
|
I will push another PR to solve this issue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Context
compacted topicinstead oforiginal topicif the task-compaction done, and read messages fromoriginal topicif task-compaction is not done.ksent to a topic is null, the compactor will mark all messages for that key as deleted.consumer.getLastMessageId:managedLedger.lastConfirmPositionif not compacted.managedLedger.lastConfirmPosition.reader.hasMessageAvailablelastReceiveMessageIdlastMessageIdInBroker, it could bemanagedLedger.lastConfirmPosition, it could be less thanmanagedLedger.lastConfirmPosition.lastReceiveMessageId<lastMessageIdInBrokerPossible issue scenarios.
Based on the above context, there are two scenarios in that a reader can not get any messages but
reader.hasMessageAvailablealways returnstrue:k1,v1}, {k2,v2}, {k2,null}][{3:0}, {3:1}, {3:2}]consumer.getLastMessageIdwill get{3:2}, and cache it aslastMessageIdInBroker.{3:1}and{3:2}, because the data of this message with keyk2sent to a topic is null.{3:0}, and mark the last received message-id is{3:0}, akalastReceiveMessageIdreader.hasMessageAvailablewill gettrue, becauselastReceiveMessageId < lastMessageIdInBrokerYou can reproduce scenario-1 by the test
CompactionTest.testRaceConditionByCompactionAndGetLastMessageIdwith@DataProvider-6.k1,v1}, {k2,v2}, {k2,null}]{position=3:0, batchSize=3}consumer.getLastMessageIdwill get{3:0:-1:2}, and cache it aslastMessageIdInBroker.{3:0:-1,1}and{3:0:-1,2}ascompactedOut, because the data of this message with keyk2sent to a topic is null.{3:0}, when the consumer unpacks the package, the two messages{3:0:-1,1}and{3:0:-1,1}are lost because they have been markedcompactedOut. Mark the last received message-id is{3:0,-1,0}, akalastReceiveMessageIdreader.hasMessageAvailablewill gettrue, becauselastReceiveMessageId < lastMessageIdInBrokerYou can reproduce scenario-2 by the test
CompactionTest.testRaceConditionByCompactionAndGetLastBatchMessageId2with@DataProvider-5(High light) We should discuss about the correctness of the behavior
scenario-3-ivk1,v1}, {k2,v2}, {k2,null}]{position=3:0, batchSize=3}{3:0:-1,1}and{3:0:-1,2}ascompactedOut, because the data of this message with keyk2sent to a topic is null.consumer.getLastMessageIdwill get{3:0:-1:2}, and cache it aslastMessageIdInBroker. After task-compaction, should it return{3:0:-1:0}? You can reproduce it by testGetLastMessageIdCompactedTest.testGetLastMessageIdAfterCompactionEndWithNullMsg2with@DataProvider-true{3:0}, when the consumer unpacks the package, the two messages{3:0:-1,1}and{3:0:-1,1}are lost because they have been markedcompactedOut. Mark the last received message-id is{3:0,-1,0}, akalastReceiveMessageIdreader.hasMessageAvailablewill gettrue, becauselastReceiveMessageId < lastMessageIdInBrokerYou can reproduce scenario-3 by the test
CompactionTest.testReadMessageAfterCompactionWithBatchFuture2with@DataProvider-6Modifications
1. Fix issue
In the following two scenarios, the consumer will read the message from the
original topic, even if read-compacted is enabled and task-compaction is done. And will move thecursor.markDeletedPositiontocompactionHorizon - 1before reading messages.compacted topic2. Add tests
getLastMessageId enabled read-compacted.The rejected plans
Plan 1
If task-compaction is not done, return the first non-empty message instead of
managedLedger.lastConfirmPositionwhen callinggetLastMessageId.Why rejected: If sending messages like below, we can't easily get that which message was the last one not deleted.
The last non-empty message is
{key = "k1", value = "v2"}, but it has been deleted by the third message.Plan 2
Diff with current changes: read messages from
original topiconly if the last message isnull.Why rejected: If the last message is a batch message, we can not easily know if the last message in this batch is empty. Rather than unpack by the broker, do unpack messages by the client.
Plan 3
Improve plan 2: If the last message is a batch message, do not execute
rebatchMessage, so that the messages in the last entry will not be marked ascompactedOut; then the client will not lose the empty messages.Why rejected: When executing task-compaction, it's impossible to easily determine which message is the last one to keep, as in the example below:
Documentation
docdoc-requireddoc-not-neededdoc-completeMatching PR in forked repository
PR in forked repository: