• Redis的并发竞争问题的解决方案总结


    什么是Redis的并发竞争问题

    Redis的并发竞争问题,主要是发生在并发写竞争。

    考虑到redis没有像db中的sql语句,update val = val + 10 where ...,无法使用这种方式进行对数据的更新。

    假如有某个key = "price",  value值为10,现在想把value值进行+10操作。正常逻辑下,就是先把数据key为price的值读回来,加上10,再把值给设置回去。如果只有一个连接的情况下,这种方式没有问题,可以工作得很好,但如果有两个连接时,两个连接同时想对还price进行+10操作,就可能会出现问题了。

    例如:两个连接同时对price进行写操作,同时加10,最终结果我们知道,应该为30才是正确。

    考虑到一种情况:

    T1时刻,连接1将price读出,目标设置的数据为10+10 = 20。

    T2时刻,连接2也将数据读出,也是为10,目标设置为20。

    T3时刻,连接1将price设置为20。

    T4时刻,连接2也将price设置为20,则最终结果是一个错误值20。

    解决方案

    方案1

    利用redis自带的incr命令,具体用法看这里http://doc.redisfans.com/string/incr.html。

    方案2

    可以使用独占锁的方式,类似操作系统的mutex机制。(网上有例子,http://blog.csdn.net/black_ox/article/details/48972085 不过实现相对复杂,成本较高)

    方案3

    使用乐观锁的方式进行解决(成本较低,非阻塞,性能较高)

    如何用乐观锁方式进行解决?

    本质上是假设不会进行冲突,使用redis的命令watch进行构造条件。伪代码如下:

    watch price
    
    get price $price
    
    $price = $price + 10
    
    multi
    
    set price $price
    
    exec

    解释一下:

    watch这里表示监控该key值,后面的事务是有条件的执行,如果从watch的exec语句执行时,watch的key对应的value值被修改了,则事务不会执行。

    具体看Redis的事务功能详解这篇文章里的watch命令介绍。

    方案4

    这个是针对客户端来的,在代码里要对redis操作的时候,针对同一key的资源,就先进行加锁(java里的synchronized或lock)。

    方案5

    利用redis的setnx实现内置的锁。

  • 相关阅读:
    Opaque data type--不透明类型
    swift class的动态派发
    swift class的虚函数表
    swift class的虚函数表、扩展、@objc修饰、虚函数的派发方式研究
    swift语言混编--语言交互的接口
    CPU指令分类
    CPU的内部架构和工作原理-原文
    cpu的组成及分工
    简单介绍 CPU 的工作原理
    php7开启强类型模式
  • 原文地址:https://www.cnblogs.com/shamo89/p/8385390.html
Copyright © 2020-2023  润新知