Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redis:为什么Lua脚本将取代事务?_Redis - Fatal编程技术网

Redis:为什么Lua脚本将取代事务?

Redis:为什么Lua脚本将取代事务?,redis,Redis,交易文件说明: “我们可能会拒绝并最终删除交易”和“您需要的一切” 可以使用Redis事务,也可以使用脚本” 但这是真的吗?我觉得这有问题 在一个事务中,您可以观察多个变量,读取这些变量,并且根据这些变量的唯一状态,您可以在调用EXEC之前进行完全不同的写入。如果在中间时间内有任何东西干扰了这些变量的状态,EXEC将不执行事务。(允许您重试。这是一个完美的交易系统。) 评估脚本不允许您这样做。根据本页上的文档: “脚本作为纯函数…脚本的计算结果始终相同 Redis使用相同的输入数据编写具有相同

交易文件说明:

“我们可能会拒绝并最终删除交易”和“您需要的一切” 可以使用Redis事务,也可以使用脚本”

但这是真的吗?我觉得这有问题

在一个事务中,您可以观察多个变量,读取这些变量,并且根据这些变量的唯一状态,您可以在调用EXEC之前进行完全不同的写入。如果在中间时间内有任何东西干扰了这些变量的状态,EXEC将不执行事务。(允许您重试。这是一个完美的交易系统。)

评估脚本不允许您这样做。根据本页上的文档:

“脚本作为纯函数…脚本的计算结果始终相同 Redis使用相同的输入数据编写具有相同参数的命令 脚本执行的操作不能依赖于任何隐藏的 (非显式)可能随脚本而改变的信息或状态 执行继续或在脚本的不同执行之间执行,或 它可以依赖于I/O设备的任何外部输入。”

我在EVAL中看到的问题是,您无法在脚本中获取这些变量的状态,并根据这些变量的状态生成一组唯一的写入。再次声明:“脚本总是使用相同的参数对相同的Redis write命令进行求值,给定相同的输入数据集。”因此,结果写入已经确定(从第一次运行时缓存),并且EVAL脚本不关心脚本中的GET值。您唯一能做的就是在调用EVAL之前对这些变量执行GET,然后将这些变量传递给EVAL脚本,但问题是:现在在调用GET和调用EVAL之间存在原子性问题

换言之,您本应监视事务的所有变量,在EVAL的情况下,您需要获取这些变量,然后将它们传递给EVAL脚本。由于脚本的原子性质在脚本实际启动之前是无法保证的,并且在调用EVAL启动脚本之前需要获取这些变量,因此在获取和将这些变量传递给EVAL之间,这些变量的状态可能会发生变化。因此,对于一组非常重要的用例,WATCH提供的原子性保证并不是EVAL提供的

那么,为什么会有人谈论弃用交易,而这会导致重要的Redis功能丢失呢?或者有没有一种方法可以用我还不了解的EVAL脚本来实现这一点?或者计划有哪些功能可以解决这一问题?(假设性示例:如果他们让WATCH与EVAL的工作方式与WATCH与EXEC的工作方式相同,那么这可能会起作用。)


有解决办法吗?或者我应该理解,从长远来看,Redis可能不完全是事务安全的?

lua脚本确实可以做任何事务,但我认为Redis事务不会消失

EVAL脚本不允许您监视变量

当eval脚本正在运行时,其他任何脚本都不能同时运行。因此,
watch
ing变量是毫无意义的。读取脚本中的值后,可以确保没有其他人修改了变量

我在EVAL中看到的问题是,您无法在脚本中获取这些变量的状态,并根据这些变量的状态生成一组唯一的写入

不是真的。可以将关键点传递给eval脚本。在eval脚本中,可以从Redis读取值,然后根据这些值有条件地执行其他命令


脚本仍然是确定性的。如果您使用该脚本并在从机上运行,它仍将执行相同的写入命令,因为主机和从机具有相同的数据。

EVAL脚本实际上扩展并简化了事务的功能

可以通过以下方式在Redis中查看两种类型的交易:

1。程序性(多执行)

Pure MULTI-EXEC将要一次性执行的命令分组,并从每个命令返回一个回复数组。它有严重的局限性。它不允许在事务中的下一个命令中使用一个命令的中间结果。在这种纯形式下,它在实际应用中不是很有用。它基本上是一个保证原子性的流水线

在事务之前添加WATCH键,允许乐观锁定,并在事务中使用从事务外部的Redis获得的值。如果出现竞争条件,事务将失败,必须重试。这会使应用程序逻辑复杂化,而且这种乐观情绪通常是没有根据的,因为您可能会陷入无休止的重试循环

2。功能性(评估脚本)

EVAL不仅对Redis命令进行分组,还提供了完整编程语言的强大功能,特别是条件、循环和局部变量。在Lua脚本中,您可以在一个命令中从Redis读取值,然后在下一个命令中使用这些值

提交以原子方式执行的脚本。单线程“停止世界”方法保证了这一点。在执行脚本时,不会执行其他脚本或Redis命令。因此EVAL也有一个限制:脚本必须小而快,以防止阻塞其他客户端


我们还需要相信,其他客户端不会提交速度慢的脚本,这应该被视为编程错误。它非常适合安全模型,因为“Redis被设计为可由可信环境中的可信客户端访问”。

EVAL脚本可以完成事务所能做的一切,但乐观锁定除外,乐观锁定在单个thr中不是很有用