我工作中用Redis的10种场景

Redis作为一种优秀的基于key/value的缓存,有非常不错的性能和稳定性,无论是在工作中,还是面试中,都经常会出现。

今天这篇文章就跟大家一起聊聊,我在实际工作中使用Redis的10种场景,希望对你会有所帮助。

一. 统计访问次数

对于很多官方网站的首页,经常会有一些统计首页访问次数的需求。

访问次数只有一个字段,如果保存到数据库中,再最后做汇总显然有些麻烦。

该业务场景可以使用Redis,定义一个key,比如:OFFICIAL_INDEX_VISIT_COUNT。

在Redis中有incr命令,可以实现给value值加1操作:

incr OFFICIAL_INDEX_VISIT_COUNT

当然如果你想一次加的值大于1,可以用incrby命令,例如:

incrby OFFICIAL_INDEX_VISIT_COUNT 5

这样可以一次性加5。

二、获取分类树

在很多网站都有分类树的功能,如果没有生成静态的html页面,想通过调用接口的方式获取分类树的数据。

我们一般为了性能考虑,会将分类树的json数据缓存到Redis当中,为了后面在网站当中能够快速获取数据。

不然在接口中需要使用递归查询数据库,然后拼接成分类树的数据结构。

这个过程非常麻烦,而且需要多次查询数据库,性能很差。

因此,可以考虑用一个定时任务,异步将分类树的数据,直接缓存到Redis当中,定义一个key,比如:MALL_CATEGORY_TREE。

然后接口中直接使用MALL_CATEGORY_TREE这个key从缓存中获取数据即可。

可以直接用key/value字符串保存数据。

三、做分布式锁

分布式锁可能是使用Redis最常见的场景之一,相对于其他的分布式锁,比如:数据库分布式锁或者Zookeeper分布式锁,基于Redis的分布式锁,有更好的性能,被广泛使用于实际工作中。

我们使用下面这段代码可以加锁:

try{String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);if ("OK".equals(result)) {return true;}return false;
} finally {unlock(lockKey);
}  

但上面这段代码在有些场景下,会有一些问题,释放锁可能会释放了别人的锁。

说实话Redis分布式锁虽说很常用,但坑也挺多的,如果用不好的话,很容易踩坑。

四、 做排行榜

很多网站有排行榜的功能,比如:商城中有商品销量的排行榜,游戏网站有玩家获得积分的排行榜。

通常情况下,我们可以使用Sorted Set保存排行榜的数据。

使用ZADD可以添加排行榜的数据,使用ZRANGE可以获取排行榜的数据。

例如:

ZADD rank:score 100 "周星驰"
ZADD rank:score 90 "周杰伦"
ZADD rank:score 80 "周润发"
ZRANGE rank:score 0 -1 WITHSCORES

返回数据:

1) "周星驰"
2) "100"
3) "周杰伦"
4) "90"
5) "周润发"
6) "80"

 五、记录用户登录状态

通常下,用户登录成功之后,用户登录之后的状态信息,会保存到Redis中。

这样后面该用户访问其他接口的时候,会直接从Redis中查询用户登录状态,如果可以查到数据,说明用户已登录,则允许做后续的操作。

如果从Redis中没有查到用户登录状态,说明该用户没有登录,或者登录状态失效了,则直接跳转到用户登录页面。

使用Redis保存用户登录状态,有个好处是它可以设置一个过期时间,比如:该时间可以设置成30分钟。

jedis.set(userId, userInfo, 1800);

在Redis内部有专门的job,会将过期的数据删除,也有获取数据时实时删除的逻辑。

六、限流

使用Redis还有一个非常常用的的业务场景是做限流

当然还有其他的限流方式,比如:使用nginx,但使用Redis控制可以更精细。

比如:限制同一个ip,1分钟之内只能访问10次接口,10分钟之内只能访问50次接口,1天之内只能访问100次接口。

如果超过次数,则接口直接返回:请求太频繁了,请稍后重试。

跟上面保存用户登录状态类似,需要在Redis中保存用户的请求记录。

比如:key是用户ip,value是访问的次数从1开始,后面每访问一次则加1。

如果value超过一定的次数,则直接拦截这种异常的ip。

当然也需要设置一个过期时间,异常ip如果超过这个过期时间,比如:1天,则恢复正常了,该ip可以再发起请求了。

或者限制同一个用户id。

七、位统计

比如现在有个需求:有个网站需要统计一周内连续登陆的用户,以及一个月内登陆过的用户。

这个需求使用传统的数据库,实现起来比较麻烦,但使用Redis的bitmap让我们可以实时的进行类似的统计。

bitmap 是二进制的byte数组,也可以简单理解成是一个普通字符串。它将二进制数据存储在byte数组中以达到存储数据的目的。

保存数据命令使用setbit,语法:

setbit key offset value

具体示例:

setbit user:view:2024-01-17 123456 1

往bitmap数组中设置了用户id=123456的登录状态为1,标记2024-01-17已登录。

然后通过命令getbit获取数据,语法:

getbit key offset

具体示例:

getbit user:view:2024-01-17 123456

如果获取的值是1,说明这一天登录了。

如果我们想统计一周内连续登录的用户,只需要遍历用户id,根据日期中数组中去查询状态即可。

八、缓存加速

我们在工作中使用Redis作为缓存加速,这种用法也是非常常见的。

如果查询订单数据,先从Redis缓存中查询,如果缓存中存在,则直接将数据返回给用户。

如果缓存中不存在,则再从数据库中查询数据,如果数据存在,则将数据保存到缓存中,然后再返回给用户。

如果缓存和数据库都不存在,则直接给用户返回数据不存在。

流程图如下:

但使用缓存加速的业务场景,需要注意一下,可能会出现:缓存击穿、穿透和雪崩等问题。

九、做消息队列

@Slf4j
@Component
public class RedisMessageListenerListener implements MessageListener {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Overridepublic void onMessage(Message message, byte[] pattern) {String channel = new String(pattern);RedisSerializer<?> valueSerializer = redisTemplate.getValueSerializer();Object deserialize = valueSerializer.deserialize(message.getBody());if (deserialize == null) return;String md5DigestAsHex = DigestUtils.md5DigestAsHex(deserialize.toString().getBytes(StandardCharsets.UTF_8));Boolean result = redisTemplate.opsForValue().setIfAbsent(md5DigestAsHex, "1", 20, TimeUnit.SECONDS);if (Boolean.TRUE.equals(result)) {log.info("接收的结果:{}", deserialize.toString());} else {log.info("其他服务处理中");}}

十、生成全局ID

在有些需要生成全局ID的业务场景,其实也可以使用Redis。

可以使用incrby命令,利用原子性操作,可以执行下面这个命令:

incrby userid 10000

在分库分表的场景,对于有些批量操作,我们可以从Redis中,一次性拿一批id出来,然后给业务系统使用。

 有不对的地方,欢迎指正,共同学习,进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

逆向学习Windows篇:C++中多线程的使用和回调函数的实现

本节课在线学习视频&#xff08;网盘地址&#xff0c;保存后即可免费观看&#xff09;&#xff1a; ​​https://pan.quark.cn/s/385577c66515​​ 在Windows环境下&#xff0c;C是一种强大的编程语言&#xff0c;它不仅支持面向对象编程&#xff0c;还提供了对系统级编程的直…

竞赛选题 python opencv 深度学习 指纹识别算法实现

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python opencv 深度学习 指纹识别算法实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;4分创新点&#xff1a;4分 该项目较为新颖…

java干货 线程间通信

文章目录 一、线程间通信1.1 为什么要处理线程间通信&#xff1f;1.2 什么是等待唤醒机制&#xff1f; 二、等待唤醒机制使用2.1 等待唤醒机制用到的方法2.1.1 wait2.1.2 notify 2.2 线程通信代码实践2.2.1 重要说明2.2.2 代码 一、线程间通信 1.1 为什么要处理线程间通信&…

windows系统使用nvidia-smi命令办法

参考&#xff1a; https://blog.csdn.net/Castlehe/article/details/114978005 老版本的cuda&#xff0c;nvidia-sim.exe这个软件是位于&#xff1a;C:\Program Files\NVIDIA Corporation\NVSMI 新版本的cuda&#xff08;比如cuda11.0&#xff09;&#xff0c;nvidia-sim.exe这…

springBoot高校宿舍交电费系统-计算机毕业设计源码031552

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

忘记 iPhone 密码:如果忘记密码,如何解锁 iPhone

为了提高个人数据的安全性&#xff0c;用户通常会为不同的帐户和设备创建不同的复杂密码。虽然较新的 iPhone 型号具有生物识别和面部解锁功能&#xff0c;但这些功能并不总是有效 - 如果您忘记了 iPhone 的密码&#xff0c;您可能会遇到麻烦。 iPhone 用户和 Android 用户一样…

MYSQL 四、mysql进阶 4(索引的数据结构)

一、为什么使用索引 以及 索引的优缺点 1.为什么使用索引 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教科书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。Mysql中也是一样的道理&#xff0c;进行数…

2024-06-19 高等数学(统计学和概率论-高等工科数学)

学习数学时&#xff0c;有效的笔记方法可以帮助你更好地理解和记忆概念、公式和解题技巧。下面是一个数学笔记的基本模本&#xff0c;你可以根据自己的需求进行调整&#xff1a; 1. **标题**&#xff1a;写上日期和课程名称&#xff0c;例如“2024-06-19 高等数学”。 2. **课…

PyFlink

PyFlink教程 官方文档链接 PyFlink官方文档 概述 PyFlink是Apache Flink的Python API&#xff0c;允许用户使用Python编写数据处理程序。Flink是一种用于处理无界和有界数据流的分布式流处理框架。PyFlink可以帮助用户轻松地在Flink集群上运行Python数据流处理任务。 架构…

办公人必备宝藏网站,提升工作效率!

对于每个办公人来说&#xff0c;如何在繁杂的工作中保持高效&#xff0c;是每位职场人士追求的目标。其中&#xff0c;高效的工具和资源可以极大地提升我们的工作效率。下面小编就来和大家分享一些办公人必备的宝藏网站&#xff0c;提升大家的工作效率。 1. 办公人导航 办公人…

反激开关电源变压器设计2

实际计算 已知 Vin&#xff1a;AC176-264V Vo&#xff1a;5V Io2A Vmax264V*根号2373V PoVo*Io10W η0.8 PinPo/η12.5W DCM变压器&#xff0c;在开关电源的整个输入电压范围内满载工作时都工作在断续模式 CCM变压器&#xff0c;在开关电源的整个输入电压范围内满载工作时都工…

小程序开发的技术难点

小程序开发是一项技术难度较高的工作&#xff0c;需要开发者具备多方面的知识和技能&#xff0c;小程序开发的技术难点主要体现在以下几个方面。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 多端兼容 小程序需要在微信、支付宝…

渗透测试基础(五) 获取WiFi密码

1. 前提条件 需要无线网卡&#xff0c;kali无法识别电脑自带的网卡。 2. 实验步骤&#xff1a; 2.1 查看网卡 命令&#xff1a;airmon-ng 2.2 启动网卡监听模式 命令airmon-ng start wlan0 检查下是否处于监听模型&#xff1a;ifconfig查看一下&#xff0c;如果网卡名加…

ARM64汇编0C - inlinehook

本文是ARM64汇编系列的完结篇&#xff0c;主要利用前面学过的知识做一个小实验 完整系列博客地址&#xff1a;https://www.lyldalek.top/article/arm 这里只讨论 ARM64 下的 inlinehook&#xff0c;做一个简单的demo&#xff0c;只是抛砖引玉&#xff0c;有兴趣了解更多细节的可…

android 13 root

一&#xff1a;修改系统文件 需要修改一些系统文件&#xff0c;以允许adbd进程在root用户下运行&#xff0c;并关闭Verity检查。我们需要修改以下文件&#xff1a; 1.frameworks/base/core/jni/com_android_internal_os_Zygote.cpp 这个文件负责创建应用程序进程&#xff0c…

HTML(13)——显示模式

目录 显示模式 块级元素 行内元素 行内块元素 转换显示模式 显示模式&#xff1a;标签的显示方式 作用&#xff1a;布局网页时&#xff0c;根据标签的显示模式选择合适的标签摆放内容 显示模式 块级元素 独占一行宽度默认为父级的100%添加宽高属性生效 行内元素 …

WordPress主题 酱茄免费主题

酱茄free主题由酱茄开发的一款免费开源的WordPress主题&#xff0c;主题专为WordPress博客、资讯、自媒体网站而设计&#xff0c;遵循GPL V2.0开源协议发布。 运行环境 酱茄Free主题当前版本&#xff1a;2020.11.25 V1.0.0 支持WordPress版本&#xff1a;5.4 兼容Chrome、Fire…

word复制技巧二则

1 纵向复制 按下Alt键&#xff0c;按下鼠标左键拖动&#xff0c;选中要纵向复制的内容&#xff0c;如下图&#xff0c; 再粘贴即可&#xff1b; 2 整页复制 在页的任意位置单击&#xff0c;然后按CtrlA&#xff0c;这会选中整页&#xff1b;然后再复制粘贴即可&#xff1b;

合并github未合并的PR

问题描述 有时候你急需某个PR解决问题&#xff0c;但是官方可能还未合并这个PR&#xff0c;你想合并到自己的分支。 解决方案 方案一&#xff1a;直接用别人的PR仓库 可以在具体的PR详情页面&#xff0c;查看别人的源仓库&#xff0c;将原仓库下载下来编译使用。 方案二&a…

Linux的dev/ 和 sys/ 和 proc/ 目录

linux精神&#xff1a; 一切设备皆文件。 设备被抽象成文件 1、 /dev : 该目录放的设备文件&#xff0c;是应用程序和内核的交互文件&#xff0c;应用程序对这些文件的读写控制可以直接访问到实际的设备 应用程序通过mknod创建的文件&#xff0c;如果底层驱动对mknod的设备号…