目录
一、Redis 简介
Redis 是一个用C 开发的数据库 ,它不仅可以用来做缓存,也可以用来做分布式锁,还有消息队列;它支持多种数据类型,还支持事务,持久化,Lua脚本,多种集群方案
二、常见面试点
1.Redis 和Memcached 的区别
共同点:
- 都是分布式的缓存,现在主流使用Redis
- 基本都是当作缓存使用,性能非常高,有过期机制
不同点
- Redis 支持更多丰富的数据类型:它不仅支持K/V 数据存储,还不仅支持List, set,zset ,hash 等数据结构的存储, 而memcached 支持k/v 数据类型
- Redis 支持数据持久化,可以把数据保存到磁盘,而Memcached 只能保存在内存中
- Redis 有灾难恢复机制
- Memcached 使用定期删除的策略,而redis 使用惰性和定期删除
2.为什么要用 Redis/为什么要用缓存?
缓存数据的处理流程
- 先读缓存,缓存有数据直接返回
- 缓存没有看数据库是否有数据
- 数据库有数据返回并更新缓存信息
- 数据库没有数据返回空
Redis具有高性能高并发的有点,数据库MYSQL 的QPS 大概在1w 左右,而因为Redis 是直接操作内存的,所以它的QPS 可以达到 10w+ ,甚至最高能达到 30w+(就单机 redis 的情况,redis 集群的话会更高)
3.Redis 没有使用多线程?为什么不使用多线程?
原因有三
- 单线程比较容易并且容易维护
- Redis的性能瓶颈不在CPU ,而是在内存和网络
- 多线程会存在死锁,上下文切换问题,甚至影响网络
4.Redis 删除策略及内存淘汰机制
删除策略:
- 惰性删除 :只会在取出key的时候才会进行过期检查
- 定期删除 :每隔一段时间抽取一批key做定期删除
但是仅仅是给key设置定期删除时间,会漏掉很多过期key的情况,为此就有了内存删除机制
内存淘汰有6种:
- volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!
5.Redis 事务
事务四大特性:原子性,持久性,隔离性,一致性
redis 只满足一致性性和隔离性,不满足原子性(不支持回滚)和持久性
命令:MULTI ,EXEC, WATCH, DISCARD
> MULTI
OK
> SET USER "测试"
QUEUED
> GET USER
QUEUED
> EXEC
1) OK
2) "测试"
6.Redis 缓存穿透
1)缓存无效的key : 如果缓存和数据库都查不到,就写一个key到redis里面并设置过期时间
2)使用布隆过滤器
7.Redis 缓存雪崩
何谓缓存雪崩:缓存在同一时间内大面积失效,后面的请求落到数据库,数据库要在短时间内承受大量的请求
解决雪崩问题:
1)设置限流,避免大批量请求
2)采用集群的方式,避免单机问题出现整个缓存服务无法使用
3)缓存永不过期
4)热点缓存随机设置过期时间
8.三种缓存读写策略
1)旁路缓存模式 :
先读cache,cache 没有读数据库,然后拿数据库返回的数据更新cache ,这种模式适合读请求比较多的场景 ; 必须要先写DB ,然后再更新缓存,因为写缓存的速度比更新DB的快很多,这样有助于保持数据一致性
2)读写穿透模式
写穿透:
- 先读cache, cache 不存在,直接更新DB
- cache 存在,更新cache,然后使用cache的服务去更新DB (同步更新cache 和DB)
读穿透:
- 先读cache, cache 存在就直接返回
- cache 不存在,直接读取DB 数据更新cache ,然后返回
3)异步缓存写入
只更新cache ,不更新DB ,异步更新DB , 这种模式适合对数据时效性要求没有那么高的场景,例如网页流量量,点击量。