Redis 介绍及各类策略、问题解决

Redis 介绍及各类策略、问题解决

绿林寻猫
2021-12-08 / 0 评论 / 238 阅读 / 正在检测是否收录...

目录

 

一、Redis介绍

 

1.1数据类型

 

1.2优缺点

 

二、为什么要使用Redis/缓存?

2.1高性能

 

2.2高并发

三、持久化

3.1什么是持久化?

3.2持久化机制

3.2.1Redis DataBase(简称RDB)

 

3.2.3Append-only file (简称AOF)

四、Redis过期键的删除策略

4.1常见删除策略

五、Redis内存淘汰策略

5.1全局的键空间选择性移除

5.2设置过期时间的键空间选择性移除

六、缓存异常

6.1缓存雪崩

6.2缓存穿透

6.3缓存击穿


一、Redis介绍

简单来说Redis是一款高性能非关系型的键值对数据库。与传统数据库不同的是Redis的数据是存储在内存中,所以读写速度非常快。因此被广泛应用于缓存方面,每秒可处理超过10W次的读写操作,Redis也经常用来做分布式锁,此外,Redis支持事务、持久化、LUA脚本、LRU驱动事件、多集群方案。

Redis可以存储键和五种不同类型的值之间的映射,键类型只能为字符串,支持五种数据类型:String、List、Set、ZSet、Hash。

 

1.1数据类型

数据类型可以存储的值操作应用场景
STRING字符串、整数或者浮点数对整个字符串或者字符串的其中一部分执行操作
对整数和浮点数执行自增或者自减操作
做简单的键值对缓存
LIST列表从两端压入或者弹出元素
对单个或者多个元素进行修剪,
只保留一个范围内的元素
存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的数据
SET无序集合添加、获取、移除单个元素
检查一个元素是否存在于集合中
计算交集、并集、差集
从集合里面随机获取元素
交集、并集、差集的操作,比如交集,可以把两个人的粉丝列表整一个交集
HASH包含键值对的无序散列表添加、获取、移除单个键值对
获取所有键值对
检查某个键是否存在
结构化的数据,比如一个对象
ZSET有序集合添加、获取、删除元素
根据分值范围或者成员来获取元素
计算一个键的排名
去重但可以排序,如获取排名前几名的用户

 

1.2优缺点

优:

  • 读写速度快

  • 支持数据持久化,AOF和RDB两种方式

  • 支持事务

  • 数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离

缺:

  • 数据库受物理内存限制,不适合海量数据高性能读写,一般作用于小数据量的高性能操作和运算

  • Redis不具备自动容错和恢复功能,主从机的宕机都有可能造成读写失败,需等待重启或前端手动更改IP才能恢复

  • 主机宕机前有部分数据未能同步到从机,切换IP后有可能造成数据不一致的问题,降低了系统可用性能

  • Redis较难支持在线扩容,在集群容量达到上限后在线扩容会变得复杂,运维人员得在运行前确保有足够的容量

 

二、为什么要使用Redis/缓存?

 

2.1高性能

如用户第一次获取数据时是从数据库获取,因数据是从硬盘上读取,相对缓慢一些。将此次请求数据存于缓存,再次访问数据时是从缓存中获取,是直接操作内存,速度相对会快很多。如果数据库中数据发生变化,则把相应Key缓存数据删除,下次获取数据又会和第一次获取数据一样,且确保数据是最新数据。

 

2.2高并发

直接操作缓存请求远远大于直接请求数据库,以秒杀/抢红包为例,在活动开始前把数据存储在缓存中,活动结束后再同步redis数据到数据库。

三、持久化

 

3.1什么是持久化?

持久化就是将数据存储到磁盘,以防宕机数据丢失无法恢复。

 

3.2持久化机制

 

3.2.1Redis DataBase(简称RDB)

执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中

优点:性能较高(因为是快照,且执行频率比aof低,而且rdb文件中直接存储的是key-values的二进制形式,对于恢复数据也快)使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能

缺点:在save配置条件之间若发生宕机,此间的数据会丢失

RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候

 

3.2.3Append-only file (简称AOF)

执行机制:将对数据的每一条修改命令追加到aof文件

优点:数据不容易丢失

可以保持更高的数据完整性,如果设置追加file的时间是1s,如果redis发生故障,最多会丢失1s的数据;且如果日志写入不完整支持redis-check-aof来进行日志修复;AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)

缺点:性能较低(每一条修改操作都要追加到aof文件,执行频率较RDB要高,而且aof文件中存储的是命令,对于恢复数据来讲需要逐行执行命令,所以恢复慢)

AOF文件比RDB文件大,且恢复速度慢。

 

四、Redis过期键的删除策略

 

4.1常见删除策略

定时删除:每个设置过期时间的Key都会创建一个定时器,到期就会定时删除,该策略会立即删除过期数据,对内存很友好。但是相对的会占用大量的CPU资源去处理过期数据处理,从而会影响缓存响应时间及吞吐量。

惰性删除:对CPU来说是最友好,只会在程序读取该数据时校验数据是否存在,不存在就删除。但是相对的对内存来说不友好,比如一些已经过去的数据,不去读取时永远不知道是否过期,更不会删除,这个键就一直存在,占用着内存资源。

定期删除:就是前两种策略的整合和折中,每隔一段时间程序执行一次过期键删除操作,通过限制删除的频率和时长来减少删除操作对CPU的影响。有效的减少了过期键对内存资源的占用

 

五、Redis内存淘汰策略

Redis内存淘汰策略是指在内存不足时,新数据怎么申请额外的空间数据。

 

5.1全局的键空间选择性移除

noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(这个是最常用的

allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

 

5.2设置过期时间的键空间选择性移除

volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。

volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。

volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

 

Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。

 

六、缓存异常

 

6.1缓存雪崩

缓存雪崩是指缓存数据同一时间大面积过期,造成所有请求都访问数据库,因短时间请求压力过大从而造成数据库崩掉。

解决方案:

  • 随机设置过期时间,避免同一时间过期

  • 并发量不是特别多的,最多处理方式是加锁排队

  • 给每个缓存数据添加标记,记录缓存是否失效,如果失效则更新缓存

6.2缓存穿透

缓存穿透是指数据库和缓存中都没有数据,造成所有请求都访问数据库,因短时间请求压力过大从而造成数据库崩掉。

解决方案:

  • 接口增加校验,如用户ID<0的直接拦截

  • 从缓存获取不到数据,数据库也不存在该数据,则设置一个Key-Value,Value=null的缓存,缓存时间可以设置30S,这样可以防止重复用一个ID暴力攻击。

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

6.3缓存击穿

缓存击穿是指没有获取到缓存数据(一般是缓存过期),由于并发用户量大,同时获取一条数据,没从缓存中获取的,请求全到数据库上,造成数据库压力过大。和缓存雪崩不同的是,缓存击穿是并发查询同一条数据,而缓存雪崩是大片数据过期,很多数据查不到都查询数据库。

解决方案:

  • 热点数据永不过期

  • 添加互斥锁,对缓存查询加锁,如果KEY不存在,就加锁,然后查数据库入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入数据库查询

 

 

 

 

 

 

 

 

0

评论 (0)

取消