improve dequeue performances with r/sqlite #28
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.
improve dequeue performances with r/sqlite
iwrr
(interleaved weighted round robin)map[string]int
inQueueConfig
(replaced with a constructor)De-queueing vs Queues Priority Types
The asynq
processor
is initialised with queues, each of them has a priority integer.The processor works by polling these queues, calling the
Dequeue
function of thebroker
The broker loops through the list, returning a task from the first queue that has one ready.
So far, there were 2 priority types (or mode) used in asynq:
strict
: in strict mode theqnames
parameter is the list of names of the queues ordered following the priority of the queues.With this mode, tasks in lower priority queues are dequeued only when higher priority queues are empty.
We never use this mode.
lenient
: in this mode the list of queue names are ordered 'statistically' with priorities.The frequency at which queues are at the head of the list is proportional to their priority.
Performances
These performance tests are run by enqueuing 1000 to 10000 tasks at a given rate and looking at the time it takes to have the task dequeued.
Two broker are tested
redis
(running locally) andsqlite
, which is our target.Three tests are shown (with the name of the corresponding test in code):
TestSingleQueueAloneAtRate
): configuration has one single queueTestSingleQueueAtRate
): configuration has multiple queues. The test enqueues in the higher priority queue only.TestAllQueuesAtRate
): configuration has multiple queues and the test enqueues in all of them.To make tables more readable, the results below only show some of the tested rates with the more relevant numbers.
Note on enqueuing rate
alone
Queues configuration has a single queue
Dequeue-ing time (millis) -
lenient
modesingle
Queues configuration
Only
q5
is usedDequeue-ing time (millis) -
lenient
modeall
Queues configuration
All queues are used
Dequeue-ing average time (millis) -
lenient
moderedis
sqlite
IWRR
The previous results show that even when not used the presence of other queues is sufficient to decrease performances
The reason for degraded performances is the time a single dequeue request takes with sqlite and the number of requests needed with the
lenient
mode.To solve the issue we use the
iwrr
mode coupled with buffered dequeue-ing (available only with sqlite):iwrr
is Interleaved Weighted Round Robin described in this Wikipedia articleWhen using buffered dequeue, the processor takes care of limiting the size of the buffer according to:
concurrency
of the queueconcurrency
of the processor. When the number of available active workers decreases, thesize allowed to the dequeue buffer is proportional to the priority of the queue.
performances
alone
single
all (avg ms)
Note that the max dequeue-ing time never exceeded 100ms in this test, for all queues.