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竞汰数据同步问题解决的更多相关文章

  1. redis如何实现数据同步

    redis如何实现数据同步 两种,1全同步,2部分同步 全备份: 在slave启动时会向master发送sync消息,master收到slave这条消息之后,将启动后台备份进程,备份完成之后,将备份数 ...

  2. redis 学习笔记——数据同步、事务

    redis主从同步      redis支持简单易用的主从复制(master-slave replication)功能,该功能也是redis高可用性实现的基础.   redis复制原理      re ...

  3. redis与DB数据同步问题

    Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了Pyt ...

  4. Redis单节点数据同步到Redis集群

    一:Redis集群环境准备 1:需要先安装好Redis集群环境并配置好集群 192.168.0.113 7001-7003 192.168.0.162 7004-7006 2:检查redis集群 [r ...

  5. Redis和MySQL数据同步及Redis使用场景

    1.同步MySQL数据到Redis (1) 在redis数据库设置缓存时间,当该条数据缓存时间过期之后自动释放,去数据库进行重新查询,但这样的话,我们放在缓存中的数据对数据的一致性要求不是很高才能放入 ...

  6. CentOS 7 PHP-redis扩展安装,浏览器不显示数据及redis无法储存数据常见问题解决办法

    首先使用php -m 可以查看到自己安装了那些扩展. 1.使用wget下载redis压缩包 wget https://github.com/phpredis/phpredis/archive/deve ...

  7. redis秒杀系统数据同步(保证不多卖)

    东西不多卖 秒杀系统需要保证东西不多卖,关键是在多个客户端对库存进行减操作时,必须加锁.Redis中的Watch刚好可以实现一点.首先我们需要获取当前库存,只有库存中的食物小于购物车的数目才能对库存进 ...

  8. Redis和数据库 数据同步问题

    Redis和数据库同步问题 缓存充当数据库 比如说Session这种访问非常频繁的数据,就适合采用这种方案:当然了,既然没有涉及到数据库,那么也就不会存在一致性问题: 缓存充当数据库热点缓存 读操作 ...

  9. Redis与Mysql数据同步

    后台定时任务,定时刷新Redis中信息到数据库.(即Job:定时任务)

随机推荐

  1. 在netcore中如何注入同一个接口的多个实现

    netcore中自带了Ioc框架,这也影响了我们的编码习惯,以前都是静态类或者直接new对象,现在有了Ioc框架的支持,我们也不必守旧,应当使用起来,接受这种对象管理方式.使用过java的同仁,都习惯 ...

  2. Node+Express+MongoDB+Socket.io搭建实时聊天应用实战教程(一)--MongoDB入门

    前言 本文并不是网上流传的多少天学会MongoDB那种全面的教程,而意在总结这几天使用MongoDB的心得,给出一个完整的Node+Express+MongoDB+Socket.io搭建实时聊天应用实 ...

  3. Bzoj4598: [Sdoi2016]模式字符串 点分治 哈希

    国际惯例的题面:这种关于树上路径的题,我也没什么好办法,只好点分治.考虑当前分治重心为root,如何统计经过分治重心的路径的答案.我们令prf[i]表示某个点到root的路径(不含root)已经循环匹 ...

  4. [CC-TRIPS]Children Trips

    [CC-TRIPS]Children Trips 题目大意: \(n(n\le10^5)\)座城市构成一棵树,且树上的每条边的长度\(l_i\)满足\(1\le l_i\le 2\).\(m(m\le ...

  5. [CodeVS4633][Mz]树链剖分练习

    思路: 轻重链剖分+线段树. #include<cstdio> #include<vector> #include<cstring> ; std::vector&l ...

  6. 关于supervisor的入门指北

    关于supervisor的入门指北 在目前这个时间点(2017/07/25),supervisor还是仅支持python2,所以我们要用版本管理pyenv来隔离环境. pyenv 根据官方文档的讲解, ...

  7. U3D面试五

    U3D面试题 配置Unity3D调试环境 Visual Studio Tools for Unity 访问http://unityvs.com 安装对应的版本 使用方法(生成项目文件,如何调试) Ar ...

  8. unity无限循环报错的定位

    晚上遇到了,碰到了程序一运行就卡住的尴尬问题,然后百度下,看了看,Get到了一个新的skill. 1. 打开对应的VS程序,选择“调试/Attach Unity Debuger”菜单来调试代码. 2. ...

  9. 奇怪吸引子---NewtonLeipnik

    奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...

  10. 用 Prettier 统一团队的代码风格~

    使用 prettier 自動調整 JavaScript 樣式 GFM 格式说明 为什么你不能缺少Linter(以及代码美化工具) 使用 prettier 自動調整 JavaScript 樣式 Reac ...