redis整理超详细

本文详细介绍了Redis的单线程模型及其优势,包括内存操作、非阻塞I/O多路复用机制,以及如何通过配置I/O多线程提高性能。同时,文章讨论了缓存问题,如缓存穿透、雪崩和击穿,提出了对应的解决方案,并讲解了Redis的键淘汰策略和LRU算法。此外,还涉及了Redis的键删除策略和锁的意外情况处理。
摘要由CSDN通过智能技术生成

 话不多少 先上图

 

Redis支持的五大数据类型包括
String(字符串 用法: 键 值),
Hash(哈希 类似Java中的 map 用法: 键 键值对),
List(列表 用法:键 集合 不可以重复),
Set(集合 用法:键 集合 可以重复),
Zset(sorted set 有序集合 用法: 键 值 值)

单线程,多线程

在一开始的时候,Redis采用的是单线程模型,因为Redis是一个基于内存的数据库,将所有的数据放入内存,所以使用单线程的操作效率是最高的多线程会上下文切换消耗大量时间对于内存系统来说单线程才能产生更高的效率。但是单线程不意味着整个Redis就一个线程Redis其他模块还有各自的线程

Redis基于内存操作,CPU并不是性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽。在6.0的版本中引入了多线程。

这个I/O threads 指的是网络I/O处理方面使用了多线程,如网络数据的读写和协议解析等,这是因为读写网络的read/write在Redis执行期间占用了大部分CPU时间,如果把这部分模块使用多线程方式实现会对性能带来极大地提升。但是Redis执行命令的核心模块还是单线程的。

目前最新的6.0版本中,I/O多线程处理模式需要在配置文件中开启。

单线程为什么快

1.    纯内存操作

2.    单线程操作避免了上下文的切换

3.    采用了非阻塞i/o多路复用机制

Redis大部分操作在内存完成

采用IO多路复用机制

非CPU密集型任务

单线程的优势

Redis大部分操作在内存完成

采用了非阻塞i/o多路复用机制

单线程操作避免了上下文切换导致的性能损耗

避免多线程上下文切换导致的性能损耗

避免多线程访问共享资源加锁导致的性能损耗

所以Redis正是基于有以上这些优点,所以采用了单线程模型来完成请求处理的工作。

雪崩,穿透,击穿

一、缓存穿透

1.问题描述:

在查询一个一定不存在的数据时,由于数据库中没有,不会缓存到redis中,所以缓存百分百不会命中,将去数据库中查询,数据库也没有此记录,循环往复,每次查询缓存无法命中,对数据库(数据存储层)造成压力,失去了缓存的意义。

2.风险:

利用数据库中不存在的数据,进行恶意攻击,数据库瞬时压力增大,导致数据库崩溃。

3.解决办法:

将查询到的null结果也缓存到redis中,并加入短暂的过期时间

最常见的则是采用布隆过滤器,将所有可能存在的数据哈 希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存 储系统的查询压力。

二、缓存雪崩

1.问题描述:

缓存雪崩是设置缓存时,设置了相同的过期时间,在大并发量不间断的访问下,缓存在某一时刻全部失效,此时所有的查询压力都会分配到数据库,数据库瞬时压力过大导致雪崩。

2.解决办法:

在原有的失效时间基础上,增加一个1-5分钟随机值,使其缓存时间不一样,减少重复率,减小数据库查询压力,降低了集体缓存失效的概率。

一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。

给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。

三、缓存击穿

1.问题描述:

对于热点数据来说,在不间断的大并发量情况下,还设置了过期时间,可能在失效的那一瞬间,被高频访问,此时redis中的缓存已经失效,所有查询压力都会落到数据库上,这种现象就叫做缓存击穿。

2.解决办法:

加锁处理。

思路:大量并发前来查询,只让一个线程去数据库查询,其他线程等待,查到后该线程释放锁,其他人获取锁,在获取到锁后,先查寻redis缓存中是否有数据,如果没有为第一个获取到锁的线程,查询数据库;有数据则直接返回。

减少重复率,减小数据库查询压力,降低了集体缓存失效的概率。

Redis key的淘汰策略有哪些

no evictionno ɪˈvɪkʃn

Redis 默认淘汰策略,对于写请求不再提供服务,直接返回错误( DEL 请求和部分特殊请求除外)

all keys - lru

从所有 key 中使用 LRU 算法进行淘汰

volatile - lru

从设置了过期时间的 key 中使用 LRU 算法进行淘汰

all keys - random

从所有 key 中随机淘汰数据

volatile - random

从设置了过期时间的 key 中随机淘汰

volatile - ttl

从设置了过期时间的 key 中,根据 key 的过期时间进行淘汰,越早过期的越优先被淘汰

当使用volatile-lru、volatile-random、volatile-ttl这三种策略时,如果没有key可以被淘汰,则和noeviction一样返回错误

LRU算法

又称最近最少使用算法,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数据替换掉。

key的删除策略

定时删除

含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除

优点:保证内存被尽快释放

缺点:若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key

定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重没人用

惰性删除

含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。

优点:删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了)

缺点:若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)

定期删除

含义:每隔一段时间执行一次删除过期key操作

优点:通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用

缺点:在内存友好方面,不如"惰性删除" 在CPU时间友好方面,不如"定时删除"

难点:合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)(这个要根据服务器运行情况来定了)

redis锁的两种意外

a.如果redis中的锁已经过期了,然后锁过期的那个请求又执行完毕,回来删锁,删除的是其他线程的锁,怎么办?

答案:用key获取value值,判断value值与set时是否一致

b.如果碰巧在查询redis锁还没有删除的时候,正在网络传输时,锁过期了,怎么办?

jedis.eval(“lua”);可与用lua脚本,在查询到key的同时删除该key,防止高并发下的意外的发生

redis内存优化方案 lru

1、缩减key和value的长度。key尽量简写如s:a:id。value不存储不需要数据。

2、开启共享内存池,纯数字数据可以公用内存。但是无法使用过lru的内存淘汰策略

3、如果编辑数据长度变化较大,尽量删除后重新存储。因为redis的预分配机制,追加操作,将会预留更大的存储空间。

4、尽量使用复杂度更低的编码方式,编码方式不可逆。如果数据变简单,情况允许,可以重新创建。

5、控制hash中键的数量。数量最好不要超过1000。因为ziplist编码,超过1000后,cpu消耗增加

先整理到这吧 一句话 想要学好还是要先看底层 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值