为什么redis取出来是null_[2020] Redis 最新面试题

Redis 的数据类型(数据结构)

  1. string (二进制安全,可以存储任意类型的数据)
  2. list(链表)
  3. 字典(就是hashmap)
  4. set(不重复无序的hashmap)
  5. zset(按照给定的 score 排序的 set)
  6. HyperLogLog(来做基数统计的算法,简介)
  7. Geo(支持地理位置的操作,使用简介)
  8. Pub/Sub
  9. BloomFilter
  10. RedisSearch
  11. Redis-ML

缓存雪崩(缓存击穿)

他们出现的原理都是访问缓存的时候,key 刚好失效,导致直接访问 DB,压垮后台。

解决办法就是让 key 的过期时间分散开,不要集中失效

分布式锁

使用 setnx 命令后为了防止死锁,需要对 key 施加 expire 命令,防止死锁,但是存在执行 expire 命令前宕机,造成死锁的发生。

解决办法就是使用复杂的 setnx 命令,他可以把 setnx 和 expire 一起原子执行

如何寻找有固定前缀的 key

使用 KEYS pattern 命令,如:KEYS alib*

但是因为 Redis 是单线程的,执行该命令后会导致 Redis 阻塞住。

解决办法就是使用 scan 命令,scan 命令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys指令长

scan 命令的特点:

Redis中的Scan命令的使用 - MSSQL123 - 博客园​www.cnblogs.com
3cf62f2cb414ef60818dcbce79464dce.png

如何用 Redis 做异步队列

使用 list 数据结构,在一遍加入,另一边取出,若取出来的是 null,则消费线程应该 sleep,或者消费线程不使用 lpop 或 rpop 命令,改为 blpop 或者 brpop 命令,若没有元素可取,它会阻塞列表直到等待超时或发现可弹出元素为止。

如何生产一次,消费多次

使用发布订阅模式

但是在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 rabbitmq

Redis 如何实现延时队列

使用 zset ,用时间戳作为 score,消息会按照时间顺序排序

然后使用 zrangebyscore key min max [WITHSCORES] [LIMIT offset count] 来取出比当前时间小的 key 的 value

持久化

Redis 4.0 时代以 RDB 为主,AOF 只记录上一次 RDB 到现在的更改记录

开启混合持久化:aof-use-rdb-preamble yes

工作原理:其实还是一种 AOF 机制,但是新增了 RDB 的特性,先看此模式下的 AOF 的数据结构图

df21e7415d34a76bd4367d891eab1fb1.png
  • 看图就知道混合模式指的就是重写 AOF 的时候,将此刻内存里面的数据做成 RDB,在此过程中增量的数据写入到缓冲区,最终形成新的 aof 文件。接着删除旧的 AOF。
  • 重启恢复时先恢复 RDB,再重放新增的 AOF 指令

持久化的意义在于故障恢复

  • AOF:记录每一次的写操作到日志上,重启时重放日志以重建数据
    • 每隔一段时间调用系统的 fsync 函数强制将 os cache 里面的数据刷新到磁盘上
  • RDB:每隔一段时间保存一次当前时间点上的数据快照
    • 快照就是一次又一次地从头开始创造一切,全量的

持久化如何工作的

关键词:写时复制和 fork 子进程

  • 每当 Redis 需要转储数据集到磁盘时,会发生:
    • Redis 调用 fork()。于是我们有了父子两个进程。
    • 子进程开始将数据集写入一个临时 RDB / AOF 文件。
    • 当子进程完成了新 RDB 文件,替换掉旧文件。
    • AOF 的 fork(),与 RDB 不同的是父进程会在一个内存缓冲区中积累新的变更,同时将新的变更写入新的 AOF 文件,所以即使重写失败我们也安全。当子进程完成重写文件,父进程收到一个信号,追加内存缓冲区到子进程创建的文件末尾,接着自动重命名文件为新的,然后开始追加新数据到新文件
  • 这个方法可以让 Redis 获益于写时复制(copy-on-write)机制

AOF 为什么要重写

AOF 记录的是 Redis 的每一次变更,这个变更包含了大量的冗余操作,导致 AOF 体积变大,恢复缓慢。

通过重写这个体积大的 AOF 文件,可以实现新的 AOF 文件不会包含任何浪费空间的冗余命令,通常体积会较旧 AOF 文件小很多。

Pipeline

将多个指令一起发送,减少 IO,提高吞吐量

Redis 的同步机制

Redis 可以使用主从同步,从从同步。

第一次同步时,主节点做一次 bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 RDB 文件全量同步到复制节点,复制节点接受完成后将 RDB 镜像加载到内存。

加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过 AOF 日志同步即可,有点类似数据库的 binlog

Redis 集群

Redis Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为 master,继续提供服务。

Redis Cluster 着眼于扩展性,在单个 redis 内存不足时,使用 Cluster 进行分片存储。

Redis 的通讯协议是什么

答案是文本协议

虽然文本协议耗费流量,但是解析性能很好

Redis 的事务

首先 Redis 支持事务,但是它的事务与MySQL这类传统的数据库的事务不同,不同点为:

  1. 通过 MULTI 开启事务(类似于MySQL的 STARTtransaction; 命令)
  2. 通过 EXEC 命令触发事务(类似于MySQL的 COMMIT; 命令)
  3. 执行事务的时候放入事务队列里面的命令都会被执行,不管是否有命令执行时出错
  4. Redis 的事务可以理解为打包的批量执行脚本,所以不支持原子性,失败了可以继续执行完,也不会回滚
  5. 但是单个的Redis命令是原子的

具备隔离性:Redis 因为是单线程操作,所以在隔离性上有天生的隔离机制,当 Redis 执行事务时,Redis 的服务端保证在执行事务期间不会对事务进行中断,所以,Redis 事务总是以串行的方式运行,事务也具备隔离性。

不具备一致性:虽然开启持久化之后可以在数据出现问题是恢复到之前的状态,但是因为Redis的事务不是原子性的,不会回滚数据,Redis设计时也没有考虑ACID特性,所以认为Redis不具备一致性

持久性:开启持久化就支持,不开启就不支持

Redis 的乐观锁 Watch 是怎么实现的

Watch 会在事务开始之前盯住 1 个或多个关键变量,如下图:

当事务执行时,也就是服务器收到了 exec 指令要顺序执行缓存的事务队列时, Redis 会检查关键变量自 Watch 之后,是否被修改了。

6985f121bdade4718492a3d146797f00.png

上图显示,watch abc 之后执行事务之前,执行了一次 incr 操作,所以在 exec 的时候失败,watch 的实现原理不是 CAS 中的 Cmpxchg 指令,而是借助 Redis 的单线程执行机制,采用了 watched_keys 的数据结构和串行流程实现了乐观锁,具体解释就是:

每一个被 watch 的 key 都会被构造成一个 watched_keys 数据类型,多个被 watch 的 key 构造成链表存储着假设客户端 A 和 B 都 watch abc
但是并发时 Redis Server 中只会有一个线程在执行,
当 A 修改了 watch 命令监视的 key 后,会改变 abc 的 watched_keys 的状态为 dirty,
客户端 B 会检查这个被 watch 的 abc,发现他的状态是 dirty 的时候就会终止事务

Redis 如何节省内存

关键词:ziplist、quicklist、对象共享

Ziplist 是一个紧凑的数据结构,每一个元素之间都是连续的内存,如果在 Redis 中,Redis 启用的数据结构数据量很小时,Redis 就会切换到使用紧凑存储的形式来进行压缩存储

Quicklist 是 ziplist 的双向链表版本,可以在两端执行 push 和 pop 操作

对象共享:指的就是多个key的value是一样的话,就把多个key指向同一个value即可,如下图:

6902e5d945eb8e63ad208e42ebe37167.png

A和B都指向值100,则A、B 共用同一个100对象

Redis 的过期策略

  1. 定时删除:创建一个定时器,让定时器在键过期时来执行删除
    1. 对CPU不友好
    2. 影响性能
  2. 定期删除:每隔一段时间,程序都要对数据库进行一次检查,删除里面的过期键,至于要删除多少过期键,由算法而定。
    1. 要么对 CPU 不友好
    2. 要么对内存不友好
  3. 惰性删除:get Key 的时候才检查是否过期,过期了就删除返回 null
    1. 对内存不友好
    2. 可能导致内存溢出

Redis 同步策略

最简单的架构模式就是:一台 master 和多个 slave

仅 master 开启持久化策略,负责写入操作,slave 只负责读取操作

同步的目的就是为了【读写分离】和【容灾备份】

同步的过程:

  1. slave 发送 SYNC 给 master
  2. master 接收到命令后一边缓存继续写入的命令,一边 fork 子进程生成 RDB 文件
  3. 子进程写完 RDB 之后,父进程把 RDB 发送给 slave,slave 接收 RDB 并重现数据
  4. 父进程增量地将缓存的写命令发送给 slave

Redis 为什么是单进程单线程的

注意:这里的单线程指的是处理 I/O 事件是单线程的,并发的请求进入 Redis 后会排队,只有上一个处理完了,才会继续处理下一个。

注意:Redis 可不完全是单进程的,开启持久化的时候,会 fork 子进程完成 RDB/AOF 的创建

6c7ec51c905f02a8320cf6be68c48db0.png
Redis 的线程模型

d6b368865e21af74c7565f99418118f4.png
命令处理过程

我们所谓的多线程操作是为了加快计算,所以开启多个线程同步操作,而这会耗费大量的 CPU 资源。

Redis 设计之初就是纯内存运行,计算速度够快了,若再使用多线程操作的话会因为线程管理问题以及上下文切换耗时,反而会降低性能。Redis 官方测试中一台普通的笔记本电脑没鸟的QPS可达十几万,所以目前来看没有必要使用多线程。

客户端获取 value 阻塞时,却不会影响后面的命令的执行

Redis 为什么这么快

  1. 纯内存运行
  2. 单线程(这个单线程指的是处理命令的时候只有一个线程执行,其他的命令加入队列阻塞)
  3. 数据结构简单,使用专门的数据结构存储数据
    1. 例如:ZSet 使用跳表存储
    2. 字符串使用 SDS(Simple Dynamic String)的结构体保存(该结构体可以存储字符串的长度,还能防止字符串溢出,实现二进制存储安全等特性)
    3. 哈希表用的是字典,且通过两个 ht 实现渐进式 rehash(有利于加快Redis响应效率)
    4. 还有通过 ZipList、QuickList 来压缩内存
  4. 非阻塞的 I/O 多路复用模型:用一个线程管理多个网络连接
    1. epoll
    2. React 线程模型

谈一下 Redis 的哈希槽

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现分区(因为一致性哈希开销很大)

数据分片就是用到了16384个槽,槽里面可存多个key

集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽

也就是说整个集群里面不管有几台机器,只有 16384 个槽,集群把槽分配给全部的实例,每个实例管理一部分的槽,如图:

51cf09e905cbc9d6c1d42bd1129a78ef.png

扩容、缩容都要涉及槽的迁移;扩容后要给新机器分配槽、缩容后要分配被释放的槽给其他节点。

传统的一致性哈希

后知后觉:面试必备:什么是一致性Hash算法?​zhuanlan.zhihu.com
677e2758b427707bdbe6f99141e92707.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

的优先级大小_如何评估需求的优先级?

一、 需求的优先级怎么定义? 很多产品经理,包括我,一定都会遇到这样的场景:“ 需求堆如山,什么都想做 ”。面对各种各样、来自各个渠道的需求,产品经理的工作职责之一,就是梳理需求的优先级。我…

html自动给图片加上水印 代码_如何给一千张图片去水印?还好我会python,100行代码轻松搞定...

写在前面近期好多网友私信我,问我编程该怎么学习、怎么入门。我觉得编程学习,就像写文章一样,需要积累。如果把代码每个字符拆开,大伙都认识,但是组合在一起,就是另外一回事了。所以我的建议是,…

html中两个图片叠放,CSS实现图片叠放(勾选图标)

场景我们经常会遇到这种场景,有一个待选图片列表,在图片上(可能是右上角也有可能时右下角)叠放一个勾选状态图标,这篇文章就记录实现这个功能的过程。原理利用flex布局space-around显示图片列表在图片的外层加一个div,同时把勾选状…

pyspark sparksession_PySpark 处理数据和数据建模

安装相关包from pyspark.sql import SparkSession from pyspark.sql.functions import udf, when, count, countDistinct from pyspark.sql.types import IntegerType,StringType from pyspark.ml.feature import OneHotEncoderEstimator, StringIndexer, VectorAssembler from…

linq查询不包含某个值的记录_MySQL行(记录)的详细操作

阅读目录一 介绍二 插入数据INSERT三 更新数据UPDATE四 删除数据DELETE五 查询数据SELECT六 权限管理一 介绍MySQL数据操作: DML在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括使用INSERT实现数据的插入UPDATE实现数据的…

听课评课记录计算机应用,教师听课的评语(精选10篇)

教师听课的评语(精选10篇)通过引导学生提炼信息提出问题解决问题,使学生再次感受了数学与现实生活的密切联系,经历了运用乘法口诀求商的计算方法的形成过程,培养了学生对知识的迁移能力。下面是小编整理的教师听课的评语(精选10篇)&#xff0…

java音频实时传输_会议室智能系统建设方案,实时远程视频协作

2019年,预计会议协作需求将持续增长,创建多功能会议室促进本地、异地协作仍然是一个强大的趋势。无论空间大小或距离远近,政府部门、企业单位以及团体组织为了实现决策指令畅通、管理层次分明,需要通过对会议室环境、多功能会议系…

依赖 netty spring_十分钟带你了解Spring的七大知识点,程序员必了解

Spring框架自诞生以来一直备受开发者青睐,有人亲切的称之为:Spring 全家桶。它包括SpringMVC、SpringBoot、Spring Cloud、Spring Cloud Dataflow等解决方案。很多研发人员把spring看作心目中最好的java项目,没有之一。所以这是重点也是难点&…

android实现手机拍照以及图片预览功能_手机系统将有A/B分区?Android 11这些变化你关注过吗...

跳票让Android 11沉淀下来并吸引了更多的消费者,在iPhone SE大规模进军主流消费市场的今天,Android这边难道不想依靠新系统扳回一局吗?在人们感叹iOS一些功能似曾相似的时候,Android 11新的突破与创新格外让人振奋。01Android 11欲…

小程序的点赞功能能和浏览次数功能_扫码点餐小程序好用吗?小程序还能实现哪些功能?...

有不少的餐厅现在都可以用小程序扫码点餐了,为什么现在很少用公众号点餐了?原因其实很简单,用公众号点餐用户还要关注公众号,第二个就是在于公众号每天发消息很烦,而小程序则没有这样的烦恼,只在使用的时候…

word计算机课教学反思,《WORD》初中信息技术的教学反思

《WORD》初中信息技术的教学反思本节课在建构主义学习理论指导下,采用“任务驱动”教学策略,借助多媒体课件,对学生实施研究式自主学习教学模式,教学中注重培养学生分析问题、解决问题的能力。通过学习和实际操作,培养…

simulink中mask设置_(实现BPSK学习Verilog)1. Simulink仿真实现

欢迎关注BUG记录知乎专栏和BUG记录公众号,关注BUG记录公众号回复101获取本文使用的Simulink仿真文件微信号:BugRec由于最近研究某个高速接口没什么实质性的突破,实在写不出太好的东西,所以就写点更为基础的东西分享给大家&#xf…

arima模型_[不说人话系列]-ARIMA模型

看文献的时候看到几个统计推理的模型,想要大概了解,想做个系列,记录自己胡说八道的数理笔记过程。如有错误,感谢您指正。文前感谢冯小姐详细认真的技术援助!1- 名称简称:ARIMA模型英文名:Auto r…

pcb天线和纯铜天线_如何简化天线设计?相控阵波束成形IC来助您

为提高性能,无线通信和雷达系统对天线架构的需求不断增长。只有那些功耗低于传统机械操纵碟形天线的天线才能实现许多新的应用。除了这些要求以外,还需要针对新的威胁或新的用户快速重新定位,传输多个数据流,并以超低的成本……正…

c语言贪吃蛇_C语言贪吃蛇完整代码

#include #include #include //windows编程头文件#include #include //控制台输入输出头文件#ifndef __cplusplustypedef char bool;#define false 0#define true 1#endif//将光标移动到控制台的(x,y)坐标点处void gotoxy(int x, int y){COORD coord;coord.X x;coord.Y y;Se…

上海市计算机一级客观题,2012年上海市高校计算机等级考试(一级)模拟卷客观题...

2012年上海市高校计算机等级考试(一级)模拟卷客观题 (5页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!11.9 积分关于防火墙,以下说法不正确的是____A____。下列属于视频制作的常用软件的…

百度云盘云知梦php_教你搭建私有云盘,简单快速,完全傻瓜式!不限速,永久有效!...

免费的云盘服务有很多,但是总感觉把重要文件存在上面不安全,动不动就跑路或者限速。辛辛苦苦收集的学习资料,一夜直接可能就会付诸东流。最稳妥的方式是存放在本地硬盘中,但是要进行共享或者不同设备之间进行交换,就显…

结束 txt进程_Python多进程抓取拉钩网十万数据

转载:Python多进程抓取拉钩网十万数据准备安装Mongodb数据库其实不是一定要使用MongoDB,大家完全可以使用MySQL或者Redis,全看大家喜好。这篇文章我们的例子是Mongodb,所以大家需要下载它。在Windows中。由于MongoDB默认的数据目录…

计算机休眠怎么唤醒,电脑休眠后,就无法唤醒了?怎么办?快速教你解决这个问题...

电脑是目前人们生活、工作中使用最多的电子产品之一,我们都经常会使用到电脑。但是如果电脑在一段时间后不使用,电脑就会自动进入休眠状态,而在进入休眠状态的之后,只有当我们将电脑唤醒了,电脑才能够回到菜单界面当中…

python爬虫爬取音乐单曲_Python爬取qq音乐的过程实例

一、前言qq music上的音乐还是不少的,有些时候想要下载好听的音乐,但有每次在网页下载都是烦人的登录什么的。于是,来了个qqmusic的爬虫。至少我觉得for循环爬虫,最核心的应该就是找到待爬元素所在url吧。二、Python爬取QQ音乐单曲…