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]intinQueueConfig(replaced with a constructor)De-queueing vs Queues Priority Types
The asynq
processoris initialised with queues, each of them has a priority integer.The processor works by polling these queues, calling the
Dequeuefunction of thebrokerThe 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 theqnamesparameter 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) -
lenientmodesingle
Queues configuration
Only
q5is usedDequeue-ing time (millis) -
lenientmodeall
Queues configuration
All queues are used
Dequeue-ing average time (millis) -
lenientmoderedis
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
lenientmode.To solve the issue we use the
iwrrmode coupled with buffered dequeue-ing (available only with sqlite):iwrris 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:
concurrencyof the queueconcurrencyof 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.