【发布时间】:2015-06-02 08:48:02
【问题描述】:
当我们在 Redis 中使用事务时,它基本上将事务中的所有命令流水线化。并且当 EXEC 被触发时,所有的命令都会一起执行,从而始终保持多个命令的原子性。
这和流水线不一样吗?
流水线和事务有何不同? 另外,为什么 Redis 的单线程特性不够用?为什么我们明确需要流水线/事务?
【问题讨论】:
标签: transactions redis pipelining
当我们在 Redis 中使用事务时,它基本上将事务中的所有命令流水线化。并且当 EXEC 被触发时,所有的命令都会一起执行,从而始终保持多个命令的原子性。
这和流水线不一样吗?
流水线和事务有何不同? 另外,为什么 Redis 的单线程特性不够用?为什么我们明确需要流水线/事务?
【问题讨论】:
标签: transactions redis pipelining
流水线主要是一种网络优化。它本质上意味着客户端缓冲一堆命令并将它们一次性发送到服务器。这些命令不保证在事务中执行。这样做的好处是为每个命令节省了网络往返时间。
Redis 是单线程的,因此 单个 命令始终是原子的,但是来自不同客户端的两个给定命令可以按顺序执行,例如在它们之间交替执行。
然而,Multi/exec 确保在 multi/exec 序列中的命令之间没有其他客户端正在执行命令。
【讨论】:
exec 时立即发送所有命令。您可以使用redis-cli 自行测试。使用redis-cli 打开 2 个终端。首先,运行MONITOR。在第二次运行以下命令GET a、MULTI、GET b、GET c、EXEC。您将看到GET a(在事务之外)立即记录在MONITOR 上,而GET b 和GET c 仅在执行EXEC 时记录。不是 100% 肯定,但这是我目前的理解。缓冲可能发生在服务器端,但我看不出原因。
GET b 之后停止我的 Redis 服务器,GET c 将失败。因此,redis-cli 似乎在每个命令上都尝试与服务器通信。但这似乎是每个客户都可以选择的。我读过客户端可以一次发送所有事务,将它们作为管道在客户端排队。像这样:redislabs.com/ebook/part-2-core-concepts/…。但他们可以添加一个简单的短语来解释这一点
exec 上一次发送所有命令。所以可以肯定的是,你应该打开 Jedis 代码并检查一下。老实说,我尝试过,但充满了让我放弃的类层次结构。
Unfortunately, MULTI and EXEC aren’t free, and can delay other important commands from executing Non-transactional pipelines,所以事务可以延迟其他重要的命令,它不是原子的,也不能保证。