redis Affairs (redis additional feature articles)

Affairs

Redis transaction function allows the user to wrap up a plurality of commands, and then one time, all the commands sequentially wrapped.

In the process of transaction execution, the server will not interrupt the transaction and change requests to execute other commands, command transaction only after all parcels have been finished, the server will request to process other commands.

Transaction Example of use

Now, let us assume that SETEX command does not exist in Redis, and does not support the SET command parameters EX seconds, if we want to achieve a SETEX own command, then we may use the following code:

 def SETEX(key, seconds, value):
 SET key value
 EXPIRE key seconds

In general, this can be achieved homemade SETEX command to set the key and set the effect of production time, but the homemade SETEX there is a flaw: If the server crashes after the successful implementation of the SET command and save the data, then the command will EXPIRE no way to execution.

At this time, although we have set the key, but did not set the expiration time for the key , if we do not find that, then this should have been deleted on a regular basis would have been left in the key database inside the memory occupied by the program even after the error cause .

Transaction command

In order to avoid the above mentioned encounter, we need to use Redis transaction capabilities through the transaction, we can make Redis multiple commands at once, and in order to ensure that the transaction or to execute all, or to have a It is not executed.
Here Insert Picture Description

Begin transaction

MULTI
start a transaction. After this command is executed, all commands sent by the client for the database or database keys will not be executed immediately, but are put into a transaction queue inside, and return QUEUED means that the command into the team.

redis> MULTI # 开始一个事务
OK
redis> SET msg "hello world" # 将这个 SET 命令放入事务队列
QUEUED
redis> EXPIRE msg 10086 # 将这个 SET 命令放入事务队列
QUEUED

Complexity is O (1).

Abandon the transaction

DISCARD
cancel the transaction, giving up all the commands in the transaction queue. Complexity is O (1).

 redis> MULTI
 OK
 redis> SET msg "hello world"
 QUEUED
 redis> EXPIRE msg 10086
 QUEUED
 redis> DISCARD # 事务已被取消
 OK
 redis> SET msg "hello world"
 OK
The enforcement branch

EXEC
in accordance with the order of command is queued to the transaction queue, all the commands in the transaction queue.
Complexity of the command queue and complexity of all commands.
The return value is a command list, the list contains all the transaction queue to be executed return value of the command.

redis> MULTI 
OK
redis> SET msg "hello world"
QUEUED
redis> EXPIRE msg 10086
QUEUED
redis> EXEC
1) OK # SET 命令的返回值
2) (integer) 1 # EXPIRE 命令的返回值
Use transaction security guarantee operation

SETEX homemade defined before, with security flaws:

def SETEX(key, seconds, value):
 SET key value
 EXPIRE key seconds # 如果服务器在 SET 命令执行之后崩溃,那么 EXPIRE 将无法执行
使用事务实现的自制 SETEX 的定义,没有安全缺陷,服务器保证要么两个命令都执行,要么就两个命令都不执行:
def SETEX(key, seconds, value):
 MULTI
 SET key value
 EXPIRE key seconds
 EXEC
The difference between the pipeline and the transaction

Here Insert Picture Description

(PIPELINE_START)
SET msg “hello world” # 这两条命令会被一起发送至服务器
EXPIRE msg 10086
(PIPELINE_END)
MULTI
SET msg “hello world” # 这两条命令会一起被服务器执行
EXPIRE msg 10086
EXEC

Optimistic locking

Use locks to ensure data correctness

Use optimistic locking to ensure data correctness

By using MULTI and EXEC, we can be multiple commands into a single transaction execution, to ensure that a transaction which either all commands are executed or not executed on a to prevent data corruption. But sometimes only the transaction still can not guarantee the accuracy of the data, this time we need to use optimistic locking function provided by Redis (Optimistic Locking).

For example, when introduced before the ordered collection we have said, Redis provides only ZINCRBY command elements were scores increment operator, but does not provide for the corresponding elements of self-score Less ZDECRBY command operations, in order to achieve our own ZDECRBY command, we might write the code like this:

def ZDECRBY(key, decrment, member):
 # 取得元素当前的分值
 old_score = ZSCORE key member
 # 使用当前分值减去指定的减量,得出新的分 值
 new_score = old_score - decrment
 # 为元素设置新分值,覆盖现有的分值
 ZADD key new_score member
ZDECRBY competitive conditions (1/2)

Although the above ZDECRBY achieve the effect of reducing the value of elements can be achieved, but this implementation contains a race condition when multiple clients simultaneously call ZDECRBY of the same element, this race conditions may occur.

For example, now assume an ordered set of scores salary peter element 4000, if both clients and perform ZDECRBY salary 500 peter ZDECRBY salary 300 peter to peter element, shown in the table on the situation may occur:
Here Insert Picture Description

ZDECRBY competitive conditions (2/2)

Under the right circumstances, peter elements of the original score of 4000, after being deducted 500 and 300, the score should be changed to 3200 fishes.

但是在上面的这个表中, 客户端 A 和客户端 B 先后对 peter 元素的分值进行减法操作, 并且客户端 A 的 ZADD 操作比客户端 B 的 ZADD 操作更早执行, 当客户端 B 执行 ZADD 时, 它不知道 peter 元素当前的分值已经出现了变化,导致它计算出的新分值 3700 已经过期了, 而是继续一味地进行设置, 使 得计算出现了错误。

WATCH 命令

为了消除 ZDECRBY 实现中的竞争条件, 我们需要用到 Redis 提供的 WATCH 命令, 这个命令需要在开始一个事务之前执行, 它接受任意多个键作为参数, 并对输入的键进行监视:
WATCH key [key …]
如果被监视的键在事务提交之前(也即是 EXEC 命令执行之前), 已经被其他客户端抢先修改了, 那么服务器将拒绝执行客户端提交的事务, 并返回 nil 作为事务的回复:

redis> WATCH msg # 监视键 msg
OK
redis> MULTI
OK
redis> SET msg "hello world" 
QUEUED
redis> EXEC # 在这个事务之前,已经有其他客户端对键 msg 进行了修改
(nil)
使用 WATCH 来防止竞争条件(1/3)

回到 ZDECRBY 的例子, 为了确保 ZDECRBY 执行时, ZADD 设置的新分值是正确的, 我们需要在 ZDECRBY 执行一开始时, 就使用 WATCH 监视输入的有序集合,并将修改操作 ZADD 添加到事务里面执行, 以下是修改后的 ZDECRBY 命令的实现:

def ZDECRBY(key, decrment, member):
 # 监视输入的有序集合
 WATCH key
 # 取得元素当前的分值
 old_score = ZSCORE key member
 # 使用当前分值减去指定的减量,得出新的分值
 new_score = old_score - decrment
 # 使用事务包裹 ZADD 命令
 # 确保 ZADD 命令只会在有序集合没有被修改的情况下执行
 MULTI
 ZADD key new_score member # 为元素设置新分值,覆盖现有的分值
 EXEC
使用 WATCH 来防止竞争条件(2/3)

在这个新的 ZDECRBY 执行时, 有两种情况可能会出现:

• 如果在程序执行期间, 输入的有序集合没有发生任何变化, 那么说明 ZADD 要修改的元素及其分值并没有变化, ZADD 可以正常地更新元素的分 值。

• 如果在程序执行期间, 输入的有序集合发生了变化, 那么程序要修改的元素可能已 经发生了变化, 这时服务器就会阻止事务执行, 使得 ZADD 无法执行, 从而防止竞争条件出现, 也避免了元素的分值被设置为错误的值。

使用 WATCH 来防止竞争条件(3/3)

For example, the following table lists two clients simultaneously ZDECRBY executed command, the client B because the effect of the command WATCH ZADD lead to failure of the command:
Here Insert Picture Description

Other related commands and optimistic locking

Here Insert Picture Description

redis> WATCH msg name fruits # 监视三个键
OK
redis> UNWATCH # 取消对上面三个键的监视
OK
The difference between the optimistic and pessimistic locking

Optimistic locking will be locked data for monitoring, multiple clients can simultaneously try to modify the data, which attempted first client will be successful, but after trying the client will fail.

Pessimistic locks only allow a client to modify the data, while other clients will need to wait for customers under revision after the end finished in order to try to get the right to modify.

For Redis frequently read and write operations, the use of optimistic locking to avoid client is blocked: When a client modifies data fails, it retries as long as you can, and this process does not require any wait.
Here Insert Picture Description

review

Review (1/2)

Services allows users to put multiple commands to the transaction queue inside, and then once all the commands transaction queue inside, and during the execution of a transaction request will not be interrupted by other command, the server will wait until all the commands inside transactions are after finished, before going to deal with other commands sent by the client request.
Command in a transaction they were all either executed or not executed on a.
Here Insert Picture Description

Review (2/2)

By using the database to monitor WATCH command key, it is possible to prevent the introduction of competition conditions while performing an operation.
Here Insert Picture Description

Published 252 original articles · won praise 151 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_39885372/article/details/104257625