redis概述+面试

1.redis概述

1.是什么?

Redis是一个完全开源免费的,遵循BSD协议,使用C语言编写的,支持网络交互的,内存中的Key-Value数据结构存储系统,它可以用作数据库、缓存和消息中间件。

2.特点

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash,等数据结构的存储。
  • Redis支持数据的备份,及master-slave模式的数据备份。

3.优势

  • 性能极高-读写速度快
  • 丰富的数据类型
  • 原子性-Redis所有操作都是原子性的,对数据的修改要么成功全部执行,要么失败全部不执行。
  • 丰富的特性-可用于缓存,消息,按key设置过期时间,过期后将会自动删除

4.Redis是单进程单线程的?

Redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。

5.关系型数据库与非关系性数据库

  • 关系型数据库

    采用关系模型来组织数据的数据库,关系模型就是二维表格模型。一张二维表的表名就是关系,二维表中的一行就是一条记录,二维表的一列就是一个字段。

    优点:

    • 易于维护:都是使用表结构,格式一致。
    • 使用方便:SQL语言通用。
    • 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。

    缺点:

    • 读写性能比较差,尤其是海量数据的高效率读写。

    • 固定的表结构,灵活度稍欠。

    • 高并发读写需求,传统关系型数据库来说,磁盘I/O是并发的瓶颈。

    • 横向扩展困难,无法简单的通过添加硬件和服务节点来扩展性能和负载能力。

    • 当需要对数据库进行升级和扩展时,需要停机维护和数据迁移 。

    • 多表的关联查询以及复杂的数据分析类型的复杂 sq 查询,性能欠佳。因为要

      保证 ACID.

  • 非关系型数据库

    非关系型,分布式,一般不保证遵循ACID原则的数据存储系统。键值对存储,结构不固定。

    优点:

    • 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,使用灵活,应用场景广泛。
    • 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘。
    • 高扩展性。
    • 成本低:noslq数据库部署简单,基本都是开源软件。

    缺点:

    • 无事务处理。
    • 不适合复杂查询的数据,只适合存储简单数据。
    • 不适合持久存储海量数据。

6.Redis中过期的key是怎么被删除的?

过期key有三种删除方式:

  1. **定时删除:**在设置键的过期时间的同时,创建一个定时器。当键的过期时间来临时,立即执行对键的删除操作。

    **缺点:**对CPU不友好,当过期键比较多的时候,Redis线程用来删除过期键,会影响正常请求的响应

  2. **惰性删除:**每次获取键的时候,判断键是否过期,如果过期的话,就删除该键,如果没有过期,则返回该键。

    **优点:**对CPU比较友好

    **缺点:**会浪费大量的内存。如果一个key设置过期时间放到内存中,但是没有被访问到,那么它会一直存在内存中。

  3. **定期删除:**每隔一段时间,对键进行一次检查,删除里面的过期键。

    **优点:**对CPU和内存都比较友好。

Redis过期key的删除策略

  1. 惰性删除

    客户端在访问key的时候,对key的过期时间进行校验,如果过期了就立即删除

  2. 定期删除

    Redis会将设置了过期时间的key放在一个独立的字典中,定时遍历这个字典来删除过期的key,遍历策略如下:

    1. 每秒进行10次过期扫描,每次从过期字典中随机选出20个key。
    2. 删除20个key中已经过期的key。
    3. 如果过期key的比例超过1/4,则进行步骤一。
    4. 每次扫描时间的上限默认不超过25ms,避免线程卡死。

**注意:**因为Redis中过期的key是由主线程删除的,为了不阻塞用户的请求,所以删除过期key的时候是少量多次。

2.数据类型

1.string(字符串)

string是redis最基本的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的sring可以包含任何数据。比如jpg图片或者序列化的对象。

string类型的值最大能存储512MB

set key value
get key

实例

string

2.hash(哈希)

redis hash是一个键值(key>=value)对集合

redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

hset key field value
hget key field

实例

hash

3.list(列表)

Redis列表是最简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的又不或者尾部。

lpush key element
rpush key element
lrange key start stop

实例

list

4.set(集合)

redis的set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是o(1)。

sadd命令

添加一个string元素到key对应的set集合中,成功返回1,如果元素已经在集合中返回0.

根据集合内元素的唯一性,第二次插入的元素将被忽略。

sadd key member
smembers key

实例

set

5.zset(有序集合)

zset和set一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数却是可以重复的。

zadd命令  添加元素到集合,元素在集合中存在则更新对应score
zadd key score member
zrangebyscore key min max

实例

zset

6.设置失效时间

redis提供了一些命令,能够让我们对key设置过期时间,并且让key过期之后自动删除。

设置值时之间设置有效时间

失效时间

EX 表示以秒为单位
PX 表示以毫秒为单位 
EX,PX 不区分大小写 
set name jim EX 30 设置失效时间为 30 秒 
ttl 键 查看剩余时间(秒) 
pttl 键 查看剩余时间(毫秒)

设置值后设置有效时间

expire 键 时间(秒) 
pexpire 键 时间(毫秒)

3.springboot集成使用redis

Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用。

Spring-data-redis 是 spring 大家族的一部分,提供了在 srping 应用中通过简单的配置访问 redis 服务,对 reids 底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate 提供了 redis 各种操作。

spring-data-redis 针对 jedis 提供了如下功能:

  1. 连接池自动管理,提供了一个高度封装的”RedisTemplate“类。

  2. 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口。

    ValueOperations:简单 K-V 操作

    SetOperations:set 类型数据操作

    ZSetOperations:zset 类型数据操作

    HashOperations:针对 map 类型的数据操作

    ListOperations:针对 list 类型的数据操作

  3. 将事务操作封装,有容器控制。

  4. 针对数据的”序列化/反序列化“,提供了多种可选择策略

    JdkSerializationRedisSerializer:POJO 对象的存取场景,使用 JDK 本身序列化机制。

    StringRedisSerializer:Key 或者 value 为字符串的场景,根据指定的charset 对数据的字节序列编码成 string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。

    JacksonJsonRedisSerializer:jackson-json 工具提供了 javabean 与 json 之间的转换能力,可以将 pojo 实例序列化成 json 格式存储在 redis 中,也可以将json 格式的数据转换成 pojo 实例。

4.主从复制

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。

使用一个Redis实例作为主机,其余的作为备份机。主机和备份机的数据完全一致,主机支持数据的写入和读取等各项操作,而从机则只支持与主机数据的同步和读取。也就是说,客户端可以将数据写入到主机,由主机自动将数据的写入操作同步到从机。主从模式很好的解决了数据备份问题,并且由于主从服务数据几乎是一致的,因而可以将写入数据的命令发送给主机执行,而读取数据的命令发送给不同的从机执行,从而达到读写分离的目的。

作用:

  • 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  • 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  • 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  • 高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

5.哨兵机制

哨兵模式是一种特殊的模式,首先Redis提高了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

单哨兵

单哨兵

哨兵集群

哨兵集群

6.缓存穿透、缓存击穿、缓存雪崩

1.缓存处理流程

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没有取到,那直接返回空结果。

缓存处理流程

2.缓存穿透

key对应的数据在数据库中并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据库,从而可能压垮数据库。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

key数据库没有,缓存没有

缓存穿透

解决办法:

  1. 使用布隆过滤器或者压缩filter提前拦截
  2. 将这个空对象设置到缓存里边去。下次再请求的时候,就可以从缓存里边获取了。这种情况我们一般会将空对象设置一个较短的过期时间。
  3. 拉黑该IP地址。
  4. 对参数进行校验,不合法参数进行拦截。
布隆过滤器

**组成:**由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。

**作用:**用于检索一个元素是否在一个集合中。

**优点:**空间效率和查询时间都比一般算法要好的多。

**缺点:**有一定的误识别率和删除困难。

**基本思想:**它可以通过一个Hash函数将一个元素映射成一个位阵列中的一个点。我们只要看这个点是不是1就可以知道集合中有没有它了。

布隆过滤器

算法:

  1. 首先需要k个hash函数,每个函数可以把 key 散列成为 1 个整数 。
  2. 初始化时,需要一个长度为 n 比特的数组,每个比特位初始化为 0 。
  3. 某个 key 加入集合时,用 k 个 hash 函数计算出 k 个散列值,并把数组中对应的比特位置为 1。
  4. 判断某个 key 是否在集合时,用 k 个 hash 函数计算出 k 个散列值,并查询数组中对应的比特位,如果所有的比特位都是 1,认为在集合中。

3.缓存击穿

某个key对应的数据库中存在,但在redis中的某个时间节点过期了,此时若有大量并发请求过来,这些请求发现缓存过期,都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

解决办法:

  1. 热点数据设置永不过期
  2. 加上互斥锁:上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到redis缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存。

缓存击穿

4.缓存雪崩

缓存雪崩是指,在高并发情况下,大量的缓存失效,或者缓存层出现故障。于是所有的请求都会达到数据库,数据库的调用量会暴增,造成数据库也会挂掉的情况。

缓存雪崩

解决办法:

  1. 随机设置key失效时间,避免大量key集体失效。
  2. 若是集群部署,可将热点数据均匀分布在不同的Redis库中也能够避免key全部失效问题。
  3. 不设置过期时间。
  4. 跑定时任务,在缓存生效前刷进新的缓存。

总结

雪崩是大面积的key缓存失效;穿透是redis里不存在这个缓存key;击穿是redis某个热点key突然失效,最终的受害者都是数据库。

对于”Redis宕机请求,全部走数据库“这种情况,我们可以有以下的思路:

**事发前:**实现Redis的高可用(主从架构+Sentinel(哨兵)),尽量避免Redis挂掉这种情况发送。

**事发中:**万一Redis真的挂了,我们可用设置本地缓存+限流,尽量避免我们的数据库被干掉。

**事发后:**redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值