每天十道面试题-20200405 清疚 2023-07-22 09:07 16阅读 0赞 ### 每天十道面试题-20200405 ### * * * * 题目 * 解答 * * * 题目一 * 题目二 * 题目三 * 题目四 * 题目五 * 题目六 * 题目七 * 题目八 * 题目九 * 题目十 #### 题目 #### * 1、什么是 Redis? * 2、Redis 的数据类型? * 3、使用 Redis 有哪些好处? * 4、Redis 是单进程单线程的? * 5、一个字符串类型的值能存储最大容量是多少? * 6、Redis 的持久化机制是什么?各自的优缺点? * 7、Redis 常见性能问题和解决方案? * 8、redis 过期键的删除策略? * 9、Redis 的回收策略(淘汰策略)? * 10、为什么 redis 需要把所有数据放到内存中? #### 解答 #### ###### 题目一 ###### * 题干:什么是 Redis? * 分析: * > Redis是一个非常快速的开源非关系、Key-Value数据库,通常称为数据结构服务器;它存储了五种不同类型值的键映射。用作数据库,缓存和消息代理。 > Redis和其他键值数据库之间的主要区别之一是Redis存储和操作高级数据类型的能力。这些数据类型是大多数开发人员熟悉的基本数据结构(列表,映射,集合和排序集)。Redis的卓越性能,简单性和数据结构的原子操作有助于解决使用传统关系数据库实现时难以实现或执行不佳的问题。 * 回答: * > Redis是一个非常快速的开源非关系、Key-Value数据库,通常称为数据结构服务器;它存储了五种不同类型值的键映射。用作数据库,缓存和消息代理。 > Redis和其他键值数据库之间的主要区别之一是Redis存储和操作高级数据类型的能力。这些数据类型是大多数开发人员熟悉的基本数据结构(列表,映射,集合和排序集)。Redis的卓越性能,简单性和数据结构的原子操作有助于解决使用传统关系数据库实现时难以实现或执行不佳的问题。 ###### 题目二 ###### * 题干:Redis 的数据类型? * 分析: * > Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 > String(字符串) > string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。 > string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。 > string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。 > 常用命令:set、get、decr、incr、mget等。 > 注意:一个键最大能存储512MB。 > Hash(哈希) > Redis hash 是一个键值(key=>value)对集合;是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。 > 每个 hash 可以存储 232 -1 键值对(40多亿)。 > 常用命令:hget、hset、hgetall等。 > 应用场景:存储一些结构化的数据,比如用户的昵称、年龄、性别、积分等,存储一个用户信息对象数据。 > List(列表) > Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 > list类型经常会被用于消息队列的服务,以完成多程序之间的消息交换。 > 常用命令:lpush、rpush、lpop、rpop、lrange等。 > 列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。 > Set(集合) > Redis的Set是string类型的无序集合。和列表一样,在执行插入和删除和判断是否存在某元素时,效率是很高的。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。 > 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 > 应用场景: > 1、利用交集求共同好友。 > 2、利用唯一性,可以统计访问网站的所有独立IP。 > 3、好友推荐的时候根据tag求交集,大于某个threshold(临界值的)就可以推荐。 > 常用命令:sadd、spop、smembers、sunion等。 > 集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。 > zset(sorted set:有序集合) > Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。 > 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 > zset的成员是唯一的,但分数(score)却可以重复。 > sorted set是插入有序的,即自动排序。 > 常用命令:zadd、zrange、zrem、zcard等。 > 当你需要一个有序的并且不重复的集合列表时,那么可以选择sorted set数据结构。 > 应用举例: > (1)例如存储全班同学的成绩,其集合value可以是同学的学号,而score就可以是成绩。 > (2)排行榜应用,根据得分列出topN的用户等。 * 回答: * > Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 ###### 题目三 ###### * 题干:使用 Redis 有哪些好处? * 分析: * > 1、redis最典型的应用场景,当做缓存使用,服务在处理请求时先从redis里获取结果,获取到了就可以直接返回,没有获取到的话再从数据库里获取,然后存到redis里以供下次使用。用redis的好处是可以做到分布式,有状态的数据都存在redis里,使业务服务层无状态,以便业务层有很高的可扩展性 > 2、Redis也以消息队列的形式存在,作为内嵌的List存在,满足实时的高并发需求。而通常在一个电商类型的数据处理过程之中,有关商品,热销,推荐排序的队列,通常存放在Redis之中,期间也包扩Storm对于Redis列表的读取和更新。 > 3、Redis 分布式锁。 * 回答: * > 见分析。 ###### 题目四 ###### * 题干:Redis 是单进程单线程的? * 分析: * > 为什么快? > 1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1); > 2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的; > 3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗; > 4、使用多路I/O复用模型,非阻塞IO; > 5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求; > 以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨: > (1)多路 I/O 复用模型 > 多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。 > 这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。 > 那么为什么Redis是单线程的? > 在单线程模式的情况下已经很快了,就没有必要在使用多线程了! > 但是,我们使用单线程的方式是无法发挥多核CPU 性能,不过我们可以通过在单机开多个Redis 实例来完善! > 这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!例如Redis进行持久化的时候会以子进程或者子线程的方式执行(具体是子线程还是子进程待读者深入研究);我们知道Redis是用”单线程-多路复用IO模型”来实现高性能的内存数据服务的,这种机制避免了使用锁,但是同时这种机制在进行sunion之类的比较耗时的命令时会使redis的并发下降。因为是单一线程,所以同一时刻只有一个操作在进行,所以,耗时的命令会导致并发的下降,不只是读并发,写并发也会下降。而单一线程也只能用到一个CPU核心,所以可以在同一个多核的服务器中,可以启动多个实例,组成master-master或者master-slave的形式,耗时的读命令可以完全在slave进行。“我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以,我们可以手动地为其分配CPU核,而不会过多地占用CPU,或是让我们关键进程和一堆别的进程挤在一起。”。 > CPU 是一个重要的影响因素,由于是单线程模型,Redis 更喜欢大缓存快速 CPU, 而不是多核 > 在多核 CPU 服务器上面,Redis 的性能还依赖NUMA 配置和处理器绑定位置。最明显的影响是 redis-benchmark 会随机使用CPU内核。为了获得精准的结果,需要使用固定处理器工具(在 Linux 上可以使用 taskset)。最有效的办法是将客户端和服务端分离到两个不同的 CPU 来高校使用三级缓存。 * 回答: * > 见分析。 ###### 题目五 ###### * 题干:一个字符串类型的值能存储最大容量是多少? * 分析: * > 512M * 回答: * > 512M ###### 题目六 ###### * 题干:Redis 的持久化机制是什么?各自的优缺点? * 分析: * > Redis 提供了两种持久化方式,一种是基于快照形式的 RDB,另一种是基于日志形式的 AOF,每种方式都有自己的优缺点。 > 首先说一下RDB这种机制,该机制分为两种触发模式,一个手动使用save或者bgsave命令,一个自动触发情形如下比如在配置文件中配置 save m n;在主从情况下,如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点;执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作;默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则自动执行 bgsave;save 命令和 bgsave命令;save:会阻塞当前 Redis 服务器响应其他命令,直到 RDB 快照生成完成为止,对于内存 比较大的实例会造成长时间阻塞,所以线上环境不建议使用,bgsave:Redis 主进程会 fork 一个子进程,RDB 快照生成有子进程来负责,完成之后,子进程自动结束,bgsave 只会在 fork 子进程的时候短暂的阻塞,这个过程是非常短的,所以推荐使用该命令来手动触发;1、执行 bgsave 命令,Redis 主进程判断当前是否存在正在执行的 RDB/AOF 子进程,如果存在, bgsave 命令直接返回不在往下执行。2、父进程执行 fork 操作创建子进程,fork 操作过程中父进程会阻塞,fork 完成后父进程将不在阻塞可以接受其他命令。 > 3、子进程创建新的 RDB 文件,基于父进程当前内存数据生成临时快照文件,完成后用新的 RDB 文件替换原有的 RDB 文件,并且给父进程发送 RDB 快照生成完毕通知 > RDB优点RDB 快照是某一时刻 Redis 节点内存数据,非常适合做备份,上传到远程服务器或者文件系统中,用于容灾备份 > 数据恢复时 RDB 要远远快于 AOF;缺点:RDB 持久化方式数据没办法做到实时持久化/秒级持久化。我们已经知道了 bgsave 命令每次运行都要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。 > RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式 的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题 > 如果我们对数据要求比较高,每一秒的数据都不能丢,RDB 持久化方式肯定是不能够满足要求的 > Redis 默认并没有开启 AOF 持久化方式,需要我们自行开启,在 redis.conf 配置文件中将 appendonly no 调整为 appendonly yes,这样就开启了 AOF 持久化,与 RDB 不同的是 AOF 是以记录操作命令的形式来持久化数据的,我们可以查看以下 AOF 的持久化文件 appendonly.aof > 在 AOF 持久化过程中有两个非常重要的操作:一个是将操作命令追加到 AOF\_BUF 缓存区,另一个是 AOF\_buf 缓存区数据同步到 AOF 文件, > 1、为什么要将命令写入到 aof\_buf 缓存区而不是直接写入到 aof 文件? > 我们知道 Redis 是单线程响应,如果每次写入 AOF 命令都直接追加到磁盘上的 AOF 文件中,这样频繁的 IO 开销,Redis 的性能就完成取决于你的机器硬件了,为了提升 Redis 的响应效率就添加了一层 aof\_buf 缓存层, 利用的是操作系统的 cache 技术,这样就提升了 Redis 的性能,虽然这样性能是解决了,但是同时也引入了一个问题,aof\_buf 缓存区数据如何同步到 AOF 文件呢?由谁同步呢?这就是我们接下来要聊的一个操作:fsync 操作 > 2、aof\_buf 缓存区数据如何同步到 aof 文件中? > aof\_buf 缓存区数据写入到 aof 文件是有 linux 系统去完成的,由于 Linux 系统调度机制周期比较长,如果系统故障宕机了,意味着一个周期内的数据将全部丢失,这不是我们想要的,所以 Linux 提供了一个 fsync 命令,fsync 是针对单个文件操作(比如这里的 AOF 文件),做强制硬盘同步,fsync 将阻塞直到写入硬盘完成后返回,保证了数据持久化,正是由于有这个命令,所以 redis 提供了配置项让我们自行决定何时进行磁盘同步,redis 在 redis.conf 中提供了appendfsync 配置项,有如下三个选项: > \#appendfsync always > \#appendfsync everysec > \#appendfsync no > always:每次有写入命令都进行缓存区与磁盘数据同步,这样保证不会有数据丢失,但是这样会导致 redis 的吞吐量大大下降,下降到每秒只能支持几百的 TPS ,这违背了 redis 的设计,所以不推荐使用这种方式 > everysec:这是 redis 默认的同步机制,虽然每秒同步一次数据,看上去时间也很快的,但是它对 redis 的吞吐量没有任何影响,每秒同步一次的话意味着最坏的情况下我们只会丢失 1 秒的数据, 推荐使用这种同步机制,兼顾性能和数据安全 > no:不做任何处理,缓存区与 aof 文件同步交给系统去调度,操作系统同步调度的周期不固定,最长会有 30 秒的间隔,这样出故障了就会丢失比较多的数据。 > 这就是三种磁盘同步策略,但是你有没有注意到一个问题,AOF 文件都是追加的,随着服务器的运行 AOF 文件会越来越大,体积过大的 AOF 文件对 redis 服务器甚至是主机都会有影响,而且在 Redis 重启时加载过大的 AOF 文件需要过多的时间,这些都是不友好的,那 Redis 是如何解决这个问题的呢?Redis 引入了重写机制来解决 AOF 文件过大的问题。 > 3、Redis 是如何进行 AOF 文件重写的? > Redis AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程,重写之后的 AOF 文件会比旧的 AOF 文件占更小的体积,这是由以下几个原因导致的: > 进程内已经超时的数据不再写入文件 > 旧的 AOF 文件含有无效命令,如 del key1、hdel key2、srem keys、set a111、set a222等。重写使用进程内数据直接生成,这样新的AOF文件只保 留最终数据的写入命令 > 多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c。为了防止单条命令过大造成客户端缓冲区溢 出,对于 list、set、hash、zset 等类型操作,以 64 个元素为界拆分为多条。 > 重写之后的 AOF 文件体积更小了,不但能够节约磁盘空间,更重要的是在 Redis 数据恢复时,更小体积的 AOF 文件加载时间更短。AOF 文件重写跟 RDB 持久化一样分为手动触发和自动触发,手动触发直接调用 bgrewriteaof 命令就好了,我们后面会详细聊一聊这个命令,自动触发就需要我们在 redis.conf 中修改以下几个配置 > auto-aof-rewrite-percentage 100 > auto-aof-rewrite-min-size 64mb > auto-aof-rewrite-percentage:代表当前 AOF文件空间 (aof\_current\_size)和上一次重写后 AOF 文件空间(aof\_base\_size)的比值,默认是 100%,也就是一样大的时候 > auto-aof-rewrite-min-size:表示运行 AOF 重写时 AOF 文件最小体积,默认为 64MB,也就是说 AOF 文件最小为 64MB 才有可能触发重写 > AOF 文件重写也是交给子进程来完成,跟 RDB 生成快照很像,AOF 文件重写在重写期间建立了一个 aof\_rewrite\_buf 缓存区来保存重写期间主进程响应的命令,等新的 AOF 文件重写完成后,将这部分文件同步到新的 AOF 文件中,最后用新的 AOF 文件替换掉旧的 AOF 文件。需要注意的是在重写期间,旧的 AOF 文件依然会进行磁盘同步,这样做的目的是防止重写失败导致数据丢失。 > Redis 的数据恢复流程比较简单,优先恢复的是 AOF 文件,如果 AOF 文件不存在时则尝试加载 RDB 文件,为什么 RDB 的恢复速度比 AOF 文件快,但是还是会优先加载 AOF 文件呢?我个人认为是 AOF 文件数据更全面并且 AOF 兼容性比 RDB 强,需要注意的是当存在 RDB/AOF 时,如果数据加载不成功,Redis 服务启动会失败。 * 回答: * > 自行解决 ###### 题目七 ###### * 题干:Redis 常见性能问题和解决方案? * 分析: * > 1、Redis 的过期策略以及内存淘汰机制 > 2、Redis 和数据库双写一致性问题 > 3、如何应对缓存穿透和缓存雪崩问题 > 4、如何解决 Redis 的并发竞争 Key 问题 > 第一个问题见 第八题 > **A**、Redis 和数据库双写一致性问题 > 一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。 > 答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。 > 另外,我们所做的方案从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。 > 回答:首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。 > **B**、如何应对缓存穿透和缓存雪崩问题 > 缓存穿透,即请求缓存中不存在的数据这个在正常的请求中一般时不会存在的,导致所有的请求都怼到数据库上,从而数据库连接异常。 > 缓存穿透解决方案: > ◆利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。 > ◆采用异步更新策略,无论 Key 是否取到值,都直接返回。Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。 > ◆提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的 Key。迅速判断出,请求所携带的 Key 是否合法有效。如果不合法,则直接返回。 > 缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。 > 缓存雪崩解决方案: > ◆给缓存的失效时间,加上一个随机值,避免集体失效。 > ◆使用互斥锁,但是该方案吞吐量明显下降了。 > ◆双缓存。我们有两个缓存,缓存 A 和缓存 B。缓存 A 的失效时间为 20 分钟,缓存 B 不设失效时间。自己做缓存预热操作。 > 从缓存 A 读数据库,有则直接返回;A 没有数据,直接从 B 读数据,直接返回,并且异步启动一个更新线程,更新线程同时更新缓存 A 和缓存 B。 > 如何解决 Redis 的并发竞争 Key 问题 > 这个问题大致就是,同时有多个子系统去 Set 一个 Key。这个时候大家思考过要注意什么呢? > 如果对这个 Key 操作,不要求顺序 > 这种情况下,准备一个分布式锁,大家去抢锁,抢到锁就做 set 操作即可,比较简单。 > 如果对这个 Key 操作,要求顺序 > 假设有一个 key1,系统 A 需要将 key1 设置为 valueA,系统 B 需要将 key1 设置为 valueB,系统 C 需要将 key1 设置为 valueC。 > 期望按照 key1 的 value 值按照 valueA > valueB > valueC 的顺序变化。这种时候我们在数据写入数据库的时候,需要保存一个时间戳。 > 假设时间戳如下: > 系统A key 1 \{valueA 3:00\} > 系统B key 1 \{valueB 3:05\} > 系统C key 1 \{valueC 3:10\} > 那么,假设这会系统 B 先抢到锁,将 key1 设置为\{valueB 3:05\}。接下来系统 A 抢到锁,发现自己的 valueA 的时间戳早于缓存中的时间戳,那就不做 set 操作了,以此类推。 > 其他方法,比如利用队列,将 set 方法变成串行访问也可以。总之,灵活变通。 * 回答: * > 见分析 ###### 题目八 ###### * 题干:redis 过期键的删除策略? * 分析: * > **A**、为什么不用定时删除策略 > 定时删除,用一个定时器来负责监视 Key,过期则自动删除。虽然内存及时释放,但是十分消耗 CPU 资源。 > 在大并发请求下,CPU 要将时间应用在处理请求,而不是删除 Key,因此没有采用这一策略。 > **B**、定期删除+惰性删除是如何工作 > 定期删除,Redis 默认每个 100ms 检查,是否有过期的 Key,有过期 Key 则删除。 > 需要说明的是,Redis 不是每个 100ms 将所有的 Key 检查一次,而是随机抽取进行检查(如果每隔 100ms,全部 Key 进行检查,Redis 岂不是卡死)。 > 因此,如果只采用定期删除策略,会导致很多 Key 到时间没有删除。于是,惰性删除派上用场。 > 也就是说在你获取某个 Key 的时候,Redis 会检查一下,这个 Key 如果设置了过期时间,那么是否过期了?如果过期了此时就会删除。 > **C**、采用定期删除+惰性删除就没其他问题了么? > 不是的,如果定期删除没删除 Key。然后你也没即时去请求 Key,也就是说惰性删除也没生效。这样,Redis的内存会越来越高。那么就应该采用内存淘汰机制。 > 在 redis.conf 中有一行配置: > \#maxmemory-policy volatile-lru > 该配置就是配内存淘汰策略的 > ◆noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。 > ◆allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。推荐使用,目前项目在用这种。 > ◆allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。应该也没人用吧,你不删最少使用 Key,去随机删。 > ◆volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。不推荐。 > ◆volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。依然不推荐。 > ◆volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。不推荐。 > 如果没有设置 expire 的 Key,不满足先决条件(prerequisites);那么 volatile-lru,volatile-random 和 volatile-ttl 策略的行为,和 noeviction(不删除) 基本上一致。 * 回答: * > Redis 采用的是定期删除+惰性删除策略,如果还会导致内存升高就使用内存淘汰策略,一般配置为allkeys-lru。 ###### 题目九 ###### * 题干:Redis 的回收策略(淘汰策略)? * 分析: * > 在 redis.conf 中有一行配置: > \#maxmemory-policy volatile-lru > 该配置就是配内存淘汰策略的 > ◆noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。 > ◆allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。推荐使用,目前项目在用这种。 > ◆allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。应该也没人用吧,你不删最少使用 Key,去随机删。 > ◆volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。不推荐。 > ◆volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。依然不推荐。 > ◆volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。不推荐。 > 如果没有设置 expire 的 Key,不满足先决条件(prerequisites);那么 volatile-lru,volatile-random 和 volatile-ttl 策略的行为,和 noeviction(不删除) 基本上一致。 * 回答: * > 见分析 ###### 题目十 ###### * 题干:为什么 redis 需要把所有数据放到内存中? * 分析: * > 因为单线程 基于内存 ,内存读取速度快。 * 回答: * > 因为单线程 基于内存 ,内存读取速度快。
相关 前端—每天5道面试题(十) 前端—每天5道面试题(十) > 每天进步1% 不多 就1% ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow 末蓝、/ 2023年01月23日 11:58/ 0 赞/ 36 阅读
相关 前端—每天5道面试题(十四) 前端—每天5道面试题(十四) > 每天进步1% 不多 就1% ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_sha 淡淡的烟草味﹌/ 2022年08月30日 01:42/ 0 赞/ 228 阅读
还没有评论,来说两句吧...