Skip to content

Commit 9db369a

Browse files
committed
draft
1 parent 8117972 commit 9db369a

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

doc/platform/sharding/vshard_admin.rst

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,90 @@ In a router application, you can define the ``put`` function that specifies how
551551

552552
Learn more at :ref:`vshard-process-requests`.
553553

554+
.. _vshard-deduplication:
555+
556+
Deduplication of non-idempotent requests
557+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
558+
559+
**Idempotent requests** produce the same result every time they are called.
560+
For example, a data read request or a multiplication by one are idempotent.
561+
Increment by one is an example of a non-idempotent operation.
562+
When such an operation is applied again, the value for the field will be increased by 2 instead of 1.
563+
564+
.. note::
565+
566+
Any write requests that are planned to be executed repeatedly should be idempotent.
567+
The idempotency of such operations ensures that the change from the operation will be applied **only once**.
568+
569+
Re-invoking queries
570+
571+
A query may need to be re-executed if an error occurs on the server or client side.
572+
In this case:
573+
574+
- Read requests can be executed repeatedly. To do this, the method
575+
[vshard.router.call()](https://www.tarantool.io/ru/doc/latest/reference/reference_rock/vshard/vshard_router/#router-api-call)
576+
in the `read` mode (`mode=read`) uses the `request_timeout` parameter (available since `vshard` 0.1.28).
577+
The `request_timeout` and `timeout` parameters must be passed together, observing the following condition:
578+
579+
For example, if ``timeout = 10``, and ``request_timeout = 2``,
580+
then within 10 seconds the router is able to make up to 5 attempts to contact (2 seconds each) with a request to different replicas,
581+
until the request finally succeeds.
582+
583+
- Write requests ([vshard.router.callrw()](https://www.tarantool.io/ru/doc/latest/reference/reference_rock/vshard/vshard_router/#router-api-callrw))
584+
in general **cannot be re-executed** without checking that the request has not been applied before.
585+
Lack of such a check may lead to duplicate records or unplanned data changes.
586+
587+
For example, a client has sent a request to the server and is waiting for a response within a specified time.
588+
If the server sends a response about successful execution after this time has elapsed, the client will receive an error and when
589+
re-sending the request without additional checking, the operation may be applied twice.
590+
591+
A write request can be re-executed without a check only if the error occurred on the server side --
592+
for example, `ER_READONLY`.
593+
594+
Methods of deduplicating queries
595+
596+
To ensure idempotency of write queries, such as data insert, update, and upsert, as well as autoincrement,
597+
it is necessary to implement a check in the code that the query is being used for the first time.
598+
599+
For example, when adding a new tuple to a space, a unique key by which the insertion is performed can be used for checking.
600+
In such a query within a single transaction:
601+
602+
1. It is checked whether there is a tuple with the key `key` in the `bands` space.
603+
2. If there is no record with such a key in the space, the tuple is inserted.
604+
605+
.. code-block:: lua
606+
607+
box.begin()
608+
if box.space.bands:get{key} == nil then
609+
box.space.bands:insert{key, value}
610+
end
611+
box.commit()
612+
613+
For tuple update requests, a separate _deduplication_ space can be created, in which the query IDs will be saved.
614+
_deduplication_ space is a user space that contains a list of unique identifiers.
615+
Each such identifier corresponds to one executed query.
616+
This space can have any name, in the example it is called `deduplication`.
617+
618+
In the example below, within a single transaction:
619+
620+
1. The `deduplication` space is checked for the presence of the `deduplication_key` request ID.
621+
2. If there is no such ID, this ID is added to the deduplication space.
622+
3. The request then increments the specified field in the `bands` space by one.
623+
624+
This approach ensures that each data modification request will be executed **only once**.
625+
626+
.. code-block:: lua
627+
628+
function update_1(deduplication_key, key)
629+
box.begin()
630+
if box.space.deduplication:get{deduplication_key} == nil then
631+
box.space.deduplication:insert{deduplication_key}
632+
box.space.bands:update(key, {{'+', 'value', 1 }})
633+
end
634+
box.commit()
635+
end
636+
637+
554638
.. _vshard-maintenance:
555639

556640
Sharded cluster maintenance

0 commit comments

Comments
 (0)