Skip to content

Commit f2bb86e

Browse files
committed
utube: fix slow take on busy utubes
If some of the utube for tasks at the top of the queue were busy most of the time, `take` would slow down for every other task. This problem is fixed by creating a new space `space_ready`. It contains first task with `READY` status from each utube. This solution shows great results for the stated problem, with the cost of slowing the `put` method (it is ~3 times slower). Thus, this workaround is disabled by default. To enable it, user should set the `storage_mode = queue.driver.utube.STORAGE_MODE_UTUBE_READY_SPACE` as an option while creating the tube. As example: ```lua local test_queue = queue.create_tube('test_queue', 'utube', {temporary = true, storage_mode = queue.driver.utube.STORAGE_MODE_UTUBE_READY_SPACE}) ``` Part of #228
1 parent aa7c092 commit f2bb86e

File tree

7 files changed

+666
-119
lines changed

7 files changed

+666
-119
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Added
11+
- `storage_mode` option for creating a `utube` tube (#228). It enables the
12+
workaround for slow takes while working with busy tubes.
13+
1014
### Fixed
1115

1216
- Stuck in `INIT` state if an instance failed to enter the `running` mode
1317
in time (#226). This fix works only for Tarantool versions >= 2.10.0.
18+
- Slow takes on busy `utube` tubes (#228). The workaround could be enabled by
19+
passing the `storage_mode = "utube_ready_space"` option while creating
20+
the tube.
1421

1522
## [1.3.3] - 2023-09-13
1623

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,48 @@ The main idea of this queue backend is the same as in a `fifo` queue:
165165
the tasks are executed in FIFO order.
166166
However, tasks may be grouped into sub-queues.
167167

168+
It is advised not to use `utube` methods inside transactions with
169+
`read-confirmed` isolation level. It can lead to errors when trying to make
170+
parallel tube methods calls with mvcc enabled.
171+
168172
The following options can be specified when creating a `utube` queue:
169173
* `temporary` - boolean - if true, the contents of the queue do not persist
170174
on disk
171175
* `if_not_exists` - boolean - if true, no error will be returned if the tube
172176
already exists
173177
* `on_task_change` - function name - a callback to be executed on every
174178
operation
179+
* `storage_mode` - string - one of
180+
* `queue.driver.utube.STORAGE_MODE_DEFAULT` ("default") - default
181+
implementation of `utube`
182+
* `queue.driver.utube.STORAGE_MODE_UTUBE_READY_SPACE`
183+
("utube_ready_space") - allows processing `take` requests faster, but
184+
by the cost of `put` operations speed. Right now this option is enabled
185+
only for `memtx` engine.
186+
187+
Here is a benchmark comparison of these two modes:
188+
* Benchmark for simple `put` and `take` methods. 30k utubes are created
189+
with a single task each. Task creation time is calculated. After that
190+
30k consumers are calling `take` + `ack`, each in the separate fiber.
191+
Time to ack all tasks is calculated. The results are as follows:
192+
193+
| | put (30k) | take+ack |
194+
|---------|-----------|----------|
195+
| default | 180ms | 1.6s |
196+
| ready | 270ms | 1.7s |
197+
* Benchmark for the busy utubes. 10 tubes are created.
198+
Each contains 1000 tasks. After that, 10 consumers are created (each works
199+
on his tube only, one tube — one consumer). Each consumer will
200+
`take`, then `yield` and then `ack` every task from their utube
201+
(1000 tasks each).
202+
After that, we can also run this benchmark with 10k tasks on each utube,
203+
100k tasks and 150k tasks. But all that with 10 utubes and 10 consumers.
204+
The results are as follows:
205+
206+
| | 1k | 10k | 50k | 150k |
207+
|---------|-------|------|------|-------|
208+
| default | 53s | 1.5h | 100h | 1000h |
209+
| ready | 450ms | 4.7s | 26s | 72s |
175210

176211
The following options can be specified when putting a task in a `utube`
177212
queue:

queue/abstract.lua

+5-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,11 @@ function tube.drop(self)
297297

298298
local space_name = tube[3]
299299

300-
box.space[space_name]:drop()
300+
if self.raw.drop ~= nil then
301+
self.raw:drop()
302+
else
303+
box.space[space_name]:drop()
304+
end
301305
box.space._queue:delete{tube_name}
302306
-- drop queue
303307
queue.tube[tube_name] = nil

0 commit comments

Comments
 (0)