redis常用知识梳理

1. redis存在的问题(常见):

缓存与数据库双写一致性

缓存穿透

缓存击穿

缓存雪崩

并发竞争问题

2. redis是一个单线程的工作模型,获取数据效率高。

纯内存操作

单线程操作,避免上下文切换

非阻塞I/O多路复用模式(只有单个线程,通过跟踪每个I/O流的状态,来管理多个I/O流。)

3. redis存储的数据类型及对应用法:

String:一般用于做一些复杂的计数等功能

hash:存放结构化的对象,便于操作其中的某个字段,如单点登录、session控制等。

list:类似消息队列的使用时。利用lrange命令,做基于redis的分页功能,性能极佳,用户体    

验好。取行情信息。就也是个生产者和消费者的场景。

set:全局去重。

sorted set:类似排行榜。

4. redis过期策略及淘汰机制:

定期删除+惰性删除机制。

定期删除:redis每隔100ms随机抽样检查是否有过期的KEY。单纯使用此方式可能会导致部分key过期后无法删除。

惰性删除:每次使用到一个KEY时,都检查一下是否过期。如过期则删除。两种删除方式均使用的情况下,仍然会存在一部分KEY过期了且一直未使用,还是无法删除。

配置内存淘汰策略:# maxmemory-policy volatile-lru

noeviction:内存不足时,写入报错。(一般不使用)

allkeys-lru:内存不足时,写入新KEY,移除掉不常使用的。(使用较多)

allkeys-random:内存不足时,写入新KEY,随机删除已有的KEY。(一般不用)

volatile-lru:内存不足时,写入新KEY,删除设置过期时间的KEY空间中最不常使用的。(把redis既当缓存,又做持久化存储的时候才用)

volatile-random:内存不足时,写入新KEY,随机删除设置过期时间的KEY空间中的KEY。

volatile-ttl:内存不足时,写入新KEY,删除设置过期时间的KEY空间中设置了更早过期时间的KEY。

ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

5. redis与数据库的双写一致性:

先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

6.1 redis缓存穿透:

黑客故意去请求缓存中不存在的KEY,导致所有的请求都怼到数据库上,从而数据库连接异常。

解决方式:

利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试

采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。

提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。

6.2 redis缓存击穿:

黑客故意去请求缓存中的热点key,当KEY失效时,大量请求直接击穿了缓存,到了数据库上。

解决方案:

可以将热点数据设置为永远不过期;或者基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key访问数据,或可以在凌晨服务器访问量较小的时候进行数据更新进数据库,同时使用linux定时任务写一个脚本来模拟访问热门数据将数据加载回redis。

7. redis缓存雪崩:

缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。

解决方案:

给缓存的失效时间,加上一个随机值,避免集体失效

使用互斥锁,但是该方案吞吐量明显下降了。

双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点:

从缓存A读数据库,有则直接返回。

A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。

更新线程同时更新缓存A和缓存B。

8. redis并发,竞争KEY:

多个子系统去set一个key。

解决方式:

如果对这个key操作,不要求顺序:准备一个分布式锁,大家去抢锁,抢到锁就做set操作即可

如果对这个key操作,要求顺序:存储数据时存入一个时间戳,后面抢到线程的进程处理时,先根据时间戳判断。

9. redis持久化方式:

快照(rdb-redis database):将存储在内存的数据以快照的方式写入二进制文件中。

每隔一段时间,对内存中的数据进行一次快照,保存到rdb文件中,主从同步可以实现异步。但是,如果间隔时间过短会影响到redis的性能,如果间隔时间过长,在间隔时间段内关闭或重启redis可能导致部分数据丢失。

仅附件文件(AOF-append only file):使用AOF持久时,服务会将每个收到的写命令通过写函数追加到文件中(appendonly.aof)。

随着时间增长,aof文件会越来越大,可能会让进程如同假死一样。

10. redis的主从复制:

主节点:负责写数据,定期同步数据到从节点。

从节点:负责读数据。

你可能感兴趣的:(redis常用知识梳理)