LogScheduler: fix IO job starvation#906
Merged
MrAnno merged 4 commits intoaxoflow:mainfrom Jan 15, 2026
Merged
Conversation
alltilla
added a commit
to alltilla/axosyslog
that referenced
this pull request
Jan 14, 2026
Signed-off-by: Attila Szakacs <[email protected]>
fe4959e to
51624d9
Compare
alltilla
added a commit
to alltilla/axosyslog
that referenced
this pull request
Jan 14, 2026
Signed-off-by: Attila Szakacs <[email protected]>
51624d9 to
5051e33
Compare
syslogng_parallelized_assigned_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="0"} 614700
syslogng_parallelized_assigned_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="1"} 614661
syslogng_parallelized_assigned_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="2"} 614600
syslogng_parallelized_assigned_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="3"} 614600
syslogng_parallelized_processed_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="0"} 614513
syslogng_parallelized_processed_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="1"} 614500
syslogng_parallelized_processed_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="2"} 614500
syslogng_parallelized_processed_events_total{id="/home/alltilla/repos/axosyslog/build/install/etc/syslog-ng.conf:6:3",partition_index="3"} 614500
Signed-off-by: Attila Szakacs <[email protected]>
alltilla
added a commit
to alltilla/axosyslog
that referenced
this pull request
Jan 15, 2026
Signed-off-by: Attila Szakacs <[email protected]>
5051e33 to
b5a6e2e
Compare
Signed-off-by: Attila Szakacs <[email protected]>
We can have more partitions (IO jobs) (from one or multiple parallelize() calls) than number of cores/IO workers available. The LogScheduler correctly spreads the messages between partitions but we can only run a limited amount of IO jobs at the same time. The work() method is implemented in a way that during its run, new batches can be added to its workload. Also, it does not return if there is even one batch available for processing. If there is a big load of messages, IO jobs run indefinitely, or at least until new batches are no longer added to its queue. If we have some IO jobs scheduled, but not ran, new batches will still be added to the non-running jobs, but we only process batches from the running jobs. This happens until log-iw-size() number of logs are accumulated in the non-running jobs, which will cause the running jobs to not receive any more logs, thus eventually return, causing the previously non-running jobs to run finally. So the only thing that saves us from complete starvation is log-iw-size() and backpressure, which is not the intended behavior. We need to put a hard limit to the number of logs processed by one job run, so ivykis can work its magic and cycle between the scheduled IO jobs. We now count the number of logs processed in one work() run, and if it reaches a configurable limit, we finish the batch and return from work(). The new log-fetch-limit() option of parallelize() can change this limit from its default 1000 value. Signed-off-by: Attila Szakacs <[email protected]>
Signed-off-by: Attila Szakacs <[email protected]>
84d8eed to
04850eb
Compare
MrAnno
approved these changes
Jan 15, 2026
bazsi
approved these changes
Jan 15, 2026
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.
We can have more partitions (IO jobs) (from one or multiple
parallelize()calls) than number of cores/IO workers available.The
LogSchedulercorrectly spreads the messages between partitions, but we can only run a limited amount of IO jobs at the same time.The
work()method is implemented in a way that during its run, new batches can be added to its workload. Also, it does not return if there is even one batch available for processing. If there is a big load of messages, IO jobs run indefinitely, or at least until new batches are no longer added to its queue.If we have some IO jobs scheduled, but not ran, new batches will still be added to the non-running jobs, but we only process batches from the running jobs.
This happens until
log-iw-size()number of messages are accumulated in the non-running jobs, which will cause the running jobs to not receive any more logs, thus eventually return, causing the previously non-running jobs to run finally. So the only thing that saves us from complete starvation islog-iw-size()and backpressure, which is not the intended behavior.We need to put a hard limit to the number of logs processed by one job run, so ivykis can work its magic and cycle between the scheduled IO jobs. We now count the number of logs processed in one
work()run, and if it reaches a configurable limit, we finish the batch and return fromwork(). The newlog-fetch-limit()option ofparallelize()can change this limit from its default 1000 value.I have also added some level 4 metrics that can help debug
parallelize()errors.