当前位置:首页 > 文章列表 > 数据库 > Redis > Redis并发访问问题详细讲解

Redis并发访问问题详细讲解

来源:脚本之家 2023-02-25 10:01:48 0浏览 收藏

各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题《Redis并发访问问题详细讲解》,很明显是关于数据库的文章哈哈哈,其中内容主要会涉及到Redis控制、并发访问等等,如果能帮到你,觉得很不错的话,欢迎各位多多点评和分享!

什么场景需要控制并发访问

需要控制并发访问,说明这些并发的访问可能会对其他的访问造成影响。比如上面提到的库存问题,若同一时期有多个客户端访问商品A的库存数据,并且可能要更更新库存数据,这时候就需要对并发访问进行控制了。

说到底,并发访问需要控制的就是对数据的更新动作。 一般来说,客户端要进行数据更新时可分为2个步骤:

  • 客户端读取Redis数据到本地。
  • 确认数据后,修改Redis的数据。

单个访问来看,这个过程并没什么问题。但是并发多了,一分为二的过程就会造成数据错误的问题。这里还是用库存的例子来说:

  • 时间a::客户端1读取到库存=10,我们需要对库存+1=11的操作。
  • 时间b:客户端2读取到的库存也是10,这次要对库存-1=9的操作。
  • 时间c:客户端1将+1后的值11写回到Redis中。
  • 时间d:客户端2将-1后的值9写回到Redis中。

这样下来,很明显能发现库存数据错了。10+1-1 = 10,正确库存是10,而上述场景最后为9。

由此可见,这个一分为二的操作不具有原子性,从而产生了错误的结果。类型这种场景很多,因此我们需要对这些并发访问的场景加以控制。

并发访问的控制方法

Redis并发访问的控制,总的来说有2种方式。分别是加入锁机制和让一系列操作原子化。

1、加入锁机制

首先第一点,加入锁机制是很常见的解决方案。简单来说就是一个客户端访问数据之前,先要获取锁,等数据操作完之后再解锁。而在这个客户端拥有锁的过程中,其他客户端如果也想访问修改该数据,必须得等锁释放了之后,获取到了锁才行。

加锁这个方案是可以解决并发访问的数据准确问题,但放在redis这个场景中并不是很好。首先,Redis作为缓存本身并发访问就很多,频繁的加锁解锁,会大大降低redis的访问性能;然后,Redis的客户端在要加锁时,需要用到分布式锁。我们又得用额外的精力去维护这个分布式锁。

2、操作原子化

操作原子化,也就是让要执行的一系列动作都保持原子性操作。它的优点就是不需要加入额外的锁机制。并发的数据准确性达到了,对Redis的性能也不会有太大的影响。

Redis要实现原子操作,总结有2种方式:

  • 单命令操作:也就是Redis中的INCR、HINCRBY等命令,直接将简单的加减操作合成一个命令执行;
  • Lua脚本:借助Lua脚本,让多个操作在Lua脚本上实现原子性操作。

1.单命令操作

首先,单命令操作,将数值的加减直接用Redis命令来执行。像string的加减可用INCR、DECR操作,hash列表field的加减可用HINCRBY操作。

比如下面截图,两个客户端在不同时刻读取的linux_pids a值为4,各自+1、-1后a值为4。结果是正确的。

由此可见,用Redis的INCR、DECR等命令可以解决数值简单增减的并发场景。但如果我们对数据的更新不仅仅是简单的加减操作时,Redis的这些命令就无能为力了。此时我们可以考虑另一种方案:Lua脚本。

2.Lua脚本

Lua语言是由C写的,因此支持多平台和系统。从Redis2.6开始,Redis就内置了Lua解释器,我们能直接用Redis客户端来执行lua脚本。

我们可以将需要执行的一系列操作用Lua脚本写好,然后用Redis执行它。Lua脚本的方法能保证原子性操作的原因是:Redis会将Lua脚本一次性执行,也就是说执行Lua脚本是0-1的操作,要么成功,要么失败。可以理解成MySQL的事务特性。

Redis使用lua脚本有2种方式:

  • 客户端中使用:用到script load脚本内容、evalsha等命令
  • 执行直接执行lua脚本

我们一般用第二种方式来执行。

客户端使用方法:

先用script load加载脚本命令,再用evalsha执行加载得到的sha1值。

127.0.0.1:6379> script load "return 'hello'"
"1b936e3fe509bcbc9cd0664897bbe8fd0cac101b"
127.0.0.1:6379> evalsha "1b936e3fe509bcbc9cd0664897bbe8fd0cac101b" 0
"hello"

再来看看Redis使用Lua脚本的语法:

redis-cli --eval {lua_path} KEYS[1] KEYS[2]... , ARGV[1] ARGV[2]...
 
--eval:          执行lua脚本的命令
{lua_path}:         lua脚本的路径
KEYS[1] KEYS[2]:       lua脚本中要操作的redis键,我们可以在lua脚本中用KEYS[1],KEYS[2],KEYS[3]指定多个
ARGV[1] ARGV[2]:    传入到lua脚本的参数,在脚本中用ARGV[1],ARGV[2]...来获取。

Redis使用lua脚本的场景很多,最经典的案例当属利用lua来控制某个IP的访问频率了。比如说需要防止恶意访问网站的行为,我们规定1分钟内访问次数不能超过30次,实现的方法有很多,比如说漏桶方案、令牌桶方案,但使用最多的还是Redis+lua的分布式限流方案。

我们用lua脚本(test_lua.script)来简单实现一下上述功能,就是1分钟内若访问次数超过30,直接拦截,否则访问次数+1:

-- 限流的key
local limit_key = KEYS[1]
-- 限流次数
local limit_nums = 30
-- 当前访问次数
local current_num = tonumber(redis.call('get', limit_key) or 0)
-- 超出限流次数
if current_num + 1 > limit_num
    then
    return '超出访问次数'
-- 没有超出限流数,访问次数+1
else
  redis.call("INCRBY", limit_key, "1")
  -- 第一次访问,设置过期时间
  if current_num == 0 then
    redis.call("expire", limit_key, "60")
  return current + 1
end

用Redis执行,命令如下:

redis-cli --eval test_lua.script limit_key

小结

本文介绍了Redis并发访问的控制问题,以及如何保证并发操作的原子化。原子化操作可通过单命令操作和Lua脚本的方式实现。我们在应对相关问题时,可根据需要选择对应方案解决之。

本篇关于《Redis并发访问问题详细讲解》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于数据库的相关知识,请关注golang学习网公众号!

版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
Redis优惠券秒杀解决方案Redis优惠券秒杀解决方案
上一篇
Redis优惠券秒杀解决方案
Redis对象与redisObject超详细分析源码层
下一篇
Redis对象与redisObject超详细分析源码层
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    15次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    24次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    42次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码