前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >面试官最喜欢问的Redis知识

面试官最喜欢问的Redis知识

作者头像
程序大视界
发布于 2022-12-19 13:12:51
发布于 2022-12-19 13:12:51
3850
举报
文章被收录于专栏:程序大视界程序大视界

01

前言

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API

Redis是一个开源(BSD许可)的,用C语言编写的基于内存的数据结构存储系统(是一个高性能的 key-value存储系统)。而且会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化。Redis可以用在数据库,缓存和消息中间件

Redis作为一种高性能的key-value内存缓存数据库,在各大互联网公司的面试中也是经常被问到。

02

常用基本数据类型

Redis支持丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

1、String 字符串

字符串有C字符串和SDS字符串两种,C字符串里面不能包含空字符,所以C字符串只能保存文本数据,不能保存图片、音频、视频、压缩文件等二进制数据。

SDS是二进制安全的字符串,不仅可以保存文本数据,还可以保存任意格式的二进制数据。

总结:Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS作为字符串表示。

比起C字符串,SDS具有以下优点:

  1. 常数复杂度获取字符串长度
  2. 杜绝缓冲区溢出
  3. 减少修改字符串长度时所需的内存重分配次数
  4. 二进制安全
  5. 兼容部分C字符串函数

2、链表List

List结构为链表提供了表头指针head、表尾指针tail,以及链表长度计数器len,特性如下:

双端:链表节点带有prev和next指针,获取某个节点的前置节点和后置节点的复杂度都是O(1)

无环:表头节点的prev指针额表尾节点的next指针都指向null,对链表的访问以null为终点

带表头指针和表尾指针:通过list结构的head指针和tail指针,程序获取链表的表头节点和表尾节点的复杂度为O(1)

带链表长度计数器:程序使用list结构的len属性来对list持有的链表节点进行计数,程序获取链表节点数量的复杂度为O(1)

多态:链表节点使用void*指针来保存节点的值,并且可以通过list结构的dup、free、match、三个属性为节点值设置类型特定的函数,所以链表可以用于保存各种不同类型的值

总结:链表被广泛用于实现Redis的各种功能,比如列表键,发布与订阅,慢查询,监视器等

每个链表节点由一个listNode结构来表示,每个节点都有一个指向前置节点和后置节点的指针,redis的链表是双向链表。

每个链表使用一个list结构来表示,这个结构带有表头节点指针,表尾节点指针,以及链表长度信息

链表表头节点的前置节点和表尾节点的后置节点都指向null,所以redis的链表实现是无环链表。

通过为链表设置不同的类型特定函数,redis的链表可以用于保存各种不同类型的值。

3、字典hash(或map)

又称为符号表、关联数组或映射,是一种用于保存键值对(key和value进行关联)的抽象数据结构。

Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对。

解决键冲突:当有两个或以上数量的键被分配到了哈希表数组的同一个索引上面时,称这些键发生了冲突。

Redis的哈希表使用链地址法来解决冲突,每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表连接起来,如此解决键冲突。

Rehash:随着操作的不断执行,哈希表报存的键值对会逐渐地增多或减少,为了让哈希表的负载因子维持在一个合理的范围之内,当哈希表保存的键值对数量太多或太少时,程序需要对哈希表进行扩展或收缩。此时就是执行rehash(重新散列)的操作来完成,步骤如下:

以下条件的任意一个被满足时,程序会自动开始对哈希表执行扩展操作:

  • 服务器目前没有执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于1。
  • 服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于5。
  • 当哈希表的负载因子小余0.1时,程序自动开始对哈希表执行收缩操作。

回顾总结:字典被广泛用于实现redis的各种功能,其中包括数据库和哈希键。

a、Redis中的字典使用哈希表作为底层实现,每个字典带有两个哈希表,一个平时使用,一个仅在进行rehash时使用。

b、当字典被用作数据库的底层实现,或者哈希键的底层实现时,redis使用murmurHash2算法来计算键的哈希值

c、哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会连接成一个单向链表

d、在对哈希表进行扩展或收缩操作时,程序需要将现有的哈希表包含的所有键值对redhs到新哈希表里面,并且这个rehash过程并不是一次性地完成的,而是渐进式地完成的。

4、集合set

整数集合是redis用于保存整数值得集合抽象数据结构,它可以保存类型为int16 int32 或int64的整数值,并且保证集合中不会出现重复元素。

整数集合是集合键的底层实现之一。

整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加的元素的类型,改变这个数组的类型。

升级操作作为整数集合带来了操作上的灵活性,并且可能地节约了内存。

整数集合只支持升级操作,不支持降级操作。

5、sorted set 集合

sorted set有序集合的编码可以是ziplist或者skiplist.

Ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个元素则保存元素的分值。

压缩列表内的集合元素按分值从小到大进行排序,分值较小的元素被放置在靠近表头的方向,分值较大的元素则被放置在靠近表尾的地方。

6、压缩列表

压缩列表是列表键和哈希键的底层实现之一,当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么redis就会使用压缩列表来做列表键的底层实现。

03

Redis的高可用

3.1 Sentinel哨兵

哨兵是Redis的高可用性解决方案:由一个Sentinel 或多个Sentinel 实例组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

3.2 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel 对下线主服务器执行故障转移操作。

3.3 故障转移

在选举产生出领头Sentinel 后,领头Sentinel 将对已下线主服务器执行故障转移操作,该操作包含以下三个步骤:

在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。

让已下线主服务器属下的所有从服务器改为复制新的主服务器。

将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

04

Redis持久化

Redis是一个内存数据库,它将自己的数据库状态存储在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存奥磁盘里面,避免数据意外丢失。

4.1 RDB持久化

RDB文件是保存在磁盘里面的,所以即使Redis服务器进程退出,甚至运行Redis服务器的计算机停机,但只要RDB文件仍然存在,Redis服务器就可以用它来还原数据库状态。

RDB文件写入:有2个命令可以用于生成RDB文件:一个是SAVE,一个是BGSAVE。

重点内容:

RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。

SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器。

BGSAVE命令由子进程执行保存操作,所以该命令不会阻塞服务器。

服务器状态中会保存所有有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令。

RDB文件是一个经过压缩的二进制文件,由多个部门组成。

对于不同类型的键值对,RDB文件会使用不同的方式来保存他们。

4.2 AOF持久化

概念:AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的,如图

4.3 AOF持久化的实现

AOF持久化功能的实现可以分为命令追加、文件写入、文件同步三个步骤。

命令追加:当AOF持久化功能处于打开状态时,服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾:

重点内容:

AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态

AOF文件中的所有命令都以Redis命令请求协议的格式保存

命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件

Appendfsync选项的不同值对AOF持久化功能的安全性及Redis服务器的性能有很大影响

服务器只要载入并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态

AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小

AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无需对现有AOF文件进行任何读入、分析或者写入操作

在执行BGREWIRTEAOF命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新的AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新的AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件的重写操作。

05

生存时间或过期时间

5.1 设置过期时间

Redis通过expire命令或者pexpire命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间(Time to Live TTL),在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键

客户端可以通过expire命令或者pexpireat命令,以秒或者毫秒精度给数据库中的某个键设置过期时间(expire time)

5.2 过期键删除

有如下几种删除策略:

06

荐语

Redis的知识内容非常丰富,Redis的应用场景也很多,尤其是在高并发和高可用等场景下,它给我们带来很大便利的同时,也极大的保障了系统的性能和安全等。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序大视界 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
99. 中高级开发面试必问的Redis,看这篇就够了
Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。
用户11332765
2024/11/01
830
99. 中高级开发面试必问的Redis,看这篇就够了
redis面试必会6题经典_redis 面试
最近囧辉发现自己的 Java 学习交流群 里有不少同学已经“悄悄”的入职了携程、美团、阿里菜鸟等大厂。
全栈程序员站长
2022/11/17
1.8K0
redis面试必会6题经典_redis 面试
面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!
大家好,我是老三,面渣逆袭系列继续,这节我们来搞定Redis——不会有人假期玩去了吧?不会吧?
三分恶
2022/05/11
1.3K0
面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!
面试官问分布式技术面试题,一脸懵逼怎么办?
2、当 redis 服务器初始化时,会预先分配 16 个数据库(该数量可以通过配置文件配置),所有数据库保存到结构 redisServer 的一个成员 redisServer.db 数组中。当我们选择数据库 select number 时,程序直接通过 redisServer.db[number] 来切换数据库。有时候当程序需要知道自己是在哪个数据库时,直接读取 redisDb.id 即可。
苏先生
2019/04/26
1.3K0
面试官问分布式技术面试题,一脸懵逼怎么办?
【建议收藏】Redis知识干货汇总
为了让大家更好的学习redis相关的知识,我这里总结一下核心的面试知识点,大家来一起学习。
公众号-利志分享
2022/06/13
6860
面试进阶必问的Redis,看这篇就够了!
Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。
乔戈里
2019/05/22
1.1K0
面试进阶必问的Redis,看这篇就够了!
Redis设计与实现读书笔记
  Redis底层的数据库采用的就是这种结构,还有哈希键的底层实现之一也是采用HashMap这种结构。 哈希表的节点结构如下:
良辰美景TT
2018/09/11
6110
Redis设计与实现读书笔记
揭秘一线大厂Redis面试高频考点(3万字长文、吐血整理)
3万+长文揭秘一线大厂Redis面试高频考点,整理不易,求一键三连:点赞、分享、收藏
程序员江小北
2024/02/24
7220
揭秘一线大厂Redis面试高频考点(3万字长文、吐血整理)
从此Redis是路人
序言:Redis(Remote DIctionary Server)作为一个开源/C实现/高性能/基于内存的key-value存储系统,相信做Java的小伙伴都不会陌生。Redis常用于缓存、分布式锁、队列(或有序集合)等场景,追求技术的小伙伴们肯定不只满足于Redis的使用上,肯定也想了解Redis背后的设计思想及对应的开发实践,话不多少,上车吧~
luoxn28
2019/11/06
5190
《redis 设计与实现》--总结
Redis自己构建了简单动态字符串(Simple Dynamic String,SDS)来作为默认的字符串表示。 SDS的构造如下:
小二三不乌
2018/08/07
8530
《redis 设计与实现》--总结
Redis 面霸篇:从高频问题透视核心原理
「码哥字节」从高频面试问题跟大家一起横扫 Redis 核心知识点,从根本上理解 Redis ,不做八股文的工具人,做扭转乾坤的大神。
码哥字节
2021/07/19
7580
有关缓存的一些面试知识
底层数据结构一共有 7 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组、快速列表。它们和数据类型的对应关系如下图所示
ma布
2024/10/21
1060
有关缓存的一些面试知识
Redis源码精炼版
本文通过学习黄建宏老师的《Redis的设计与实现》以及其对应的redis-3.0-annotated源码,精炼、简化其中的内容,以供快速学习。
devi
2021/08/18
4170
Redis核心知识点
​ RedisTemplate底层默认使用JDK序列化来将key和value输出为字节数组:
大忽悠爱学习
2023/02/13
4730
Redis核心知识点
面试官最爱问的 11道 Redis 面试题,我替你整理好了
基于这些基础的数据结构,redis封装了自己的对象系统,包含字符串对象string、列表对象list、哈希对象hash、集合对象set、有序集合对象zset,每种对象都用到了至少一种基础的数据结构。
程序员小富
2020/10/10
7440
面试官最爱问的 11道 Redis 面试题,我替你整理好了
《Redis设计与实现》简读
最佳实践:因为对字符串的增长或缩短操作都有可能需要执行内存重分配,所以修改相同键使用SDS类型保存的值时保持修改前后长度一致。
MonroeCode
2018/01/10
1.4K0
2W字!详解20道Redis经典面试题!(珍藏版)
大家好,我是捡田螺的小男孩。金九银十即将到来,整理了20道经典Redis面试题,希望对大家有帮助。
捡田螺的小男孩
2021/09/08
8800
44连问,接近2w字Redis面试题总结
PS:Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据
小熊学Java
2022/09/06
7820
(三万字长文)面试不怂之redis与缓存大全
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/03/04
3690
Redis必知必会
这是用来查看某个key的数据类型,这里的类型即指的是上面诸如 String,hash,set....。而不能查看他们对应源码实现上所用的数据编码。可以通过下面的命令查看:
堆栈哲学
2022/11/24
1K0
Redis必知必会
相关推荐
99. 中高级开发面试必问的Redis,看这篇就够了
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档