Redis 面试知识点

132 阅读6分钟

Redis 是什么

  • Redis 是一个基于内存的NoSql类型的数据存储服务。
    • Nosql即not only sql,非关系型数据库,区别于传统关系型数据库的固定格式的行+列,Nosql的数据存储没有固定的格式,并且可以进行横向扩展。例如redis,HBase,MongoDB,图数据库等。
  • Redis的全称为Remote Dictionary Server,意为远程字典服务,是一个开源的基于C语言的K-V形式的数据库,并提供了多种语言的API。

与memcached区别

两者都是内存形式的数据存储中间件,早期项目用memcached的多一些,但是随着redis普及之后,得益于它丰富的数据类型迅速获得开发者青睐,并抢占了memcached的市场,redis也确实够稳定,在软件迭代更新频繁的互联网中持续十几年依旧火热不止,暂时还没有一款他的平替,性能强悍,社区活跃,并且很好地支持了分布式场景,是开发者手上的一大利器。

五大基本类型

上文说到Redis支持丰富的数据类型,具体的,它支持字符串、哈希表、列表、集合、有序集合这些基本类型以及bitmap,hyperloglog等进阶数据类型。

String

  • String是Redis最基础的数据结构,也是最常用到的类型。其他四种类型也是基于字符串类型构建的。
  • String类型的值最大能存储512MB,可以使简单字符串,复杂的xml/json字符串,音视频图像等二进制流。

应用场景

  • 缓存 前后端项目中最常见的用法,存储token用户信息。还有其他字符类型的数据都可以设置缓存,避免直接访问数据库,提高了查询效率,但是要做好数据的一致性。

List

  • 列表类型用于存储多个有序元素
  • 一个列表中可以存储一至多个元素,最多支持存储2^32-1个元素
  • 支持从列表两端进行插入和弹出元素,支持读取指定范围的元素集,可以充当队列或栈的角色
  • 列表内的元素是有序的,可重复的,支持通过下标获取指定的元素

应用场景

  • 消息队列 基于以上特性,可以用list实现阻塞队列,使用左进右出的命令完成设计,生产者通过lpush从左边插入消息,多个消费者使用brpop阻塞弹出链表尾部数据
  • 文章列表 博客网站的文章列表,当文章很多时,需要分页展示,可以用list存储,不仅有序,而且支持按照固定范围获取数据,解决了分页查询的问题,提高了查询效率

Set

  • 集合类型的存储,但是set是无序的,不可重复的
  • 支持集合内的增删改查,并且支持多个集合间的交集、并集、差集操作

应用场景

  • 标签 浏览博客网站的共同话题、共同爱好的永科可以用标签进行归类
  • 统计 利用元素的不可重复做去重统计功能

sorted set

  • 即zset,有序的不可重复的集合

应用场景

  • 排行榜 有序不重复集合的经典实用场景,例如视频网站对用户上传的视屏做排行榜,榜单参考的维度可能是点赞、播放量、收藏等多个方面

hash

  • key field value 结构的存储规则,适合存储关系型对象

应用场景

  • 整个对象存储

进阶数据类型

geospatial

  • 存储地理空间位置,即经纬度信息

应用场景

  • 附近的人
  • 位置共享
  • 地图直线距离展示

Hyperloglog

  • 基数统计,无论输入的内容多大,hyperloglog占用固定12kb空间,计算出2^64个不同元素的基数,非常节省空间,但是可能存在误差

应用场景

  • 网页统计UV(浏览用户数量,同一天一个ip多次访问算一次,目的是计数,比set节省空间)

bitmap

  • 想象成一长条数组,每个格子只能存0或1
  • 数组最大长度可达2^32bit,即512MB

应用场景

  • 统计时间周期内的活跃用户数
  • 统计打卡数

Redis持久化

作为一种内存数据库,当服务器进程退出时,存在数据丢失的风险,因此有了两种持久化方案:RDB和AOF,将内存数据落到磁盘上,等服务重启即可加载。

RDB

  • 保存特定时间点的数据快照
  • 进行rdb时,redis主进程不会做io操作,会fork一个子进程将数据集写入临时rdb文件中,完成新rdb文件写入后,用新文件替换旧文件
  • rdb只能保存某个时间间隔的数据,如果中途Redis服务意外停止了,会丢失一段时间内的数据

AOF

  • 以日志的形式记录每个写操作,行业内通用是每秒执行一次
  • 重写,随着Redis运行时间变长,AOF日志文件越来越大,此时就要用重写机制来合并相同操作指令
    • 手动触发 bgrewriteaof
    • 自动触发 根据配置规则(redis.config)no-appendfsync-on-rewrite : yes ,开启重写;auto-aof-rewrite-percentage 100 意为上次重写后文件大小增长100%再次触发重写;auto-aof-rewrite-min-size 64mb意为当文件至少达到64mb后触发重写

主从复制

  • 将一台Redis服务器的数据复制到其他的Redis服务器
  • 故障恢复 当主节点出现问题时,可以切换为由从节点提供服务
  • 负载均衡 读写分离:由主节点提供写服务,从节点提供读服务,在写少读多的场景中,通过多个从节点分担读负载,提高Redis集群并发量

缓存问题

缓存穿透

  • 攻击者用缓存中不存在的key发起大量查询,导致请求直接打到数据库

解决方案

  • 接口层增加校验,用户鉴权,id基础校验
  • 增加key-null的缓存值,有效时间设置短点,防止攻击者用同一个key反复请求
  • 布隆过滤器 如果有-可能有,如果没有-肯定没有,快速判断key是否存在,不存在则直接返回

缓存击穿

  • 某个热点缓存由于时间到期二失效,导致大量请求打到数据库

解决方案

  • 设置热点数据永不过期策略
  • 接口接入限流与熔断方案,一来防止攻击者恶意刷接口,二来是有熔断策略,当接口中某些服务不可用时快速返回默认,不影响整条调用链路

缓存雪崩

  • 缓存中大量数据到达过期时间,大量请求直接打到数据库

解决方案

  • 缓存数据的活期时间要分散、随机设置,防止同一时间大量失效
  • 分布式部署,把热点数据均匀分布在不同的服务器上
  • 大热数据设置永不过期

总结

本文罗列了当下流行的内存数据库Redis的常见面试题和知识点,方便各位读者做内容提炼和知识归纳总结。