redis 入门,一起学习redis

news/2024/11/15 5:45:53/

文章目录

  • 一、什么是redis? redis的作用?
  • 二、redis的特点
  • 三、redis的基本数据结构类型
  • 四、redis 的三种特殊数据类型
  • 五、redis 作为缓存
  • 六、redis 作为缓存存在的问题
    • 6.1 数据一致性
    • 6.2 缓存雪崩
    • 6.3 缓存穿透
    • 6.4 缓存击穿
  • 七、redis为什么那么快?
  • 八、redis的过期策略
  • 九、redis 内存淘汰策略
  • 十、redis持久化


redis_redis_3">一、什么是redis? redis的作用?

Redis 英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,可以用来做数据库、缓存、消息中间件等场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库
它的读写速度非常快,每秒可以处理超过10万次读写操作。经常用来做分布式锁,支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。

redis_6">二、redis的特点

  • 优秀的性能,数据是存储在内存中,读写速度非常快,可支持并发10W QPS
  • 单线程但进程,是线程安全的,采用IO 多路复用制
  • 可作为分布式锁
  • 支持五种数据类型
  • 支持数据持久化到磁盘
  • 可以作为消息中间件使用,支持消息发布及订阅

redis_13">三、redis的基本数据结构类型

在这里插入图片描述
它还有三种特殊的数据结构类型

  • Geospatial
  • Hyperloglog
  • Bitmap

redis__19">四、redis 的三种特殊数据类型

Geo:Redis3.2推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。
HyperLogLog:用来做基数统计算法的数据结构,如统计网站的UV。
Bitmaps :用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组

redis__23">五、redis 作为缓存

数据缓存是Redis最重要的一个场景,为缓存而生,在springboot中,一般有两种使用方式:

  • 直接通过RedisTemplate使用
  • 通过Spring Cache集成Redis(也就是注解的方式)

redis__27">六、redis 作为缓存存在的问题

6.1 数据一致性

在分布式环境下,缓存和数据库很容易出现数据一致性问题,如果项目对缓存的要求是强一致性,那就不要使用缓存。
我们只能在项目中使用策略降低缓存与数据库一致性的概率,是无法保障两者的强一致性,一般策略包括缓存更新机制,更新数据库后及时更新缓存、缓存失败时增加重试机制等方式。

6.2 缓存雪崩

假设A系统每秒需要处理5000个请求,但数据库每秒只能处理4000个请求,某一天,缓存机器出现了宕机,挂了,这时候所有的请求一下子全部落在数据库上,数据库肯定扛不住,报警挂掉了,这时候如果没有采取缓存设施,数据库又急着用,重新重启数据库,刚重启完成(有可能没启动完),请求又来,数据库立马挂掉。这就是雪崩事件,是Redis缓存中最致命问题之一(有一个是穿透)。
在这里插入图片描述
我们可以在事故前中后三个方面来思考解决方案

  • 事故前redis高可用方案,主从+哨兵,集群方案,避免全盘崩溃
  • 事故中:较少数据库的压力,本地Ehcache缓存+限流及降级,避免超过数据库承受压力
  • 事故后:做redis持久化,一旦Redis重启,可从磁盘中快速恢复数据
    改造后的数据流程,假设用户A发送一个请求,系统先请求本地Ehcache是否有数据,如果没有再去Redis请求数据,如果没有再去数据库请求数据,获取到数据后同步到Ehcache和redis
    限流的作用:可以设置每秒请求数次,有多少通过请求,剩余的未通过的可以走降级处理,返回一些默认的值,或者友情提示等默认操作。具体流程可以看看下图:
    在这里插入图片描述
    数据库安全:在限流组件可用的情况下,数据库不会挂掉,限流根据确保了每秒多少请求能通过。
    部分请求可以被处理数据库没挂,就意味着至少2/5的请求可以被处理掉
    高峰时期部分请求无法处理到,需要用户多次点击,因为只有2/5的请求被处理,剩下的请求,用户刷不出来界面,需要多点击几次
    redis设置的缓存失效时间不是设置成同一个时间,可根据功能、业务、请求接口灵活设置缓存时间:setRedis(key, value, time+Math.random()*10000)。

6.3 缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,用户(黑客)不断发起请求,导致请求直接查询数据库,这种恶意行为攻击场景的会直接导致数据库挂掉。
在这里插入图片描述
可以采取以下方案:

  • 在请求接口层可以做一些校验,比如用户签权、参数校验,不合法的请求直接return。
  • 还可以针对有效id做认证或直接拦截,不符合的id直接过滤或采用统一key保存到redis,下次不合法的id请求时,直接到缓存中获取数据。
  • 采用redis的高级接口Bloom Filter,利用高效的数据结构和算法快速判断出你这个 Key 是否在数据库中存在,不存在你return 就好了,存在你就去查 DB 刷新 KV 再 return。

6.4 缓存击穿

穿透是针对大面积数据请求,那么击穿是针对一点(一个key)来来导致redis异常,但某个key是非常热点,请求非常频繁,处于集中式访问现象,当这个key失效(过期)时,大量的请求就会击穿了缓存,直接请求数据库,就像在屏障中凿开了一个洞。
不同场景下缓存击穿解决方案
数据基本不变:热点数据value基本不更新时,可以设置成永不过期
数据更新不频繁:缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。
数据更新频繁:采用定时线程,在缓存过期前主动重新构建缓存或延长过期时间,保证所有的请求能一直访问缓存

redis_59">七、redis为什么那么快?

redis 是单进程单线程的模型,完全基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈是内存及网络带宽,有以下特点:

  • 使用类似于HashMap的原理,HashMap的查询及操作的时间复杂度是O(1),且绝大多数请求是纯碎的内存操作,数据存在内存中。
  • 数据结构简单,对数据操作也简单,基于KV。
  • 不错死锁现象采用单线程操作,避免了不必要的上下文切换及竞争条件,不存在CPU切换现象,也就不存在考虑各种锁的问题。
  • 使用非阻塞IO,多路复用IO模型。

redis_66">八、redis的过期策略

我们在set key的时候,可以给它设置一个过期时间,比如expire key 60。指定这key60s后过期,60s后,redis是如何处理的嘛?我们先来介绍几种过期策略:
定时过期
每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
惰性过期
只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
定期过期
每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。
Redis中同时使用了惰性过期和定期过期两种过期策略。

  • 假设Redis当前存放30万个key,并且都设置了过期时间,如果你每隔100ms就去检查这全部的key,CPU负载会特别高,最后可能会挂掉。
  • 因此,redis采取的是定期过期,每隔100ms就随机抽取一定数量的key来检查和删除的。
  • 但是呢,最后可能会有很多已经过期的key没被删除。这时候,redis采用惰性删除。在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除。

但是呀,如果定期删除漏掉了很多过期的key,然后也没走惰性删除。就会有很多过期key积在内存内存,直接会导致内存爆的。或者有些时候,业务量大起来了,redis的key被大量使用,内存直接不够了,运维小哥哥也忘记加大内存了。难道redis直接这样挂掉?不会的!Redis用8种内存淘汰策略保护自己~

redis__83">九、redis 内存淘汰策略

volatile-lru:当内存不足以容纳新写入数据时,从设置了过期时间的key中使用LRU(最近最少使用)算法进行淘汰;
allkeys-lru:当内存不足以容纳新写入数据时,从所有key中使用LRU(最近最少使用)算法进行淘汰。
volatile-lfu:4.0版本新增,当内存不足以容纳新写入数据时,在过期的key中,使用LFU算法进行删除key。
allkeys-lfu:4.0版本新增,当内存不足以容纳新写入数据时,从所有key中使用LFU算法进行淘汰;
volatile-random:当内存不足以容纳新写入数据时,从设置了过期时间的key中,随机淘汰数据;。
allkeys-random:当内存不足以容纳新写入数据时,从所有key中随机淘汰数据。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的key中,根据过期时间进行淘汰,越早过期的优先被淘汰;
noeviction:默认策略,当内存不足以容纳新写入数据时,新写入操作会报错。

redis_92">十、redis持久化

Redis 持久化策略有两种:

  • RDB:快照形式是直接把内存中的数据保存到一个 dump 的文件中,定时保存,保存策略。
  • AOF:把所有的对 Redis 的服务器进行修改的命令都存到一个文件里,命令的集合。Redis 默认是快照 RDB 的持久化方式。

如果非常关心你的数据,但仍然可以承受数分钟内的数据丢失,那么可以额只使用 RDB 持久。
AOF 将 Redis 执行的每一条命令追加到磁盘中,处理巨大的写入会降低Redis的性能,不知道你是否可以接受。
数据库备份和灾难恢复:定时生成 RDB 快照非常便于进行数据库备份,并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度快。
当然了,Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。
本文参考:一文读懂Redis
感谢您的观看,希望对您有帮助,发财的小手点点赞,点点关注~


http://www.ppmy.cn/news/1508723.html

相关文章

C语言——预处理详解(下)

目录 前言 #和## 1.#运算符 2.##运算符 命名约定 #undef 命令行定义 条件编译 1.单分支条件编译 2.多分支条件编译 3.判断是否被定义 4.嵌套指令 头文件的包含 1.头文件被包含的方式 (1)本地文件包含 (2)库文件包含 2.嵌套文件包含 其他预处理指令 1.#error…

第三章 zookeeper+kafka群集

消息队列 概念 消息(Message)是指在应用间传送的数据消息队列(Message Queue)是一种应用间的通信方式解决方法,确保消息的可靠传递 特征 存储 将消息存储在某种类型的缓冲区中,直到目标进程读取这些消…

【HarmonyOS NEXT星河版开发学习】小型测试案例11-购物车数字框

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面(暂未发布) 前言 经过一周的学习,我发现还是进行拆分讲解效果会比较好,因为鸿蒙和前端十分的相识。主要就是表达的方式不同罢了…

设计模式-单例设计模式

单例模式的设计和线程安全 单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。实现单例模式时,线程安全性是一个重要考虑因素,特别是在多线程环境中。 1. C11 之前的线程安全实现 在 C11 之前&#…

电商平台的推荐算法需要备案吗?

答案是肯定的! 政策要求: 根据我国《互联网信息服务算法推荐管理规定》(以下简称《规定》)第六条,具有舆论属性或社会动员能力的互联网信息服务,包括电商平台的推荐算法,需要进行备案。 电商平…

Openlayers6 图形绘制和修改功能(结合React)

Openlayers常用的API了解的差不多了,就开始进入实战了,首先从绘制基本的图形开始,这里主要介绍一下绘制圆形、矩形和多边形。 通过使用openlayers的ol.interaction.Draw和ol.interaction.Modify模块实现地图上绘制圆形、矩形、多边形并修改编…

C++ 函数语义学——inline 函数回顾和扩展

inline 函数回顾和扩展 inline 函数回顾和扩展 inline 函数回顾和扩展1. inline 函数回顾2. inline 扩展总结 1. inline 函数回顾 inline 函数即有优点又有缺点,优点是它的执行成本一般比常规的函数调用和函数返回所带来的成本低,提高了程序执行效率&am…

05_ Electron 自定义菜单、主进程与渲染进程通信

Electron 自定义菜单、主进程与渲染进程通信 一、定义顶部菜单二、Electron 自定义右键菜单1、使用 electron/remote 模块实现 三、 Electron 主进程和渲染进程通信场景1:渲染进程给主进程发送异步消息场景2:渲染进程给主进程发送异步消息,主…