什么是redis
redis是C语言开发的一个开源免费高性能非关系型(NOSQL)的key-value内存数据库 它的值类型相对更为丰富
rdis的value类型有哪些
string(字符串),
list(链表),
set(无序集合),
zset(有序集合),
hash(哈希类型)
geospatial(Redis 在 3.2 推出 Geo 类型,该功能可以推算出地理位置信息两地之间的离)
hyperloglog(Redis 的 hyperLogLog 是用来做基数统计的数据类型)
bitmap(位图大概是用来做地图的,存储有些地理位置只需要很小的内存)
redis的使用场景
数据库,缓存,消息中间键
什么是redis持久化
就是吧数据存储在磁盘当中,防止服务器宕机内存数据的丢失。
redis提供了两种持久化方式:
Rdb: Rdb是以快照的形式将数据存储在磁盘当中。 Rdb是指定的时间间隔,执行个dump.rdb文件,redis重启时加载dump.rdb文件实现数据恢复 优点:适合大规模的数据恢复场景,如备份,全量复制等 缺点:没有办法做到实时存储/秒级存储新老版本存在兼容问题 Aof: Aof是采用日志的方式记录每个写操指定的写操作,将数据存储在磁盘当中,Rdb是redis的默认存储化方式, 执行后会在指定目录下生成一作,追加到文件当中,重启时在执行AOF文件中的命令来恢复数据它主要解决数据持久化的实时性问题。默认是不开启的。 优点:数据的一致性和完整性 缺点:内容越大,文件越大,恢复速度越慢
Redis的缓存雪崩、缓存击穿、缓存穿透与缓存预热、缓存降级
缓存雪崩:
是指在同一时刻有大规模的key失效,导致大量请求访问到数据库,导致数据库压力巨大,如果是在高并发的情况下,数据库可能就会崩溃宕机,如果这个时候运维又重启数据库,又会有新的请求马上吧数据库打死,这就是缓存雪崩解决方案:
事前: 均匀过期:均匀的设置过期时间,让缓存失效的时间分布均匀,避免大量相同的过期key导致雪崩 分级缓存:第一级缓存失效的基础上,访问二级缓存,每一级缓存的失效时间都不同 热点数据缓存永远不过期。 事中: 互斥锁:在缓存失效后,通过互斥锁或者队列来控制读数据写缓存的线程数量,比如某个key只允许一个线程查询数据和写缓存,其他线程等待。这种方式会阻塞其他的线程,此时系统的吞吐量会下降 使用熔断机制,限流降级。当流量达到一定的阈值,直接返回“系统拥挤”之类的提示,防止过多的请求打在数据库上将数据库击垮,至少能保证一部分用户是可以正常使用,其他用户多刷新几次也能得到结果。 事后: 开启Redis持久化机制,尽快恢复缓存数据,一旦重启,就能从磁盘上自动加载数据恢复内存中的数据。
缓存击穿:
缓存击穿和缓存雪崩有些类似,缓存雪崩是同一时刻大量的key失效,而缓存击穿是一个热点的key失效,然后又有大量请求,请求了又没有数据,就会大量访问到数据库,导致数据库压力剧增,这种现象就叫做缓存击穿解决方案:
(1)在缓存失效后,通过互斥锁或者队列来控制读数据写缓存的线程数量,比如某个key只允许一个线程查询数据和写缓存,其他线程等待。这种方式会阻塞其他的线程,此时系统的吞吐量会下降 (2)热点数据缓存永远不过期。
缓存穿透:
缓存穿透是指用户请求的数据在缓存中不存在,及没有命中,数据库中也没有,导致每次请求都会到数据库查一遍,如果这时有大量恶意请求访问不存在的数据,就会导致数据库压力过大导,宕机崩溃。
解决方案:
思路: 请求没有Key====》redis没有查到====》到数据库查 2、问题分析: 缓存穿透的关键在于在Redis中查不到key值,它和缓存击穿的根本区别在于传进来的key在Redis中是不存在的。 假如有黑客传进大量的不存在的key,那么大量的请求打在数据库上是很致命的问题,所以在日常开发中要对参数做好校验,一些非法的参数,不可能存在的key就直接返回错误提示。 3、解决方法: (1)将无效的key存放进Redis中: 当出现Redis查不到数据,数据库也查不到数据的情况,我们就把这个key保存到Redis中,设置value="null",并设置其过期时间极短,后面再出现查询这个key的请求的时候,直接返回null,就不需要再查询数据库了。但这种处理方式是有问题的,假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。 (2)使用布隆过滤器: 如果布隆过滤器判定某个 key 不存在布隆过滤器中,那么就一定不存在,如果判定某个 key 存在,那么很大可能是存在(存在一定的误判率)。于是我们可以在缓存之前再加一个布隆过滤器,将数据库中的所有key都存储在布隆过滤器中,在查询Redis前先去布隆过滤器查询 key 是否存在,如果不存在就直接返回,不让其访问数据库,从而避免了对底层存储系统的查询压力。
缓存预热:
缓存预热是指系统上线后,提前将相关的缓存数据加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。
如果不进行预热,那么Redis初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。
2、缓存预热解决方案: (1)数据量不大的时候,工程启动的时候进行加载缓存动作; (2)数据量大的时候,设置一个定时任务脚本,进行缓存的刷新; (3)数据量太大的时候,优先保证热点数据进行提前加载到缓存。
缓存降级:
缓存降级是指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。在项目实战中通常会将部分热点数据缓存到服务的内存中,这样一旦缓存出现异常,可以直接使用服务的内存数据,从而避免数据库遭受巨大压力。