java分布式(第四章)——Redis

假如想象 提交于 2019-12-14 10:59:49

老套路

1、什么是Redis

2、为什么要用Redis

3、怎么用Redis

4、使用Redis过程中遇到的问题


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,加互斥锁
  •   设置热点数据永不过期

缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题。所以一定要谨慎对待,当然,面试的时候也是常考点。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!