什么是Redis的并发竞争问题

Redis的并发竞争问题,主要是发生在并发写竞争。考虑到redis没有像db中的sql语句,update val = val + 10 where ...,无法使用这种方式进行对数据的更新。

假如有某个key(mileage),  value(10),现在想把value值进行+10操作。正常逻辑下,就是先把数据key为mileage的值读回来,加上10,再把值给设置回去。

如果只有一个连接的情况下,这种方式没有问题,可以工作得很好,但如果有两个连接时,两个连接同时想对还mileage进行+10操作,就可能会出现问题了。

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

考虑到一种情况:

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

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

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

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

另外假设有个A线程正在写mileage,B线程正在读写mileage,当A,B同时执行的时候也可能发生并发竞争问题:

即B将mileage值读出来的时候,A正好更新了mileage值,然后B又更新回mileage值,此时照成A的更新无效。

解决方案

方案1

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

方案2

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

方案3

使用乐观锁的方式进行解决(成本较低,非阻塞,性能较高)。如何用乐观锁方式进行解决?本质上是假设不会进行冲突,使用redis的命令watch进行构造条件。伪代码如下:

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

解释一下:

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

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

方案4

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

方案5

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

Redis的中并发问题的解决方案小结的更多相关文章

  1. php中并发读写文件冲突的解决方案(文件锁应用示例)

    PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适 ...

  2. Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案

    Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案 说明:Java开源生鲜电商中OMS订单系统中并发问题和锁机制的探讨与解决方案: 问题由来     假设在一个订单系统中(以火车票 ...

  3. 企业高并发的成熟解决方案(一)video(笔记&知识点)

    知识点 答案 什么是高可用(HA) 高并发发生在哪两处 app服务器会出现什么问题,有哪些解决方案? 数据库并发有什么要求? hadoop集群的作用 负载均衡的功能有哪些 负载均衡的分类 哪种负载均衡 ...

  4. 第二十节: 深入理解并发机制以及解决方案(锁机制、EF自有机制、队列模式等)

    一. 理解并发机制 1. 什么是并发,并发与多线程有什么关系? ①. 先从广义上来说,或者从实际场景上来说. 高并发通常是海量用户同时访问(比如:12306买票.淘宝的双十一抢购),如果把一个用户看做 ...

  5. 关于Redis处理高并发

    Redis的高并发和快速原因 1.Redis是基于内存的,内存的读写速度非常快: 2.Redis是单线程的,省去了很多上下文切换线程的时间: 3.Redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  6. 企业高并发的成熟解决方案(一)----搭建LVS负载均衡

    企业整个架构分析 1. App服务器上边部署应用,如果是java的话,一般是tomcat: 2. 负载均衡服务器负责转发请求,这种既有主机又有备机的负载均衡成为高可用(HA): 3. 一般web服务器 ...

  7. redis处理高并发

    参考: https://www.cnblogs.com/wanlei/p/10464517.html 关于Redis处理高并发 Redis的高并发和快速原因 1.Redis是基于内存的,内存的读写速度 ...

  8. Nginx与Redis解决高并发问题

    原文链接:http://bbs.phpchina.com/forum.php?mod=viewthread&tid=229629 第一版产品采用的是Jquery,Nginx,PHP(CI框架) ...

  9. Redis实现高并发分布式序列号

    使用Redis实现高并发分布式序列号生成服务 序列号的构成 为建立良好的数据治理方案,作数据掌握.分析.统计.商业智能等用途,业务数据的编码制定通常都会遵循一定的规则,一般来讲,都会有自己的编码规则和 ...

随机推荐

  1. 基于Servlet+jsp的web计算器

    基于Servlet+jsp的web计算器 这次老大为了让我们自己复习web中页面的跳转给布置得任务 天下代码一大抄,关键看你怎么抄 首先我想到的计算算法不是什么堆栈,是简单的(其实很复杂,但是我就只需 ...

  2. 设计模式(Design Patterns)的简单讲解

    模式的诞生与定义 模式(Pattern)起源于建筑业而非软件业(小本本记下来--) 模式之父--美国加利佛尼亚大学环境结构中心研究所所长Christopher Alexander博士; 模式 : -C ...

  3. HIVE扩展GIS函数

        按项目日益增长的gis数据量要求,需要在大数据集群中部署HIVE的扩展函数.     Apache Hive是一个建立在Hadoop架构之上的数据仓库.它能够提供数据的精炼,查询和分析.([引 ...

  4. 有趣的 box-decoration-break

    这两天接触到一个很有意思的 CSS 属性 -- box-decoration-break.下面就一起去一探究竟. 因为 MDN 上关于这个属性,没有中文文档,所以一直在想一个合理贴切的中文翻译.直译一 ...

  5. 不带parent指针的successor求解

    问题: 请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继).给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值.保证结点的值大于等于 ...

  6. PHP全栈学习笔记11

    连接MySQL mysql_connect(servername,username,password); 面向对象: <?php $servername = "localhost&qu ...

  7. 在Linux系统配置Nodejs环境的最简单步骤,部署多个thinkjs(nodejs)项目

    发现一台服务器部署管理多个nodejs服务,可以采用二级域名weekly.mwcxs.top,也可以采用固定后缀www.mwcxs.top/weekly的方式,本文先从固定后缀的方式部署管理多个nod ...

  8. Spring Cloud微服务系列文,服务调用框架Feign

    之前博文的案例中,我们是通过RestTemplate来调用服务,而Feign框架则在此基础上做了一层封装,比如,可以通过注解等方式来绑定参数,或者以声明的方式来指定请求返回类型是JSON.    这种 ...

  9. ASP.NET Core中使用GraphQL - 第一章 Hello World

    前言 你是否已经厌倦了REST风格的API? 让我们来聊一下GraphQL. GraphQL提供了一种声明式的方式从服务器拉取数据.你可以从GraphQL官网中了解到GraphQL的所有优点.在这一系 ...

  10. JDK源码分析(11)之 BlockingQueue 相关

    本文将主要结合源码对 JDK 中的阻塞队列进行分析,并比较其各自的特点: 一.BlockingQueue 概述 说到阻塞队列想到的第一个应用场景可能就是生产者消费者模式了,如图所示: 根据上图所示,明 ...