Repository navigation
[Bug] parseMessageMetadata error when broker entry metadata enable with high loading #22601
Description
Search before asking
- I searched in the issues and found nothing similar.
Read release policy
- I understand that unsupported versions don't get bug fixes. I will attempt to reproduce the issue on a supported version of Pulsar client and Pulsar broker.
Version
- 3.2.2
- 3.1.2
Minimal reproduce step
publish event in about 6k QPS and 100Mbits/sec
with metaData
BatcherBuilder.KEY_BASED mode
and producer and send message by high concurrent/parallel producer process.
it happens only in almost real time consumer (almost zero backlog)
What did you expect to see?
no lost event
What did you see instead?
could see error log in broker and show
Failed to peek sticky key from the message metadata
it look like thread safe issue, because it happen randomly.
in 1M events, it only happen few times but the consumer will lose few events
Anything else?
the error similar to
#10967 but I think it's different issue.
the data in bookkeeper is correct.
I can download the event from bookkeeper and parse it successfully.
or consume the same event few minutes later and it could consume successfully.
but all subscriptions will get the same error in the same event in real time consumer(zero backlog).
I have traced source code.
it happens in
PersistentDispatcherMultipleConsumers.readEntriesComplete -> AbstractBaseDispatcher.filterEntriesForConsumer
-> Commands.peekAndCopyMessageMetadata
and I also print the ByteBuf contents,
it's I could clearly see the data isn't the same in bookkeeper
in normal event , the hex code usually start by 010e (magicCrc32c)
0000000 010e 9529 5fbc 0000 0a03 3a0a 6e69 7267
in one of our error event, the bytebuf have about 48 bytes strange data, then continue with normal data
0000000 0000 a610 0000 0000 0200 7239 0000 0000 <== from here
0000020 0200 1339 0000 0000 ea17 a8b0 8b8e fa5e
0000040 2af0 2675 f645 1623 d17e dc34 526d ef44 <=== until here is garbage
0000060 010e 9529 5fbc 0000 0a03 3a0a 6e69 7267 <== from here is normal data
this is just an example, but sometimes the first few bytes are correct and something wrong after few bytes later.
I am still trying to debug when and how the ByteBuf returns incorrect data, and why it only happens during stress testing. It is still not easy to reproduce using the perf tool, but we can 100% reproduce it in our producer code.
Does anyone have any idea what could be causing this issue, and any suggestions on which library or class may have potential issues? Additionally, any suggestions on how to debug this issue or if I need to print any specific information to help identify the root cause would be appreciated. Thank you.
Are you willing to submit a PR?
- I'm willing to submit a PR!
Activity
lhotari commentedon Apr 26, 2024
@semistone Just wondering if this could be related to apache/bookkeeper#4196?
There might are also other recent ByteBuf retain/release fixes such as #22393 .
In Bookkeeper, there's apache/bookkeeper#4289 pending release and apache/bookkeeper#4293 is pending review.
semistone commentedon May 1, 2024
we still try to compare what's the different between our producer and perf tool
will feedback later once we have any conclusion.
semistone commentedon May 2, 2024
@lhotari
we do many tests
current broker setting is
and producer setting (small batch message and big max bytes)
payload
98% < 3K bytes
2% between 10-20K bytes
then it will show that error and publish throughput isn't good.
but if we change to
and filter all data bigger than 15K bytes
then that error disappear
so we decide to create
one batch publisher to publish data < 15000 bytes
and one chunk publisher to publish data >= 15000 bytes
then it worked and performance is also better than previous test
we still don't known why
but at least we have workaround solution now.
I don't how which batch producer configuration could fix this errors.
if you have any suggestions, we will still try it .
and we also publish in multi thread programs,
seems like it's not directly related to loading but related to payload size
but maybe if the publish rate is low, it's more difficult to reproduce .
we also tried to reproduce by perf tool but it didn't always happen.
thanks
semistone commentedon May 8, 2024
I tried to upgrade to bookkeeper 4.17.0
but still have the same issue :(
lhotari commentedon May 8, 2024
@semistone Please share a way how to reproduce it. It's not a problem if it's not always consistent. Fixing this issue will be a lot easier if there's at least some way to reproduce.
lhotari commentedon May 8, 2024
@semistone Thanks for testing this.
semistone commentedon May 8, 2024
I will try to reproduce in perf tool.
lhotari commentedon May 8, 2024
@semistone since you have some way to reproduce this in your own tests, would you be able to test if this can be reproduced with
dispatcherDispatchMessagesInSubscriptionThread=false?pulsar/conf/broker.conf
Lines 435 to 436 in 80d4675
It impacts this code:
pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
Lines 659 to 681 in 188355b
semistone commentedon May 8, 2024
I almost could reproduce by perf tool
when very few payload > 30K bytes. others are 3K bytes
then
error happen when messageKeyGenerationMode=random
if without messageKeyGenerationMode, then error disappear
I guess in batch mode, payload size have some restriction.
let me confirm again tomorrow to make sure I didn't make any stupid mistake during my test.
semistone commentedon May 9, 2024
Hi @lhotari
I update perf tool in
https://github.com/semistone/pulsar/tree/debug_ssues_22601
it only include one commit which modify PerformanceProducer.java to include
big payload ( -bp 5 means 5 percent big payload)
and BatcherBuilder.KEY_BASED (-kb)
my consumer command is
and producer command is
that error happen when
Batch builder is KEY_BASE
with random event key
and few big payload (in my environment 3% could reproduce 10% will crash producer)
in my test
I use normal payload 2K bytes , big payload 20K bytes
if I removed any above conditions, that error will either reduced or disappear.
when it happen it will have WARN message in pulsar-broker.log
unfortunately I can't preproduce in docker, I guess docker standalone is different from my pulsar cluster.
my pulsar cluster is
almost default config but with TLS auth in broker/bookkeeper/zookeeper.
Please help to check it, if have any problem to reproduce this issue in your environment,
then I will try to simplify my pulsar cluster to reproduce it.
Thanks
semistone commentedon May 9, 2024
I tested, still the same
lhotari commentedon May 9, 2024
@semistone Thanks for testing. That tells that it's not related to switching the thread in
pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
Lines 659 to 681 in 188355b
semistone commentedon May 17, 2024
@lhotari
I am checking when that byteBuf went wrong
and in
OpAddEntry.java
I verify data when construct this object and save original data
and during run(), I try to compare and print bytebuf
it show
the bytebuf object haven't changed, but the data in bytebuf have changed.
it seem like the first few bytes(about 20) will be overwrited and rest of the data is still ok
and it's PooledSlicedByteBuf and PooledUnsafeDirectByteBuf
do you have any idea how to find who change the data inside bytebuf ?
semistone commentedon May 17, 2024
I also test again
if publish payload always 20K, it won't happen
only happen when normal is 2K but some data bigger than 16K( sound like netty receive buffer size but I also try to increase it)
and about 1000 qps
I also checked the data again
the wrong data look exactly like been overwrited by tail of previous payload
and it not related to batch mode
it happened when disable batch mode
43 remaining items
lhotari commentedon May 27, 2024
I can confirm that this issue reproduces with https://github.com/lhotari/pulsar-playground/tree/master/issues/issue22601/standalone_env / https://github.com/semistone/personal_notes/blob/main/pulsar_issue_22601/Test.md also with Netty 4.1.111.Final-SNAPSHOP and Bookkeeper 4.16.6-SNAPSHOT (with PR 4293 included). This is a different issue than what I reproduced in my microk8s based repro.
lhotari commentedon May 27, 2024
@semistone Your problem is caused by invalid TLS configuration. When TLS is enabled between Broker and Bookkeeper, you must set
bookkeeperUseV2WireProtocol=falseinbroker.conf. In the autorecovery process, it is necessary to setuseV2WireProtocol=falseinbookkeeper.conf, if there's TLS enabled for autorecovery.It's possible that there's isn't much documentation to assist with this.
lhotari commentedon May 27, 2024
I found apache/bookkeeper#2071 and apache/bookkeeper#2085 which seem to indicate that running with
bookkeeperUseV2WireProtocol=trueis supported. However, I don't think that it has ever been stable when TLS is enabled between broker and bookkeeper. In the Apache Pulsar Helm chart, the chart will setbookkeeperUseV2WireProtocol=falsewhen TLS is enabled between broker and bookkeeper.https://github.com/apache/pulsar-helm-chart/blob/3ecc2baab809389ede5e53f4ecf518fab0f13dad/charts/pulsar/templates/broker-configmap.yaml#L180-L196
lhotari commentedon May 27, 2024
Previous comment about bookkeeperUseV2WireProtocol #21421 (comment)
lhotari commentedon May 27, 2024
It looks like there's a feature that enables V3 protocol using a separate client when V2 is configured: apache/bookkeeper#2085 . As mentioned in the previous comments, I don't think that this has ever been proven to be stable when TLS is enabled.
semistone commentedon May 28, 2024
@lhotari
Thanks to point out that config issue
I tested and verified it worked.
also talk about our release history.
actually we have notice that issue #21421 during our pre release load test and since that error logs have ledger id and entry id
and it happens about 4 times during about 10M events.
so we could still recover the data from bookkeeper manually or by auto fix tool.
and we have about 10 consumers, only 1 consumer is too slow to consume data from bookkeeper
so only one consumer been impacted and we could still wait bookkeeper side to fix that issue.
and after upgrading bookkeeper version, it seems improved.
but this error, the data in bookkeeper is correct. that why at beginning we didn't aware it's bookkeeper client issue
it only happened about 10 times in 1M events if relative higher QPS.
and there is no ledger/entry id in error logs.
so it's impossible for us to fix the data.
and it mainly impact real time consumer
so we don't have choice but rollback our release.
so I will use that settings in our broker setting
and I will suggest to print ledger/entry id in case of that happen again (I could create PR if it's ok)
then at least user could still re publish the data from bookkeeper.
and I think it still need to report to bookkeeper team.
seems those issues are already closed, I will create issue in bookkeeper tomorrow if there is no existed ticket to trace this issue.
I will try to understand bookkeeper's code if I have time :)
I already debug this issue for one month.
Thanks for helping us.
lhotari commentedon May 28, 2024
@semistone It seems that V2 should be supported also when using TLS. The downside of using V3 is that it's not very efficient and will add a lot of GC overhead. However some bug gets triggered and that's the reason why V3 is more stable when TLS is enabled between brokers and bookies.
I was reviewing code for reference count bugs in Pulsar and I did find an issue in RangeCache (the broker cache implementation). I'll follow up with a PR to fix the issue soon. It's not related to the bookkeeper protocol version at all.
lhotari commentedon May 28, 2024
RangeCache race condition fix: #22789
lhotari commentedon May 28, 2024
I have made a fix to bookkeeper which fixes the issue: apache/bookkeeper#4404 .
I tested with Pulsar 3.2.3 with bookkeeper.version set to 4.16.6-SNAPSHOT. Before compiling that locally, I compiled Bookkeeper branch-4.16 with PR 4404 changes included (branch-4.16 backport available at https://github.com/lhotari/bookkeeper/commits/lh-fix-tls-stability-with-V2-branch-4.16/).
Compiling Bookkeeper 4.16.6-SNAPSHOT locally with apache/bookkeeper#4404 changes.
Compiling local Pulsar v3.2.3 with Bookkeeper 4.16.6-SNAPSHOT (passing
-Dbookkeeper.version=4.16.6-SNAPSHOTto maven build)semistone commentedon May 29, 2024
@lhotari
I tested in standalone server. and it's all good.
here is my test report
https://github.com/semistone/personal_notes/blob/main/pulsar_issue_22601/20240528Test.md
I will deploy to our cluster and test again few days later.
semistone commentedon Jun 3, 2024
@lhotari
I had tested
pulsar 3.2.3 + bookkeeper 4.16.6-SNAPSHOT.jar + netty buffer 4.1.111.Final-SNAPSHOT
and I think this issue had been fixed.
I will test more scenario
Thanks.
Optimize wrap buffer cumulation in SslHandler and don't mutate input …
Optimize wrap buffer cumulation in SslHandler and don't mutate input …