极简Redis速成学习

redis是什么?

是一种以键值对形式存储的数据库,特点是基于内存存储,读写快,性能高,常用于缓存、消息队列等应用情境

redis的五种数据类型是什么?

分别是String、Hash、List、Set和Zset(操作命令很多这里只写部分关键的,其他查一查即可)

①String类型



redis中最基本的数据结构,key是String类型,value可以存储字符串、整型或浮点数

SET <KEY> <VALUE>    //写入
GET <KEY>    //读取
②Hash类型 



在value部分提供了一个field作为value的键,因此一个Hash可以存储多个字段和对应的值,适合用来存储对象

HSET <KEY> <FIELD> <VALUE>    //写入
HGET <KEY> <FIELD>        //读取
③List类型

有序可重复,相当于LinkedList,可以从列表的两端进行插入或删除

LPUSH <KEY> <ELEMENT>    //从列表左边插入
LPOP <KEY>        //移除左侧第一个元素
右侧同理,用RPUSH和RPOP
④Set类型

无序不重复

SADD <KEY> <MEMBER>...     //添加一个或多个
SREM <KEY> <MEMBER>...     //删除一个或多个
SCARD <KEY>      //返回元素个数
⑤Zset类型

有序集合,每个元素都带有一个score属性,用score来排序

ZADD <KEY> <SCORE> <MEMBER>...     //添加一个或多个
ZREM <KEY> <MEMBER>...     //删除一个或多个
ZSCORE <KEY> <MEMBER>      //获取指定元素的score值

在Java中怎么使用redis?

我们会用RedisTemplate

使用方法:
①导入依赖

<!--Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--连接池依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

②在application.yml中配置redis

spring:
   redis:
      host:127.0.0.1  # Redis服务器地址
      port:6379   # Redis服务器连接端口
      password:    # Redis服务器连接密码(默认为空)
      lettuce:
        pool:
          max-active:8  #最大连接
          max-idle:8  #最大空闲连接
          min-idle:0   #最小空闲连接
          max-wait:100  #连接等待时间

③在你要的文件中注入RedisTemplate

@Autowired
private RedisTemplate redisTemplate

 ④代码实例

redisTemplate.opsForValue.set(key,value);   //存
String id = redisTemplate.opsForValue.get(key);   //取
redisTemplate.delete(key);    //删除

可以在存数据的时候设置超时时间,避免因为只存出现内存不足的情况(如果不引入超时删除,就会出现redis只存不删的情况,时间长了内存会爆)

redisTemplate.opsForValue.set(key,value,超时时间,超时单位);   //存

可以给已有的键值对设置过期时间

redisTemplate.expire(key,超时时间,超时单位);   

提示:key可以用 : 来分隔,这样可以清楚层级,比如 login:user:code

 

Redis作用


一、redis+session登录校验

二、缓存数据 


优点:降低后端负端,提高读写效率和性能,更好应对高并发
以前的项目中我们是直接访问数据库,众所周知mysql的性能很差,那我们就可以引入redis作为缓存,当用户发起请求时,我们可以先去redis看看有没有对应的数据,如果有我们就直接取用,不用访问数据库了;如果没有我们才去数据库取,同时把读取到的数据写入redis,方便下一次取用

但是会有一个问题:如果redis或者mysql其中一个地方的数据发生更改,没有通知另一个,就会出现redis中的数据和数据库中的数据不一致,也就是redis和数据库的缓存一致性问题

为了解决缓存一致性问题,我们可以使用缓存更新策略 

第一种是内存淘汰,就是redis中存太多了它会自动杀掉
第二种是超时剔除,就是前面的给缓存设置超时时间
第三种是主动更新,就是我们手动添加逻辑,一致性最好,但是也最麻烦
因此我们常常采用主动更新策略,里面又有三种

第一种是旁路缓存,也是最常用的方法:读操作先找缓存,没有再找数据库,然后把数据保存到缓存;写操作就是在更新数据库后删除缓存。这样操作相对最少出问题

第二种是读写穿透,将缓存和数据库整合成一个服务。调用者只需与缓存交互,读操作缓存未命中时,服务从数据库加载数据并写入缓存;写操作时,服务先更新缓存,再同步更新数据库,但是实现难一点,而且对数据库要求高

第三种是异步写回,调用者只操作缓存,然后缓存再异步更新到数据库中,有可能出现一致性问题

三、缓存穿透等问题

(1)缓存穿透

缓存穿透就是指用户请求的数据在缓存和数据库中都不存在(比如乱传一个id),那么因为缓存没有这个数据,每次请求都会打到数据库,然后数据库返回一个null;如果有人故意大量制造这样的请求,就会有大量的请求直接打到数据库,导致数据库崩溃,这就是缓存穿透问题

解决缓存穿透有主要两种方法:

缓存空对象,如果用户请求一个在缓存和数据库中都不存在的数据,那就缓存null值,当下一次再请求,就直接返回null。但我觉得没什么鸟用因为只要请求一直换他就要在redis一直新增缓存直接爆炸

布隆过滤 在请求到达缓存前,先用布隆过滤器进行判断,存在就放行,不存在就拒绝

其余方法有加强权限校验,设置限流等

(2)缓存雪崩

缓存雪崩是指同一时间大量的key失效或者redis直接宕机导致大量的请求直接打到数据库

解决方法:

① 给不同的key添加不同的TTL随机值
② 用redis集群 主从机制 哨兵检测 主挂了就换一个从上
③ 使用多级缓存
④ 做限流

(3)缓存击穿

缓存击穿是指某些被大量访问且缓存重建复杂的热点key失效了,导致大量的请求直接打到数据库

解决方法:

①互斥锁

当大量请求来到时,只让第一个到达的线程进行缓存的重建,此时其余请求会被卡住,直到这个缓存重建完成,优点是返回的数据是准确的,缺点是性能差
对于第一个线程:获得互斥锁,进行缓存重建
对于后面的线程:获取不到互斥锁,休眠,过段时间重试

②逻辑过期

热点key永不过期,但是要设置一个过期时间的字段(不是设置过期时间)。当请求到达时会根据过期时间的字段进行判断,如果过期了,那就用互斥锁,创建一个新的线程单独负责缓存的重建,而它和其余线程直接返回当前key的数据(也就是错误的旧数据),优点是线程无需等待性能好,缺点是数据一致性差
对于第一个线程:判断缓存是否过期,如果过期,获得互斥锁,新建一个进程进行缓存重建,自己先返回旧的数据
对于后面的线程:获取不到互斥锁,直接先返回旧的数据

提示:在获取到锁后最好再进行一次判断

(4)超卖问题

超卖问题就是比如有一个秒杀活动,此时大量的线程发起购买请求,线程a查到库存为1,线程b查到库存也为1,然后线程a调用请求会让库存 -1,而线程b不知道(因为查到的库存为1),所以也会让库存 -1,本来库存只有1,现在却触发了两次扣减库存,让库存为 -1,这就是超卖问题

解决方法:加锁

①悲观锁

悲观指认为线程安全问题一定会发生。因此在操作数据之前需要先获取锁,让这些线程串行执行,优点是不出错,缺点是性能差
synchronized、lock都属于悲观锁

②乐观锁

乐观指认为线程安全问题不一定发生,不加锁,只在数据进行更新操作时检查在此期间数据是否被更改
乐观锁的方法通常会给数据额外引入一个标识(比如版本号或者时间戳)来标记数据是否被更改
对于一个线程来说,去更新时发现如果数据已被更改就更新失败;否则更新成功

但是这些只在单一服务下好用,多集群就失效了,要用分布式锁

四、Redis分布式锁

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ADC采集模块与MCU内置ADC性能对比

2.5V基准电压源&#xff1a; 1. 精度更高&#xff0c;误差更小 ADR03B 具有 0.1% 或更小的初始精度&#xff0c;而 电阻分压方式的误差主要来自电阻的容差&#xff08;通常 1% 或 0.5%&#xff09;。长期稳定性更好&#xff0c;分压电阻容易受到温度、老化的影响&#xff0c;长…

python数据容器切片

从一个序列中取出一个子序列 序列[起始位置:结束位置:步长] 起始位置和结束位置 省略,表示从头取到尾 步长省略表示1 步长负数,表示从后往前取 步长-1 等同于将序列反转了

【网络安全 | 渗透测试】GraphQL精讲一:基础知识

未经许可,不得转载, 文章目录 GraphQL 定义GraphQL 工作原理GraphQL 模式GraphQL 查询GraphQL 变更(Mutations)查询(Queries)和变更(Mutations)的组成部分字段(Fields)参数(Arguments)变量别名(Aliases)片段(Fragments)订阅(Subscriptions)自省(Introspecti…

005-Docker 安装 Redis

Docker 安装 Redis 1.从镜像官网拉取Redis镜像2.创建实例并启动3.测试连接4.设置开机启动 1.从镜像官网拉取Redis镜像 镜像官网地址&#xff1a;https://hub.docker.com执行命令 -- 拉取最新的版本 docker pull redis查看镜像 docker images2.创建实例并启动 先创建好需要的…

【星云 Orbit • STM32F4】04.一触即发:GPIO 外部中断

【星云 Orbit- • STM32F4】04. 一触即发&#xff1a;外部中断控制 摘要 本文详细介绍了如何使用STM32F407微控制器的HAL库实现外部中断功能。通过配置GPIO引脚作为外部中断源&#xff0c;并在中断回调函数中处理按键事件&#xff0c;实现了按键控制LED状态翻转的功能。本文旨…

探索Elasticsearch:索引的CRUD

在企业环境中&#xff0c;Elasticsearch的索引CRUD&#xff08;创建Create、读取Read、更新Update、删除Delete&#xff09;操作是非常基础且频繁使用的功能。这些操作对于管理和维护数据至关重要&#xff0c;尤其是在处理大规模数据集和需要实时搜索与分析的应用场景中。 目录…

React antd的datePicker自定义,封装成组件

一、antd的datePicker自定义 需求&#xff1a;用户需要为日期选择器的每个日期单元格添加一个Tooltip&#xff0c;当鼠标悬停时显示日期、可兑换流量余额和本公会可兑流量。这些数据需要从接口获取。我需要结合之前的代码&#xff0c;确保Tooltip正确显示&#xff0c;并且数据…

NVIDIA GPU 架构详解:Pascal、Volta、Turing、Ampere、Ada、Hopper、Blackwell

目录 1. Pascal&#xff08;帕斯卡&#xff09;架构&#xff08;2016&#xff09;关键技术性能特性代表产品应用场景 2. Volta&#xff08;伏特&#xff09;架构&#xff08;2017&#xff09;关键技术性能特性代表产品应用场景 3.Turing&#xff08;图灵&#xff09;架构&#…

Linux 命令行的基本命令(生信)

常见的操作系统包括 Windows、Mac OS X 和 Unix 。Linux 是类 Unix 操作系 统&#xff0c; 可安装在各种各样的电脑硬件设备&#xff0c; 从手机、平板电脑、路由器到超级计算 机。Linux 是一个领先的操作系统&#xff0c;世界上最快的十台超级计算机运行的都是 Linux 操作系统…

ECharts--中国地图(无敌详细)

前段时间需要做一个中国地图的页面&#xff0c;要求是展示各地产品的销量&#xff0c;我就在网上搜了很多ECharts的资料&#xff0c;学习了一下怎么使用。 本着互相学习&#xff0c;共同进步的原则&#xff0c;特此分享一下自己的学习经验以及使用技巧。如果有用的话可以给老弟…

QwenVL 2.5-本地安装编译布署全教程

开篇 DeepSeek开源后我国又开源了一个震撼大模型,QwenVL2.5,这是一个多模态的模形,它可以认图、识图、更能作图,还能读懂video。 Qwen2.5-VL 的主要特点如下所示: 感知更丰富的世界:Qwen2.5-VL 不仅擅长识别常见物体,如花、鸟、鱼和昆虫,还能够分析图像中的文本、图表…

【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现

项目介绍 本课程演示的是一款 基于SpringBoot电脑DIY装机教程网站的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…

React高级内容探索

flushSync确保了DOM立即更新 flushSync让你强制React同步刷新提供回调中的任何更新&#xff0c;这确保了DOM立即更新 flushSync是DOM更新之后的&#xff0c;像vue中的nextTick&#xff1a; import { useState,useRef} from "react" import { flushSync} from &quo…

基于 MetaGPT 自部署一个类似 MGX 的多智能体协作框架

MGX&#xff08;由 MetaGPT 团队开发的 mgx.dev&#xff09;是一个收费的多智能体编程平台&#xff0c;提供从需求分析到代码生成、测试和修复的全流程自动化功能。虽然 MGX 本身需要付费&#xff0c;但您可以通过免费服务和开源项目搭建一个类似的功能。以下是一个分步骤的实现…

主时钟与虚拟时钟约束

1、主时钟约束 1.1、主时钟约束语法&#xff1a; create_clock -name< clock_name > -period <period> -waveform{ <rise_time> <fall_time> } [get_ports< port_name >] 说明&#xff1a; name 之后的<clock_name> 是clk 的name&a…

CyberRT(apollo) 定时器模块简述及bug分析

timer 模块 timer的定义&#xff0c;cyberrt中timer模块用于设置定时器任务&#xff0c;字面意思&#xff0c;设置设置定时周期及出发频次&#xff08;周期 or oneshot)&#xff0c;到达指定时间时间触发callback time wheel 时钟节拍轮&#xff0c;常见的定时器设计&#x…

网络安全月度报告

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 3.1.1网络安全现状及安全挑战 网络的出现给人们的工作和生活带来了极大的便利&#xff0c;但同时也带来了极大的安全风险。在信息传输和交换时&#xff0c;需要对…

nio多线程版本

多线程多路复用 多线程NIO&#xff0c;&#xff0c;就是多个线程&#xff0c;每个线程上都有一个Selector&#xff0c;&#xff0c;&#xff0c;比如说一个系统中一个线程用来接收请求&#xff0c;&#xff0c;剩余的线程用来读写数据&#xff0c;&#xff0c;每个线程独立干自…

一周学会Flask3 Python Web开发-Flask3之表单处理WTForms安装与定义WTForms表单类

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们平时开发项目&#xff0c;都会用到表单&#xff0c;编写表单&#xff0c;提交表单&#xff0c;验证表单&#xff0c;如果…

基于NI USRP 硬件的下一代O-RAN研究测试台​

目录 基于NI SDR硬件的下一代O-RAN研究测试台​挑战&#xff1a;解决方案&#xff1a; 基于NI SDR硬件的下一代O-RAN研究测试台​ “OAIC提供了一个开放平台&#xff08;包括软件架构、库和工具集&#xff09;&#xff0c;用于对基于AI的无线接入网(RAN)控制器进行原型开发和测…