【问题标题】:pipelining vs transaction in redisRedis中的流水线与事务
【发布时间】:2015-06-02 08:48:02
【问题描述】:

当我们在 Redis 中使用事务时,它基本上将事务中的所有命令流水线化。并且当 EXEC 被触发时,所有的命令都会一起执行,从而始终保持多个命令的原子性。

这和流水线不一样吗?

流水线和事务有何不同? 另外,为什么 Redis 的单线程特性不够用?为什么我们明确需要流水线/事务?

【问题讨论】:

    标签: transactions redis pipelining


    【解决方案1】:

    流水线主要是一种网络优化。它本质上意味着客户端缓冲一堆命令并将它们一次性发送到服务器。这些命令不保证在事务中执行。这样做的好处是为每个命令节省了网络往返时间。

    Redis 是单线程的,因此 单个 命令始终是原子的,但是来自不同客户端的两个给定命令可以按顺序执行,例如在它们之间交替执行。

    然而,Multi/exec 确保在 multi/exec 序列中的命令之间没有其他客户端正在执行命令。

    【讨论】:

    • 为了澄清假设我使用 jedis 如下:JEDIS.MULTI \\ line 1; JEDIS.command1 \\ 第 2 行; JEDIS.command2 \\ 第 3 行; JEDIS.EXEC \\ 第 4 行;然后对于每一行,此代码将转到 redis 服务器,因此从 redis 服务器来回四轮。但是,如果我管道交易,那么所有四行都会在一轮中到达redis服务器。对吗?
    • @ManasSaxena,我相信不会。我认为客户端将缓冲命令并在调用exec 时立即发送所有命令。您可以使用redis-cli 自行测试。使用redis-cli 打开 2 个终端。首先,运行MONITOR。在第二次运行以下命令GET aMULTIGET bGET cEXEC。您将看到GET a(在事务之外)立即记录在MONITOR 上,而GET bGET c 仅在执行EXEC 时记录。不是 100% 肯定,但这是我目前的理解。缓冲可能发生在服务器端,但我看不出原因。
    • 我进行了额外的挖掘,发现了与我在上一条评论中所说的相反的东西。如果我在GET b 之后停止我的 Redis 服务器,GET c 将失败。因此,redis-cli 似乎在每个命令上都尝试与服务器通信。但这似乎是每个客户都可以选择的。我读过客户端可以一次发送所有事务,将它们作为管道在客户端排队。像这样:redislabs.com/ebook/part-2-core-concepts/…。但他们可以添加一个简单的短语来解释这一点
    • @ManasSaxena 好的,经过一番挖掘,你的问题的答案是:这取决于 Jedis 的实现。 Jedis 可以打开一个事务,并一个一个地发送命令(我在本期确认命令在服务器上排队:github.com/antirez/redis-doc/issues/1203#issuecomment-547475496)。但它也可以在exec 上一次发送所有命令。所以可以肯定的是,你应该打开 Jedis 代码并检查一下。老实说,我尝试过,但充满了让我放弃的类层次结构。
    • Unfortunately, MULTI and EXEC aren’t free, and can delay other important commands from executing Non-transactional pipelines,所以事务可以延迟其他重要的命令,它不是原子的,也不能保证。
    猜你喜欢
    • 2014-04-04
    • 2017-03-24
    • 2018-02-09
    • 2013-07-12
    • 2012-05-17
    • 2017-04-24
    • 2019-01-22
    • 2019-03-22
    • 1970-01-01
    相关资源
    最近更新 更多