老套路
1、什么是Redis
介绍Redis之前先了解一下Nosql(非关系型数据库)
我们都知道MySql是一种关系型数据库,那什么是非关系型数据库呢?它又是做什么呢?
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。
Redis是使用c语言开发的一个高性能键值数据库。Redis通过键值类型存储数据。
Redis使用场景:缓存(数据查询、短连接、新闻内容、商品内容等等)
(最多使用) 分布式集群架构中的session分离
聊天室的在线好友列表
任务队列
(秒杀、抢购、12306等等) 应用排行榜
网站访问统计
数据过期处理(可以精确到毫秒)
2、为什么要用Redis
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题,MySql不能很好为我们提供服务,引入了Redis。
那么为什么要用Redis呢?
1、速度快:首先Redis由C语言编写,纯内存操作,第二个 核心是基于非阻塞的IO多路复用机制,单线程避免了多线程的频繁上下文切换问题
2、支持多种数据类型,5种数据类型:String、Hash、List、Set、Zset(面试时可能会问到),还有其他数据结构:HyperLogLog、Geo、Pub/Sub
3、支持多种语言,Java/PHP
4、支持持久化存储,Redis 通过快照方式将数据持久化到磁盘中
3、怎么用Redis
首先来了解一下Redis5种数据类型:String、Hash、List、Set、Zset
数据类型 | 常规操作 | 应用场景 |
String |
赋值 语法: set key value 取值 语法: get key 删除 语法:del key23:19:59 数值增减 语法:incr key 递减数值 语法:decr key |
商品编号、订单号采用 string 的递增数字特性生成 自增主键 缓存 计数器 共享session |
Hash |
一次获取一个字段值 语法:hget key field 一次可以获取多个字段值 语法:hmget key field [field...] 获取所有字段值 语法:hgetall key 删除字段 可以删除一个也可以删除多个 语法:hdel key field [field...]
|
适合存储对象 变更数据,修改、读取用户属性 |
List |
向列表左边增加元素 语法:lpush key value [value...] 向列表右边增加元素 语法:rpush key value [value...] |
商品评论列表,用户发布商品评论,将评论信息转成json存储到list中。 用户在页面查询评论列表,从redis中取出json数据展示到页面。 消息队列 实现原理:利用list的push操作,将人物存在list中,然后工作线程再用POP操作将任务取出进行执行 |
Set |
增加/删除元素 语法:sadd key member [member...] 获得集合中的所有元素 语法:smembers key 判断元素是否在集合中 语法:sismember key member 差集 语法:sdiff key [key...] 交集语法:sinter key [key...] 并集 语法:sunion key [key...] |
标签 共同好友、二度好友 利用唯一性,可以统计访问网站的所有独立 IP
|
Zset |
增加元素 语法:zadd key score member [score member...] 获取元素分数 语法:zscore key member 删除元素 语法:zrem key member [member...] 获取集合中元素数量 语法:zcard key |
商品销售排行榜 游戏的用户得分排行榜 排行榜 |
4、Redis使用过程中遇到的问题
1、Redis缓存雪崩:
情况:Redis缓存雪崩指一段时间内,缓存大面积失效,Redis崩溃,数据请求全部打到MySql上,使MySql崩溃。
举个例子,双十一抢购,庞大的数据请求在同一时间对淘宝发起请求,数据请求量超过Redis缓存量,用户的请求全部打到数据库上面,数据库全面崩溃,当数据库重启,新的数据又到了,数据库又崩溃。
那出现这种情况怎么解决呢?
解决方案:
批量往redis存数据的时候,把每个key的失效时间加上个随机数,这样的话就能保证数据不会在同一个时间大面积失效。
2、Redis缓存穿透:
情况:用户请求一个数据库和缓存中都不存在的数据。
正常使用缓存的流程是,先对缓存进行查询,如何缓存中的key值过期或是不存在,再去数据库进行查询,并把查询到的数据放在缓存中,如果查询的对象为空,则不放入缓存。
解决方案:
- 在接口层增加校验,不合法的参数直接返回。不相信任务调用方,根据自己提供的API接口规范来,作为被调用方,要考虑可能任何的参数传值。
- 在缓存查不到,DB中也没有的情况,可以将对应的key的value写为null,或者其他特殊值写入缓存,同时将过期失效时间设置短一点,比如60秒,以免影响正常情况。这样是可以防止反复用同一个ID来暴力攻击。
- 高级用户布隆过滤器(Bloom Filter),这个也能很好地防止缓存穿透。原理就是利用高效的数据结构和算法快速判断出你这个Key是否在DB中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。
3、Redis缓存击穿:
情况:缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。
解决方案:
- 对热点key,加互斥锁
- 设置热点数据永不过期
缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题。所以一定要谨慎对待,当然,面试的时候也是常考点。
来源:https://www.cnblogs.com/zdh052286/p/12000127.html