redis在日常开发工作中的常见用法
redis是一款内存型数据库,在开发工作中经常用到,功能强大;
特别开一篇文章用来记录一下它的常见用法,算是一种总结;
它最主要的特点就是高可用的,速度快,分布式;有人说速度快,能有我本地的全局静态变量快?但是在大型的项目中,多个服务器部署时,其他服务实例节点如何获取到你单个节点JVM中存储的这个全局静态变量?数据不一致怎么办?如果只是用来读取还好,但凡涉及到修改,都建议使用redis管理这部分常用而又准备的数据;
日常的工作可以是为某个业务功能开发,也可以是单纯的为实现某一项自认为的技术开发;
我总结了下一些常用的场景:
1、用于分布式的数据锁
在一个告警的模块,我们对单个对象的告警消息提示要做频率限制,不然会导致频繁推送单个对象的告警消息;例如:单个对象在10分钟内,最多仅可提示一条消息;代码片段如下:
//如果最近10分钟内已推送信息,则跳过
if (!redisTemplate.opsForValue().setIfAbsent(PARK_COUPON_ERROR_REDIS_KEY + order.getId(), 1, errmsgInterval, TimeUnit.SECONDS)) {continue;
}
在一个抽奖秒杀的功能中,我用redis来防止用户频繁点击,超过活动限定次数的抽奖,避免数据错乱的情况;
//避免 单用户频繁点击
Boolean setIfAbsent = redisTemplate.opsForValue().setIfAbsent(userKey, LocalDateTime.now().toString(), Duration.ofSeconds(10));
if (ObjectUtil.isNotEmpty(setIfAbsent) && !setIfAbsent) {log.info("单用户加redis失败 ,耗时{}ms", stopwatch.getTotalTimeMillis());throw new ServiceException("请勿频繁点击领券");
}
2、用于内存存储高频调用数据
在redis中存储高频数据的作用非常大,可以有效地降低程序的处理时间;但是一般建议将该模块设计巧妙一些,而不是一股脑将所有数据全部扔进去;redis是内存数据库,比通过mysql查询的效率往往高得多,因此可以提高程序的处理效率,且对于高频的查询数据放入redis中可以减少mysql的查询压力;
例如:秒杀活动中的奖品,打乱一次性存入队列,后续抽奖按顺序取出即可;不用查询MySQL
//将抽奖的随机性转移到奖品元素入队顺序的随机性
Collections.shuffle(prizeList);
redisTemplate.opsForList().leftPushAll(LOTTERY_LOTTERY_PRIZE + lotteryId, prizeList);
例如:抽奖活动中,用户再次点击,判断用户是否还剩余抽奖的权限,而不用查询数据库,对于这种限制一天一次,或者限制一周N次这样的情况;
List<ChargingUserMarketingCoupon> userCouponList = chargingUserMarketingCouponService.list(new QueryWrapper<ChargingUserMarketingCoupon>().lambda().
eq(ChargingUserMarketingCoupon::getMarketingId, lotteryId).
eq(ChargingUserMarketingCoupon::getUserId, SecureUtil.getUserId()).
ge(ChargingUserMarketingCoupon::getCreateTime, start).
le(ChargingUserMarketingCoupon::getCreateTime, end));
String key = LOTTERY_USER_DELIVERY_NUM + ":" + lotteryId + ":" + DateUtil.format(start, "yyyyMMdd") + ":" + AuthUtil.getUserId();
redissonClient.getAtomicLong(key).set(userCouponList.size());
可以巧妙设计KEY,来实现对单个对象,某个日期中抽奖次数的存储和更新;
3、用于实现一些特殊的场景
例如:抽奖活动,使用队列一次性将奖品全部入队,然后再出队列,便不用查询数据库,且可以方便实现队列出完就识别为抽奖活动结束的逻辑;
Object o = null;try {o = redisTemplate.opsForList().leftPop(LOTTERY_LOTTERY_PRIZE + lottery.getId(), 1, TimeUnit.SECONDS);} catch (Exception e) {e.printStackTrace();throw new ServiceException("当前抽奖人数过多,请稍后重试!");}//仍然为NULL,则说明奖品发放完毕,leftPop操作没有元素if (ObjectUtils.isEmpty(o)) {throw new ServiceException("本次活动奖品已发放完毕,请关注下次活动!");}
这里需要注意,redis中的队列元素在出队完毕后,key会自动删除的;此时可能会报错,而不是取出NULL数据,开发时踩过坑;
就记录这么多吧,要搬砖了;
总之一句话,就是合理使用redis的各大数据结构和特性,来实现产品的特殊功能;
开发过程中要考虑周到,对于redis中数据存入后仅读取的情况还好,对于要频繁修改的数据还要考虑多线程并发等的问题;注意开发过程中可能的踩坑;
相关文章:
redis在日常开发工作中的常见用法
redis是一款内存型数据库,在开发工作中经常用到,功能强大; 特别开一篇文章用来记录一下它的常见用法,算是一种总结; 它最主要的特点就是高可用的,速度快,分布式;有人说速度快&…...
小程序实现下拉刷新
小程序实现下拉刷新可以通过使用组件scroll-view和事件onPullDownRefresh来实现。 scroll-view组件的使用 在需要下拉刷新的页面的wxml文件中,通过scroll-view组件包裹需要滚动的内容,设置scroll-y属性为true,表示允许竖向滚动。示例代码如…...
Day 36 贪心算法 part05 : 435. 无重叠区间 763.划分字母区间 56. 合并区间
56. 合并区间 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1: 输入:inte…...

使用Python将网页数据保存到NoSQL数据库的方法和示例
随着大数据和人工智能技术的快速发展,对于大规模数据的处理需求日益增多。NoSQL数据库作为一种新兴的数据存储解决方案,具有高可扩展性、高性能和灵活性数据模型等优势,已经在许多行业得到广泛应用。传统的关系型数据库在处理海量数据时可能会…...

两个路由器如何连接设置的方法攻略
一、前言 随着智能家居时代来临,家里的网络部署需求开始复杂起来。往往一个路由器已经不能满足需求或者不利于拓展。两个路由器连接最常见的情况是家中已有一个路由器,并且已经通过这个路由器来正常上网。现在是因某些原因想在不改变已经在用的路由器的设…...

分类任务评价指标
分类任务评价指标 分类任务中,有以下几个常用指标: 混淆矩阵准确率(Accuracy)精确率(查准率,Precision)召回率(查全率,Recall)F-scorePR曲线ROC曲线 1. 混…...
c++静态成员
目录 静态成员 静态成员变量 静态成员函数 const 静态成员属性 静态成员实现单例模式 静态成员 在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字 static 声明为静态的,称为静态成员。 不管这…...

go-zero直连与etcd服务注册中心
go-zero中直连方式 在使用grpc是最重要的就是pb文件了,生成的pb文件,通过pb文件可以生成grpc的客户端和服务端,那么客户端和服务端就可以直连了,再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写,包…...
Kotlin File writeText appendText appendBytes readBytes readText
Kotlin File writeText appendText appendBytes readBytes readText import java.io.Filefun main(args: Array<String>) {val filePath "./myfile.txt"val file File(filePath)file.writeText("hello,") //如果原有文件有内容,将完全覆…...

常见缺少msvcp140.dll问题及解决方法,分享多种方法帮你解决
在日常使用电脑的过程中,我们可能会遇到各种问题,比如电脑提示msvcp140.dll文件丢失。这个问题通常是由于某些程序或游戏需要这个dll文件来正常运行,但是由于某种原因,这个文件被误删或者损坏了。那么,如何解决这个问题…...

【K210+ESP8266图传上位机开发】TCP server + JPEG图像解析上位机开发
本文章主要记录基于 【K210-ESP8266】 图传和显示的过程,上位机开发过程,系统架构和下位机开发请参考文章: 【K210-ESP8266】开发板上传图像数据到服务器并实时显示 💖 作者简介:大家好,我是喜欢记录零碎知…...
Linux查看当前文件夹的大小
在Linux中,可以使用du(disk usage)命令来查看当前文件夹的大小。以下是一些使用du的方法: 查看当前文件夹的大小: 为了查看当前文件夹的总大小,可以在文件夹中运行: du -sh .这里: -…...

YOLO目标检测——密集人群人头数据集+已标注yolo格式标签下载分享
实际项目应用:城市安防、交通管理、社会研究、商业应用、等多个领域数据集说明:YOLO密集人群人头目标检测数据集,真实场景的高质量图片数据,数据场景丰富,图片格式为jpg,共4300张图片。标注说明:…...

论文精读 —— Gradient Surgery for Multi-Task Learning
文章目录 Multi-task Learning和 PCGrad 方法简介论文信息论文核心图摘要翻译引言翻译2 使用PCGrad进行多任务学习2.1 基本概念:问题和符号表示2.2 三重悲剧:冲突的梯度,主导的梯度,高曲率2.3 PCGrad:解决梯度冲突2.4 …...

【VS Code插件开发】常见自定义命令(七)
🐱 个人主页:不叫猫先生,公众号:前端舵手 🙋♂️ 作者简介:前端领域优质作者、阿里云专家博主,共同学习共同进步,一起加油呀! 📢 资料领取:前端…...
Spring Cloud服务发现与注册的原理与实现
Spring Cloud服务发现与注册的原理与实现 一、简介1 服务发现的定义2 服务发现的意义 二、Spring Cloud服务注册与发现的实现1 Spring Cloud服务注册1.1 服务注册的基本框架1.2 服务注册的实现方式 2 Spring Cloud服务发现2.1 服务发现的基本框架2.2 服务发现的实现方式 三、Sp…...

FFmpeg入门之简单介绍
FFmpeg是什么意思: Fast Forward Moving Picture Experts Group ffmpeg相关文档: Documentation FFmpeg ffmpeg源码下载: https://git.videolan.org/git/ffmpeg.git https://github.com/FFmpeg/FFmpeg.git FFmpeg能做什么? 多种媒体格式的封装与解封装 : 1.多种音…...

新版DBeaver调整编辑窗口字体大小
网上有DBeave字体设置了,但看了下,目前最新版的已经更改了首选项分组,层级发生了变化,这里记录一下2022.08.21版的设置。 默认字体是10,比较小,改为11或更大会好看些。...

《vue3实战》运用push()方法实现电影评价系统的添加功能
目录 前言 电影评价系统的添加功能是什么? 电影评价系统的添加功能有什么作用? 一、push()方法是什么?它有什么作用? 含义: 作用: 二、功能实现 这段是添加开始时点击按钮使…...

JavaScript学习笔记02
JavaScript笔记02 数据类型详解 字符串 在 JavaScript 中正常的字符串都使用单引号 或者双引号" "包裹:例: 转义字符 在 JavaScript 字符串中也可用使用转义字符(参考:详解转义字符):例&…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...