龙空技术网

Redis面试题解答-性能优化(五)

ElevenLord 25

前言:

现在我们对“先进先出算法例题详解”大致比较关注,咱们都需要学习一些“先进先出算法例题详解”的相关文章。那么小编同时在网摘上汇集了一些关于“先进先出算法例题详解””的相关资讯,希望姐妹们能喜欢,我们快快来了解一下吧!

1. Redis 常见性能问题和解决方案有哪些?

常见问题及解决办法有:

Master 最好不要写内存快照,如果 Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一为了主从复制的速度和连接的稳定性,Master 和 Slave 最好在同一个局域网尽量避免在压力很大的主库上增加从主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1<- Slave2 <- Slave3… 这样的结构方便解决单点故障问题,实现 Slave 对 Master 的替换。如果 Master 挂了,可以立刻启用 Slave1 做 Master,其他不变。2. Redis 过期键的删除策略?

过期键的删除策略是将惰性删除策略和定期删除策略组合使用。

「1. 定时删除策略」

该策略的作用是给 key 设置过期时间的同时,给 key 创建一个定时器,定时器在 key 的过期时间来临时,对这些 key 进行删除。这样做的好处是保证内存空间得以释放。但是缺点是给 key 创建一个定时器会有一定的性能损失。如果 key 很多,删除这些 key 占用的内存空间也会占用 CPU 很多时间。

「2. 惰性删除策略」

每次从数据库取 key 的时候检查 key 是否过期,如果过期则删除,并返回 null,如果 key 没有过期,则直接返回数据。

这样做的好处是占用 CPU 的时间比较少。但是缺点是如果 key 很长时间没有被获取,将不会被删除,容易造成内存泄露。

「3. 定期删除策略」

该策略的作用是每隔一段时间执行一次删除过期 key 的操作,该删除频率可以在 redis.conf 配置文件中设置。

这样做的好处是可以避免惰性删除时出现内存泄露的问题,通过设置删除操作的时长频率,可以减少 CPU 时间的占用。但是缺点是相对内存性能友好来说,该策略不如定时删除策略,相对 CPU 性能友好来说,该策略不如惰性删除策略。

Redis 采用的删除策略是将惰性删除策略和定期删除策略组合使用。

3. Redis 的回收策略(淘汰策略)?

Redis 提供了 6 种淘汰策略:

volatile-lru:该淘汰策略是被使用最多的一种,从已设置过期时间的数据集(server.db [i].expires)中挑选最近最少使用的数据淘汰;而没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失;volatile-ttl:从已设置过期时间的数据集(server.db [i].expires)中挑选将要过期的数据淘汰,它和 volatile-lru 的区别在于 key 的剩余生存时间 ttl 的值越小越优先被淘汰,而 volatile-lru 是根据使用程度越小越被淘汰;volatile-random:从已设置过期时间的数据集(server.db [i].expires)中随机选择数据淘汰;allkeys-lru:从数据集(server.db [i].dict)中挑选最近最少使用的数据淘汰;它和 volatile-lru 淘汰机制的区别在于 allkeys-lru 针对的是全体 key 对象,淘汰的 key 不只是包括设置了过期时间的 key,也包括了没有设置过期时间的 key。而 volatile-lru 主要是针对设置了过期时间的 key 进行淘汰;allkeys-random:从数据集(server.db [i].dict)中随机选择数据淘汰;no-enviction:Redis 默认使用这种淘汰策略,当内存达到限制的时候,不淘汰任何数据,不可写入任何数据集,所有引起申请内存的命令会报错。它的优点在于可以保证数据不被丢失,但是它的缺点是会导致线上的业务不能持续进行的问题。这个淘汰策略下除了 DEL 请求和读请求服务可以继续被执行外,不能继续执行写请求。4. 如何优化 Redis 服务的性能?

主要可以从以下几点进行优化:

对 Master 节点不进行持久化工作,让 Slave 节点进行 AOF 备份,对数据做持久化操作;可以把主从节点都部署在同一个局域网内,从而保证复制速度与稳定性;根据主库的压力情况来设置或者增加从库;

主从复制的结构一定要使用单向结构,避免使用图状结构。

5. Redis 回收进程如何工作的?

当客户端运行了新命令添加新数据,Redis 都会检查内存使用情况,如果内存使用情况大于 maxmemory 的限制,那么回根据设置的淘汰策略进行回收。所以会出现内存的使用限制不断的超过边界又被回收到边界以下。

6. 都有哪些办法可以降低 Redis 的内存使用情况呢?

可以使用 Hash、list、sorted set、set 等集合类型数据,更有利于将数据存储得更紧凑,更有利于内存空间的使用。

7. Redis 的慢查询修复经验有哪些?怎么修复的?

可以对大对象数据进行拆分,防止执行一次命令操作过多的数据。也可以将一些算法复杂度高的命令或执行效率低的命令,禁用或者替换成高的指令。

8. Redis 慢查询是什么?通过什么配置?

慢查询是指系统执行命令之后,当计算系统执行的指令时间超过设置的阀值,该命令就会被记录到慢查询中,该命令叫做慢指令。

Redis 慢查询的参数配置有:

「1. slowlog-log-slower-than」

该参数的作用为设置慢查询的阈值,当命令执行时间超过这个阈值就认为是慢查询。单位为微妙,默认为 10000。

可以根据自己线上的并发量进行调整这个值。如果存在高流量的场景,那么建议设置这个值为 1 毫秒,因为每个命令执行的时间如果超过 1 毫秒,那么 Redis 的每秒操作数最多只能到 1000。

「2. slowlog-max-len」

该参数的作用为设置慢查询日志列表的最大长度,当慢查询日志列表处于最大长度时,最早插入的一个命令将会被从列表中移除。

9. Redis 如何做内存优化?

内存优化可以从以下几点进行:

Redis 对所有数据都进行 redisObject 封装;对键、值对象的长度进行缩减,简化键名,提高内存使用效率;减少 key 的数量,尽量使用哈希数据类型;共享对象池,并设置空间极限值。10. Redis 的内存用完了会发生什么?

如果 Redis 的内存使用达到了 redis.conf 配置文件中的设置上限,执行 Redis 的写命令会返回错误信息,但是还是支持读操作。解决这个问题的办法是,可以开启 Redis 的淘汰机制,当 Redis 内存达到上限时可以根据配置的策略删除一些数据,防止内存用完。

11. 缓存的更新策略有几种?分别有什么注意事项?

缓存的更新策略主要有以下几种:

先更新数据库,再更新缓存;先删除缓存,再更新数据库;先更新数据库,再删除缓存;

对应的策略分别需要注意的事项为:

「1. 先更新数据库,再更新缓存」

使用这种策略可能会存在以下两种问题:

缓存复杂度变高:写入缓存的数据如果需要经过特殊的计算,那么这时候更新缓存操作比删除缓存要复杂得多。因为更新完数据库后,得到的数据需要执行一次加工,最后得到的值才能更新缓存。线程安全存在问题:如果存在线程 1 和线程 2 同时操作数据库和缓存,线程 1 先更新了数据库,线程 2 再更新数据库,这时候由于某种原因,线程 2 首先更新了缓存,线程 1 再更新。那么这样会导致产生脏数据的问题。因为数据库存储的是线程 2 更新后的数据,而缓存存储的是线程 1 更新的老数据。

「2. 先删除缓存,再更新数据库」

这种策略可能导致数据库数据和缓存数据不一致的问题。如果存在线程 1 和线程 2,线程 1 写数据先删除缓存,有一个线程 2 正好需要查询该缓存,发现缓存不存在,去访问数据库,并得到旧值放入缓存重,线程 1 再更新数据库。那么这时就出现了数据不一致的问题。如果缓存没有过期时间,那么这个脏数据一直存在。如果要解决这个问题,那么可以在更新完数据库后,对缓存再淘汰一次。

「3. 先更新数据库,再删除缓存」

这种策略可能导致数据库数据和缓存数据不一致的问题。如果在更新完数据库还没来得及删除缓存的时候,有请求过来从缓存中获取数据,那么可能会造成缓存和数据库数据不一致的问题。但是正常情况下,机器不出现故障或其他影响的情况下,不一致性的可能性相对较低。

12. Redis 单机会有瓶颈,那么怎么解决这个瓶颈?

可以对 Redis 进行集群部署,实行主从同步读写分离,可以方便的对 Redis 进行横向扩容,可以支撑系统更大数据量的缓存和提高系统的可用性。

13. 惰性删除有什么优点和缺点?

惰性删除的优点为:对 CPU 比较友好,因为每次键空间获取键时,检查获取到的键是否过期删除,删除的键只在选中中饿键,不用花费过多的时间和资源在其它任务上,不会增加 CPU 的负担。所以对 CPU 比较友好。

惰性删除的缺点为:但是对内存并不友好,没有被选中的键也有可能存在过期的,但是未被选中删除一直存在内存中。当存在很多这些过期键一直未被获取和未被选中删除,就会一直在内存中。所以对内存并不友好。

14. Redis 是单线程的,如何提高多核 CPU 的利用率?

可以在同一个服务器部署多个 Redis 的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的,所以,如果你想使用多个 CPU,你可以考虑一下分片(shard)。

15. 什么是缓存淘汰?

因为内存的空间是有限的,所以 Redis 引入了淘汰机制,主要为了解决在某个时间点,Redis 中存在很多过期键,定期删除策略随机抽查时没有抽查到,并且也没有走惰性删除策略时,大量过期键占用内存的问题。

16. Redis 报内存不足怎么处理?

Redis 内存不足可以这样处理:

修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存;设置缓存淘汰策略,提高内存的使用效率;使用 Redis 集群模式,提高存储量。17. 如何设置 Redis 的内存上限?有什么作用?

设置方法为:修改配置文件 redis.conf 的 maxmemory 参数,该参数可以限制最大可用内存。

18. 简单介绍一下 Redis 的内存管理方式有哪些?

内存管理方式主要有两个,一是控制内存上限;二是优化回收策略,对内存回收。

19. 常见的淘汰算法有哪些?

主要常见的淘汰算法有:

「1. 最近最少使用算法(LRU)」

LRU 是 Least Recently Used 的缩写,中文意思是最近最少使用,它是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

「2. 先进先出算法(FIFO)」

FIFO 是 First Input First Output 的缩写,即先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。

「3. 最不经常使用算法(LFU)」

LFU 是 Least Frequently Used 的缩写,中文意思是最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。

20. 以下关于 NoSQL 的说法,不对的是:

A. Redis 支持字符串、哈希、列表、集合、有序集合等数据结构,目前 Redis 不支持事务。B. MongoDB 支持 CAP 定理中的 AP,MySQL 支持 CAP 中的 CA,全部都支持不可能存在。C. MongoDB 不用先创建 Collection 的结构就可以直接插入数据,目前 MongoDB 不支持事务。D. Memcache 既支持 TCP 协议,也支持UDP协议,我们可以把 PHP的 Session 存放到 Memcache 中。

答案:A

本题解析:Redis 是支持事务的。选项 A 说法错误,所以选项 A 正确。

标签: #先进先出算法例题详解 #先进先出算法例题详解及答案