如何对Redis进行原子操作

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 如何对Redis进行原子操作什么时候需要进行需要原子操作?很常见的例子,就是利用Redis实现分布式锁。实现锁需要哪些条件?我们知道要实现锁,就需要一个改变锁状态的方法。这个方法能原子地对锁的状态进行检查并修改。

如何对Redis进行原子操作
什么时候需要进行需要原子操作?

很常见的例子,就是利用Redis实现分布式锁。

实现锁需要哪些条件?

我们知道要实现锁,就需要一个改变锁状态的方法。这个方法能原子地对锁的状态进行检查并修改。如果修改成功,则意味着获得了锁。对于硬件,它提供的就是test-and-set,compare-and-swap等原语。

Redis有没有提供类似的原语呢?

有的。Redis有提供setnx(),它会提供这样的原子操作:如果key没有值,则将值设置进去,如果已有值就不做处理,提示失败。

这样就可以基于这个原语来实现锁,简单原理就是:key就是对应的锁,如果key有值就说明锁被占用。删除值代表释放锁。如果插入值成功,则代表获得锁。再加上过期时间,基本就可以满足分布式锁的需求了。

除了锁,还有哪些地方需要原子操作?

假如我们在操作Redis数据的时候,需要判断Redis中某个值是否满足条件,只有满足条件才做这个操作

我随便举个例子,例如:如果key-xxx的值不为0,则加1,如果为0,则删除。

这种情况Redis可以处理吗?

可以,Lua脚本。Redis支持Lua脚本。针对上面的问题,我们只要写这样的Lua脚本就可以了。

复制代码
local a = redis.call('get', 'xxx') //调用redis的get方法,key为'xxx'
if(tonumber(a) > 0) then //redis都是以String进行存储的,需要转型

redis.call('incr', 'xxx') //调用redis的incr方法,key为'xxx'
return 'OK'

else

return 'FAIL'

复制代码
为什么Lua脚本可以实现原子操作, 看不出来它有用锁啊?

这与Redis的请求处理有关。Redis只用一个线程来处理客户端的请求。所以在执行lua脚本的时候,没有其他客户端的请求在处理。所以在lua脚本中的对redis数据的修改操作就是原子的。

只用一个线程处理的过来吗?

Redis的请求处理线程,利用Select和事件循环进行处理,大概就是下面这样:

while(1) {

events = getEvents(); //先利用SELECT拿到最近的请求
for(e in events)  //然后逐个处理
    processEvent(e);

}
由于使用的是select()来处理网络I/O,所以线程不会在一个socket连接上阻塞。另一方面因为redis的操作的数据都在内存中。处理起来也很快,所以也不会出现响应时间太长的情况。

万一这个线程阻塞了怎么办?

一般情况下,阻塞不了。前面也说了,客户端上来的请求都是操作内存的,不会有其他调用(例如文件I/O这样的调用)。但是,这是一般情况。别忘了lua,lua脚本里面是可以写阻塞操作的(比如文件I/O,或者最简单的死循环)。实测发现,如果往Redis中提交一个死循环的lua脚本,Redis就挂了。所以写lua脚本的时候要小心。
原文地址https://www.cnblogs.com/longfurcat/p/11250827.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8月前
|
NoSQL Redis 数据库
Redis原子操作和分布式锁setnx
Redis原子操作和分布式锁setnx
|
监控 NoSQL Redis
Redis从入门到精通之为什么说 Redis 的事务并不是真正的原子操作
为什么说 Redis 的事务并不是真正的原子操作
210 4
|
消息中间件 NoSQL Redis
深入探究Redis事务和Lua脚本:实现原子操作与复杂业务逻辑
本篇深入剖析了Redis的事务处理和Lua脚本特性,为读者呈现了如何利用这两个功能来实现数据的原子操作和执行复杂的业务逻辑。我们首先介绍了Redis事务的概念和基本操作,通过MULTI、EXEC、DISCARD和WATCH等命令,展示了如何在一组命令中保持原子性。进一步,我们探讨了事务命令的使用方法,演示了如何在事务中监视键变化以及提交事务。
880 0
|
1月前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
177 85
|
3月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
96 6
|
9天前
|
存储 缓存 NoSQL
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
|
9天前
|
缓存 NoSQL 关系型数据库
云端问道21期实操教学-应对高并发,利用云数据库 Tair(兼容 Redis®)缓存实现极速响应
本文介绍了如何通过云端问道21期实操教学,利用云数据库 Tair(兼容 Redis®)缓存实现高并发场景下的极速响应。主要内容分为四部分:方案概览、部署准备、一键部署和完成及清理。方案概览中,展示了如何使用 Redis 提升业务性能,降低响应时间;部署准备介绍了账号注册与充值步骤;一键部署详细讲解了创建 ECS、RDS 和 Redis 实例的过程;最后,通过对比测试验证了 Redis 缓存的有效性,并指导用户清理资源以避免额外费用。
|
1月前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文详细探讨了分布式系统和缓存应用中的经典问题——缓存穿透。缓存穿透是指用户请求的数据在缓存和数据库中都不存在,导致大量请求直接落到数据库上,可能引发数据库崩溃或性能下降。文章介绍了几种有效的解决方案,包括接口层增加校验、缓存空值、使用布隆过滤器、优化数据库查询以及加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统的影响,提升系统的稳定性和性能。
|
2月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
2月前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构