redis竞汰数据同步问题解决
Redis
面试的时候遇到过问Redis是如何解决“竞态条件”的,相关知识点总结一下。
乐观锁
所谓竞态条件,举个例子,一个代表点击数的数值hitcount,每个客户点击一次则+1。
没有事务的时候,假设我们的操作如下:
hc=GET hitcount;
hc=hc+1;
SET hitcount $hc;
非并发状态下,这样做是OK的,但是并发状态下会出现的问题是:
1
A和B两个客户端分别从Redis处取值,并+1,值都是11。
2
Redis是单线程模型,所以A和B的SET命令只能先执行1个,此处先执行A,hitcount更新为11。
3
接着执行B的SET命令,hitcount依然是11,这就是明显的因为竞态而产生的错误,hitcount应该为12才是。
Redis的事务其实是通过MULTI命令开启事务,将后续一系列的命令放在一个队列里,不立即执行,直到EXEC命令,队列中的命令才会依次执行。
命令类似:
MULTI;
set val1 111;
set val2 222;
EXEC;
在实际工作中,我们也会经常遇到这种问题:我们必须先拿到数据,根据数据做出判断,进行一些处理之后,再更新数据,这时候我们就没法保证取数据、更新数据在同一个队列事务中了。
这就需要乐观锁。简单说,我们每取一个数据的时候,Redis不仅返回数值,还会返回这个数值的版本号。
当我们执行更新命令时,Redis会拿你要SET值的版本号与库里现在值的版本号进行比对,如果相同,则更新,版本号变更。
如果版本号不同,则说明在我们执行更新命令之前,有其他客户端修改了这条数据,我们的更新操作失败。
Redis里是通过WATCH命令来监控版本号的。
WATCH hitcount;
hc=GET hitcount;
hc=hc+1;
MULTI;
SET hitcount $hc;
EXEC;
因为通过WATCH监控了hitcount这个Key,那么在事务中SET的时候,一旦发现版本号不对,执行就失败。
悲观锁
乐观锁是CAS——Check And Set,先检查(版本号)再设置更新,那么悲观锁就是先锁,再查,最后更新。
以MySQL为例,我们要实现悲观锁:
SELECT * FROM tabA AS t WHERE t.id=1 FOR UPDATE;
这样,因为主键是明确指定的(id=1),所以这一行记录就被锁定了——行锁定,在本事务被commit之前,这条数据都只会被本事务的SQL语句进行修改,其他事务的加锁操作,更新操作都会在本事务提交之后再执行,单纯的查询则不受影响。
如果没有指定明确地主键,则锁定的是表——表锁定。
redis竞汰数据同步问题解决的更多相关文章
- redis如何实现数据同步
redis如何实现数据同步 两种,1全同步,2部分同步 全备份: 在slave启动时会向master发送sync消息,master收到slave这条消息之后,将启动后台备份进程,备份完成之后,将备份数 ...
- redis 学习笔记——数据同步、事务
redis主从同步 redis支持简单易用的主从复制(master-slave replication)功能,该功能也是redis高可用性实现的基础. redis复制原理 re ...
- redis与DB数据同步问题
Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了Pyt ...
- Redis单节点数据同步到Redis集群
一:Redis集群环境准备 1:需要先安装好Redis集群环境并配置好集群 192.168.0.113 7001-7003 192.168.0.162 7004-7006 2:检查redis集群 [r ...
- Redis和MySQL数据同步及Redis使用场景
1.同步MySQL数据到Redis (1) 在redis数据库设置缓存时间,当该条数据缓存时间过期之后自动释放,去数据库进行重新查询,但这样的话,我们放在缓存中的数据对数据的一致性要求不是很高才能放入 ...
- CentOS 7 PHP-redis扩展安装,浏览器不显示数据及redis无法储存数据常见问题解决办法
首先使用php -m 可以查看到自己安装了那些扩展. 1.使用wget下载redis压缩包 wget https://github.com/phpredis/phpredis/archive/deve ...
- redis秒杀系统数据同步(保证不多卖)
东西不多卖 秒杀系统需要保证东西不多卖,关键是在多个客户端对库存进行减操作时,必须加锁.Redis中的Watch刚好可以实现一点.首先我们需要获取当前库存,只有库存中的食物小于购物车的数目才能对库存进 ...
- Redis和数据库 数据同步问题
Redis和数据库同步问题 缓存充当数据库 比如说Session这种访问非常频繁的数据,就适合采用这种方案:当然了,既然没有涉及到数据库,那么也就不会存在一致性问题: 缓存充当数据库热点缓存 读操作 ...
- Redis与Mysql数据同步
后台定时任务,定时刷新Redis中信息到数据库.(即Job:定时任务)
随机推荐
- 用js来实现那些数据结构01(数组篇01-数组的增删)
在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念.那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记 ...
- LOJ.115.[模板]无源汇有上下界可行流(Dinic)
题目链接 参考:http://blog.csdn.net/clove_unique/article/details/54884437 http://blog.csdn.net/wu_tongtong/ ...
- 1207 ACM 汉诺塔II 数学
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1207 中文题目,在原来三个柱子的情况下(汉诺塔一),增加了一个柱子,难度也增加了. 思路: 思考时尽量和汉 ...
- [USACO11FEB]Generic Cow Protests
思路: 动态规划.首先处理出这些数的前缀和$a$,$f_i$记录从第$1$位到第$i$位的最大分组数量.DP方程为:$f_i=max(f_i,f_j+1)$,其中$j$满足$a_i-a_j≥0$. # ...
- python 反射的用法
class Foo(): def __init__(self,name): self.name=name def text(self): f=Foo() ''' hasattr(obj,name) 判 ...
- Ajax csrf跨站请求伪造
方式一: ///仅限js代码在HTML内//// $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, }); 方式二: // ...
- C++ 函数模板基础知识
为什么要引入模板:为了避免代码重复,程序员可以编写脱离数据类型通用模板. 模板的分类:函数模板 + 类模板 注意:模板的声明或定义只能在全局,命名空间或类范围内进行.不能在函数内进行,比如不能在mai ...
- bzoj 4084 双旋转字符串
给两个集合A,B,找满足要求的(a,b)的对数,可以计算对于a,哪些b成立. 还有就是字符串hash的使用,感觉平时用字符串hash太少了. /**************************** ...
- git 分支合并冲突
准备新的feature1分支,继续我们的新分支开发 [root@node1 git]# git checkout -b feature1 D git/LICENSE.txt Switched to a ...
- float类型数保留一位小数
float类型数保留一位小数 float a = 2.5f; float b = 1.2f; System.out.println(a/b); System.out.println((float)(M ...