【问题标题】:Redis: Race Condition and Single threadedRedis:竞争条件和单线程
【发布时间】:2015-05-02 15:54:06
【问题描述】:

我是 Redis 新手,正在阅读 Redis in Action 这本书,其中详细介绍了竞争条件和避免它的不同锁定机制。(有一个专门的章节)。 但是在一些 StackOverflow 帖子中讨论了 Redis 是单线程的。 链接如下: Are redis operations on data structures thread safe

在上面的链接中(在其中一个答案中)明确写道,当命令正在执行时,不会运行其他命令。

现在我的问题是:如果 Redis 是单线程的,那么为什么需要锁定机制。

请澄清一下,如果我的理解有误,请告诉我。

它还遵循乐观锁定机制,其中多个线程可能会尝试更新数据,如果数据被修改,它将通知其他尝试同时更新的线程(因为他们的更新失败,他们可以再次重试相同操作)。

【问题讨论】:

    标签: redis


    【解决方案1】:

    如果 Redis 是单线程的,那为什么还需要 Locking 机制呢。

    Redis 确实(大部分)是单线程的,但是当多个客户端尝试在相邻的时间邻近处做不同的事情时,需要锁定。 RiA 中讨论的锁定正是如此——确保只有一个客户端/线程执行特定任务,或者确保更新不会出错。

    这是一个尽管 Redis 是单线程但仍需要锁定的示例:假设您在 Redis 中有一个值,例如存储在名为 foo 的键下的数字。您的应用程序代码读取该数字 (GET foo),对其执行操作(即加 1)并将其写回 (SET)。当你在一个线程中运行你的代码时,它会是这样的:

    App               Redis
     |---- GET foo ---->|
     |<------ 1 --------|
     |                  |
     | thinking...      |
     |                  |
     |--- SET foo 2 --->|
     |<----- OK --------|
    

    现在让我们看看当两个应用客户端尝试这样做时会发生什么:

    App 1             Redis              App 2
     |---- GET foo ---->|                  |
     |<------ 1 --------|<--- GET foo -----|
     |                  |------- 1 ------->|
     | thinking...      |                  |
     |                  |       thinking...|
     |--- SET foo 2 --->|                  |
     |<----- OK --------|<--- SET foo 2 ---|
     |                  |------ OK ------->|
    

    尽管服务器(大部分)是单线程的,foo 的值为 2 而不是 3,但您可以在此处立即看到没有锁定的情况。当您添加更多线程/客户端/应用程序时,事情会顺利进行当多个编写者尝试在不协调的情况下修改数据时(例如锁定),这是非常错误的。

    乐观锁定只是其中一种方法,Redis 通过WATCH 机制提供了内置的方法。然而,有时乐观——尽管它随和和快乐的天性——并不是正确的解决方案,因此您需要实施更好/先进/不同的机制来防止竞争条件。可以说,这种锁甚至可以在 Redis 之外实现,但如果您已经在使用它,那么在其中管理您的锁也是有意义的。

    【讨论】:

    • 据我了解:Redis 命令本身就是原子的。并且在执行原子命令时没有任何数据竞争的范围。但是如果我们希望将多个命令作为单个原子执行{这样就不会受到其他客户端的干扰},那么我认为事务就是答案。让我们在上面的例子中说:客户端程序可能是这样的:get x; //执行一些工作;增加 x;这里 get x 是原子执行的,但是当 incr x 到来时,它会采用陈旧的值还是更新一次。
    • 没错。使用 MULTI/EXEC 块(可选用 WATCH)或 Lua 脚本来获得类似事务的原子性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    相关资源
    最近更新 更多