文章目录

  • 前言
  • 1.第一问:redis支持哪些数据类型:
  • 2 第二问:redis持久化方式和说明:
  • 2.1 RDB(默认)持久化存储:
  • 2.2 AOF:
  • 2.3 持久化比较:
  • 3.第三问:redis架构模式介绍:
  • 4.第四问:redis常用命令和过期策略介绍:
  • 5.第五问:redis分布式锁和队列:
  • 6.第六问:redis针对缓存穿透、击穿、雪崩的解决方案:
  • 总结


前言

java后端现在去外面面试,redis也是必须面试的问题点,因为在实际的开发当中,我们很多场景下秒杀、缓存、加锁会使用到redis。redis其实是数据库的一种,与传统的sqlserver和mysql的关系型数据库比较,属于非关系数据库,key-value形式存储。传统数据库遵循的是ACID规则。而redis遵循的是CAP理论。

1.第一问:redis支持哪些数据类型:

类型

命令

说明

String字符串

set key value

String 是二进制安全的,也是基本数据类型,最大键值存储为512M,用于字符串缓存,加锁等场景

Hash类型

hmset name key1 value1 key2 value2

是一个键值对的集合,非常适合存储字段比较多的对象

List类型

注意存储的是字符串列表,当然可以支持json字符串支持头部和尾部进行插入,同样支持头部和尾部读取,也支持索引获取元素,长度等方法

我之前用list做过队列,就是一个服务往里面写,另一个进行读取,进行了服务之间的解耦,当然这个数据量小的时候可以,数据量大的时候还是使用mq等中间件比较靠谱

Set集合

sadd name value,set的是String 类型的无序集合

集合通过hash表实现,添加、删除、查找的复杂度都是O(1)

zset类型

有序集合, zadd name score value,跟set一样,是String类型元素集合,不允许重复成员,因为元素都会关联一个分数,所以通过分数的排序使其具有排序的特性,成员唯一,但是分数可以重复

使用与需要排序的集合的使用场景

2 第二问:redis持久化方式和说明:

持久化的目的是防止服务宕机内存中的数据丢失。

2.1 RDB(默认)持久化存储:

RDB快照存储,隔一段时间fork一个子进程进行快照形式的保存数据,缺点是容易丢失数据。RDB是Redis DataBase缩写,rdbsSave和rdbLoad两个函数进行和磁盘文件交互。

2.2 AOF:

追加模式,aof是Append-only file缩写,就是定期往磁盘文件进行追加持久化的内容,缺点是导致后面的追加文件很大,但是优点是不容易丢失数据。

2.3 持久化比较:
  1. aof的更新频率比rdb高,优先使用aof进行数据还原
  2. aof比rdb安全,但是文件会更大
  3. rdb的性能比aof好
  4. 如果配置的两种持久化策略,优先使用的aof

这里提一下redis客户端和服务端的通讯协议是:RESP。
特点是:
实现简答、快速解析、可读性好

3.第三问:redis架构模式介绍:

单机版: 一个服务提供给多个客户端使用:

特点是:简单

缺点:内容存储有限、处理能力有限、无法高可用

主从复制:
一个master 多个slave,主服务器发生在自己身上的数据更新给从服务器,来保证主从相同。

特点:降低了度压力

缺点:无法保证高可用,主挂了就挂了,也没有解决写的压力

哨兵:
Redis sentinel 是一个分布式系统中监控redis主从服务器,在主服务器下线时自动进行故障迁移。

监控:监控主从服务器之间是否正常

提醒:当监控的redis服务器出现问题,会向管理员和其他应用发出通知

自动故障迁移:当主服务器不能正常工作时,开始自动故障迁移。

特点:
保证高可用、监控各个节点、自动故障迁移

缺点:主从模式,切换时间可能都是数据,缺点是没有解决master写的压力

集群(proxy 型)用的不多:

Twemproxy 是一个 Twitter 开源的一个 redis 和 memcache 快速/轻量级代理服务器; Twemproxy 是一个快速的单线程代理程序,支持 Memcached ASCII 协议和 redis 协议。

特点:1、多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins

2、支持失败节点自动删除

3、后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

缺点:增加了新的 proxy,需要维护其高可用。

集群(直连型):
redis 3.0之后支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

特点:

1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

缺点:

1、资源隔离性较差,容易出现相互影响的情况。

2、因为数据通过异步复制,不保证数据的强一致性
补充:目前来说最好的一个架构

4.第四问:redis常用命令和过期策略介绍:

命令

说明

Keys pattern/keys aa* keys *

查看key相关

Exists key

查询key是否存在存在返回1不存在返回0

set

set key value进行存储键值对

setnx

设置key对应的值为String类型的value,如果key已经存在,返回0,nx是not exist的意思

del key

删除key

Incr

对key进行加1的操作并且返回新的值

incrby

指定Key加的值并且返回最新值

Decr

在原来的值的基础上减1并返回结果

Decrby

指定减的值

Rename

重命名

Type

返回数据类型

这里要说明的是如果使用的是SpringBoot,RedisTemplate 里面直接点点操作会有对应的api操作。
这里还要说的是如果你面试的能够回答出来,SpringBoot1x中使用的是jedis连接池 ,SpringBoot2x中使用的是lettuce 连接池,性能有很大提升,会是加分项。

Redis过期策略:
我们知道设置过期时间命令:

expire key time

字符串独有的过期设置:

setx(String key ,int seconds,String value)

除了字符串其他的类型都是依靠expire设置过期时间。如果不设置过期时间就是永不过期。

三种过期策略:

策略

说明

优点

缺点

定时删除

在设置key的时候设置一个定时器为key,当到期时删除key

保证尽快释放内存

key多cpu占用多,影响性能

惰性删除

key过期的时候不删除,获取的时候检查key是否过期,若过期则删除,返回null

占用cpu少

大量key过期不删除,内存泄露会发生

定期删除

每隔一段时间删除过期key的操作

能有效降低cpu的占用和惰性删除的缺点

内存不如定时删除,cpu不如惰性删除

redis采用的惰性删除和定期删除的组合策略。
RDB和AOF对过期key都会有个判断的操作,所以过期key对持久化无影响。

5.第五问:redis分布式锁和队列:

redis的分布式锁之前setnx,先加锁再加过期时间,但是新版本中增加了原子锁:commands.set(Constant.前缀+ “:” + key, “1”, “NX”, “EX”, expireSecond);NX/EX实现分布式原子锁,防止两死锁的发生。

异步队列:就像我上面提到的就是使用list类型实现,lpush进行生产消息,lpop进行消费消息。当然这种队列只适合简单的队列场景,涉及到过期队列并发高等还是应该使用mq。

6.第六问:redis针对缓存穿透、击穿、雪崩的解决方案:

名词

说明

解决

穿透

存在则缓存返回,不存在则查询db,恶意查询不存在的key对后端压力增大就叫穿透

查询为空的时候缓存下,查询以后更新缓存,过滤key

击穿

缓存中没有数据库中有,穿透是数据库中也可能没有

设置热点key永不过期,加互斥锁,保证第一个访问去数据库查询数据,其他的都是走缓存空

雪崩

缓存服务器重启或者大量缓存失效,都去访问数据库,引起压力过大

key的过期时间分布均匀 ,避免短时间大量key过期,加锁避免并发并发量大访问控制流量

总结

上面总的来说把redis整个的面试涉及到的点进行了一个总结。