微前端架构如何改变企业的开发模式与效率提升
759
2022-09-19
基于 Redis 实现 CAS 操作(基于stm32的毕业设计)
基于 Redis 实现 CAS 操作
Intro#
在 .NET 里并发情况下我们可以使用 Interlocked.CompareExchange 来实现 CAS (Compare And Swap) 操作,在分布式的情景下很多时候我们都会使用 Redis ,最近在改之前做的一个微信小游戏项目,之前是单机运行的,有些数据存储是基于内存的,直接基于对象操作的,最近要改成支持分布式的,于是引入了 redis,原本基于内存的数据就要迁移到 redis 中存储,原来的代码里有一些地方使用了 Interlocked.CompareExchange 来实现 CAS 操作,迁移到 redis 中之后也需要类似的功能,于是就想基于 redis 实现 CAS 操作。
CAS#
CAS (Compare And Swap) 通常可以使用在并发操作中更新某一个对象的值,CAS 是无锁操作,CAS 相当于是一种乐观锁,而直接加锁相当于是悲观锁,所以相对来说 CAS 操作 是会比直接加锁更加高效的。
Redis Lua#
redis 从 2.6.0 版本开始支持 Lua 脚本,Lua 脚本的执行是原子性的,所以我们在实现基于 redis 的分布式锁释放锁的时候或者下面要介绍的实现CAS 操作的,要执行多个操作但是希望操作是原子操作的时候就可以借助 Lua 脚本来实现(也可以使用事务来做)
基于 Redis Lua 实现 CAS#
String CAS Lua Script:
KEYS[1] 对应要操作的String 类型的 redis 缓存的 key,ARGV[1]对应要比较的值,值相同则更新成 ARGV[2],并返回 1,否则返回 0
Copy
if redis.call(""get"", KEYS[1]) == ARGV[1] then redis.call(""set"", KEYS[1], ARGV[2]) return 1 else return 0 end
Hash CAS Lua Script:
KEYS[1] 对应要操作的 Hash 类型的 redis 缓存的 key,ARGV[1] 对应 Hash 的 field,ARGV[2]对应要比较的值,值相同则更新成 ARGV[3],并返回 1,否则返回 0
Copy
if redis.call(""hget"", KEYS[1], ARGV[1]) == ARGV[2] then redis.call(""hset"", KEYS[1], ARGV[1], ARGV[3]) return 1 else return 0 end
基于 StackExchange.Redis 的实现#
为了方便使用,基于 IDatabase 提供了几个方便使用的扩展方法,实现如下:
Copy
public static bool StringCompareAndExchange(this IDatabase db, RedisKey key, RedisValue newValue, RedisValue originValue) { return (int)db.ScriptEvaluate(StringCasLuaScript, new[] { key }, new[] { originValue, newValue }) == 1; } public static async Task
实际使用#
使用可以参考下面的测试代码:
Copy
[Fact] public void StringCompareAndExchangeTest() { var key = "test:String:cas"; var redis = DependencyResolver.Current .GetRequiredService
References#
https://redis.io/commands/eval
https://redisbook.readthedocs.io/en/latest/feature/scripting.html
https://github.com/WeihanLi/WeihanLi.Redis/blob/dev/src/WeihanLi.Redis/RedisExtensions.cs
https://github.com/WeihanLi/WeihanLi.Redis/blob/dev/test/WeihanLi.Redis.UnitTest/RedisExtensionsTest.cs
出处:https://cnblogs.com/weihanli/p/redis-based-cas.html
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~