You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jira@kafka.apache.org by "Krzysztof Piecuch (Jira)" <ji...@apache.org> on 2023/11/22 14:36:00 UTC
[jira] [Created] (KAFKA-15884) Reduce lock contention when cleaning topics
Krzysztof Piecuch created KAFKA-15884:
-----------------------------------------
Summary: Reduce lock contention when cleaning topics
Key: KAFKA-15884
URL: https://issues.apache.org/jira/browse/KAFKA-15884
Project: Kafka
Issue Type: Improvement
Components: log cleaner
Reporter: Krzysztof Piecuch
Somewhat similar to KAFKA-14213, there are a couple of subroutines which require the same lock which results in throttling compaction speed and limits parallelism.
There's a couple of problems here:
# LogCleanerManager.grabFilthiestCompactedLog - iterates through a list of partitions multiple times, all of this while holding a lock
# LogCleanerManager.grabFilthiestCompactedLog doesn't cache anything and returns only 1 item at a time - method is issued every time a cleaner thread asks for a new partition to compact
# LogCleanerManager.checkCleaningAborted - a quick check which:
## shares a lock with grabFilthiestCompactedLog
## is executed every time a LogCleaner reads bufsize data to compact
# LogCleaner's bufsize is limited to 1G / (number of log cleaner threads)
Here's the scenario where this design falls short:
* I have 15k partitions
* all of which need to be compacted fairly often but it doesn't take a lot of time to compact them
* Most of the cputime spent by cleaner threads is spent on grabFilthiestCompactedLog
** so the other cleaners can't do anything since they need to acquire a lock to read data to compact as per 3.1. and 3.2.
** because of 4. log cleaners run out of work to do as soon as grabFilthiestLog is called
* Negative performance scaling - increasing # of log cleaner threads decreases log cleaner's bufsize which makes them hammer the lock mentioned in 3.1. and 3.2. more often
I suggest:
* making LogCleanerManager to use more fine-grained locking (ex. RW lock for checkCleaningAborted data structures) to decrease the effect of negative performance scaling
* making LogCleanerManager.grabFilthiestLog faster on average:
** we don't need grabFilthiestLog to be 100% accurate
** we can try caching candidates for "filthiestLog" and re-calculate the cache every 1 minute or so.
** change the algorithm to probabilistic sampling (get 100 topics and pick the worst one?) or even round-robin
* Alternatively we could make LogCleaner's bufsize to allow values higher
--
This message was sent by Atlassian Jira
(v8.20.10#820010)