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:定时任务)
随机推荐
- centos 支持复制与粘贴
centos 要支持与主机的交互,vmtools 必不可少. 为了方便虚拟机和主机之间复制粘贴文件,拖拽文件,需要安装VMwareTools.下面将我的安装步骤记录如下:第一步:打开虚拟机后,在VM的 ...
- 洛谷.3121.审查(AC自动机 链表)
题目链接 //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) #include <cstdio> #include <cstring> #defi ...
- linux下自定义域名访问本机部署的应用
在linux系统下,用weblogic部署了两套应用,创建了两个虚拟主机,一个主机指向www.test1.com, 另一个虚拟主机指向www.test2.com. 一套应用指定一台虚拟主机. 修改/e ...
- SSH使用自定义私钥进行登录
ssh -i /root/.ssh/id_rsa root@192.168.1.2 -i指定了私钥文件的路径
- wordpress模板修改及函数说明
原文:http://java-er.com/blog/wp-mb-edit/ WordPress基本模板文件 style.css : CSS(样式表)文件index.php : 主页模板archive ...
- android:View的setTag和getTag
Adapter 有个getView方法,可以使用setTag把查找的view缓存起来方便多次重用 public View getView(int position, View convertView, ...
- GO开发环境搭建
GO开发环境搭建 1)下载GO SDK,并安装 https://golang.google.cn/dl/ 2)下载GO IDE:GOLAND,并安装 3)设置GOROOT和GOPATH 4)新建一个工 ...
- 【linux】linux修改open file 大小
使用下面命令可以查看openfile数量 ulimit -a linux修改open file 大小,修改步骤如下: 1>修改file-max 修改文件: vi /etc/sysctl.conf ...
- app v1界面
- centos npm 安装后 command not found
ok,