基于redis的乐观锁

转自:https://www.toutiao.com/i6503412526095532558/?tt_from=weixin&utm_campaign=client_share&timestamp=1514535595&app=news_article&utm_source=weixin&iid=22004594589&utm_medium=toutiao_android&wxshare_count=1

在游戏开发中,我们有时需要实现乐观锁功能,乐观锁在数据竞争概率比较小的情况下会带来比较大的性能提升。memcached中有cas命令,用来实现check-and-set这样功能。Redis中我们可以基于Multi/EXEC/WATCH操作来实现类似的功能。

被WATCH的键会被监视,并且在事务执行前会去感知键的值是否发生了变化。如果有至少一个被监视的键在EXEC执行之前被修改了,那么整个事务都会被取消。

假如有一个用户使用购买的点数,兑换了一部分游戏内的金币,通常的操作如下,

curr_point = GET user1_pointcurr_gold = GET user1_goldcurr_point -= xcurr_gold += x*100SET user1_point curr_pointSET user1_gold curr_gold

在单个Redis客户端执行上述命令的时候没有问题,但是如果用户做了多次兑换,然后有多个Redis客户端同时在执行上述逻辑,那么用户的数据就错乱了。那如果基于Redis的WATCH和MULTI/EXEC机制,我们可以这么做,

WATCHcurr_point = GET user1_pointcurr_gold = GET user1_goldcurr_point -= xcurr_gold += x*100MULTISET user1_point curr_pointSET user1_gold curr_goldEXEC

这样如果在执行EXEC之前,user1_point和user1_gold这两个key的值发生了变化,那么事务就会失败,否则事务执行成功。对于业务来说,就是不断的去重试上述逻辑,直到成功,这也是为什么数据冲突概率小的时候,性能很好,因为基本相当于无锁,所以称之为乐观锁。

原文地址:https://www.cnblogs.com/yanwei-wang/p/8145123.html

时间: 2024-10-11 06:08:32

基于redis的乐观锁的相关文章

[Redis] 基于redis的分布式锁

前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件: 互斥性.在任意时刻,只有一个客户端能持有锁.不会发生死锁.即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁.具有容错性.只要大部分的Redis节点正常运行,客户端就可以加锁和解锁.解铃还须系铃人.加锁和解锁必须

基于redis的分布式锁的分析与实践

转:https://my.oschina.net/wnjustdoit/blog/1606215 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于线程之间是否相互阻塞. 那么,本文主要来讨论基于redis的分布式锁算法问题. 从2.6.12版本开始,redis为SET命令增加了一系列选项(SET key value [EX seconds] [PX

AtomicInteger源码分析——基于CAS的乐观锁实现

AtomicInteger源码分析--基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行cpu切换,也就是会发生进程的切换.切换涉及到清空寄存器,缓存数据.然后重新加载新的thread所需数据.当一个线程被挂起时,加入到阻塞队列,在一定的时间或条件下,在通过notify(),notifyAll()唤醒回来.在某个资源不可用的时候,就将cpu让出,把当前等待线程切换为阻

基于Redis的分布式锁到底安全吗(上)?

网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词"Redis 分布式锁"随便到哪个搜索引擎上去搜索一下就知道了.这些文章的思路大体相近,给出的实现算法也看似合乎逻辑,但当我们着手去实现它们的时候,却发现如果你越是仔细推敲,疑虑也就越来越多. 实际上,大概在一年以前,关于Redis分布式锁的安全性问题,在分布式系统专家Martin Kleppmann和Redis的作者antirez之间就发生过一场争论.由于对这个问题一直以来比较关注,所以我前些日子仔细阅读了与这场争

基于redis的分布式锁

<?php /** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * https://gist.github.com/nickyleach/3694555 */ pc_base::load_sys_class('cache_redis', '', 0); class dist_key_redis { //锁的超时时间 const TIMEOUT = 20; const SL

转载:基于Redis实现分布式锁

转载:基于Redis实现分布式锁  ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等.大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系.其次Redis提供一些命令SETNX,GETSET,可以方便实现分布式锁机制. Redis命令介绍使用Redis实现分

基于redis的分布式锁(不适合用于生产环境)

基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境,另一个是集群环境下的Redis锁实现.在介绍分布式锁的实现之前,先来了解下分布式锁的一些信息. 2 分布式锁 2.1 什么是分布式锁? 分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一种锁实现,如果不同的系统或同一个系统的不同主机之间共享了某个资源时,往往需要互斥

ElasticSearch(九)基于version进行乐观锁并发控制

一.基于version进行乐观锁并发控制 1).查看一条document GET /test_version/test_version_type/1 { "_index" : "test_version", "_type" : "test_version_type", "_id" : "1", "_version" : 1, "found" : t

基于redis的分布式锁实现

关于分布式锁 很久之前有讲过并发编程中的锁并发编程的锁机制:synchronized和lock.在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量.而同步的本质是通过锁来实现的.为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记.