Redis问题回答

95 阅读8分钟

1、Redis篇

1、什么是Redis

Redis是一种C语言开发的K-V型的数据库,value支持多种数据结构,常用来在项目中做缓存使用

2、Redis有哪些优缺点

优点:

Redis数据存储在内存中,读写效率高,支持数据访问的QPS高

缺点:

受限于内存的大小,Redis存储的数据量较小

非关系型数据库,存储的数据不支持明确的关系结构

不支持事务

3、为什么要用Redis

使用Redis取决于业务的场景,在一些高QPS的场景下,使用Redis可以减轻流量直接访问数据库的压力;同时Redis也可作为分布式锁使用,在业务处理逻辑中可做前置锁的拦截判断,避免重复请求

4、为什么用Redis而不是用map/guava做缓存

Redis是分布式缓存,保证了多台机器获取的缓存数据是一致的;map和guava都是本地缓存,无法保证数据的一致性

5、Redis为什么这么快

6、redis有哪些数据类型

list、set、String、SortSet、

7、Redis的应用场景

分布式锁:

业务数据缓存:

8、什么是Redis持久化? ✅

Redis持久化指的是定期将内存中的数据库状态持久化到磁盘中,通过持久化之后的文件可以还原数据库状态

9、Redis的持久化机制是什么?各自的优缺点? ✅

Redis持久化机制有两种:一种是RDB、一种是AOF

RDB的实现机制是,定时判断配置,满足配置中指定的ms内修改的次数时,将目前数据库所有的键值对保存在rdb文件中并持久化到磁盘上;有两种方式写入rdb文件,一种是save的阻塞写入;另一种是bgsave,fork一个子进程由子进程写入rdb文件

开启方式:在redis.conf文件中配置save命令

rdb的优点是存储的数据是当前数据库键值对数据,数据量小

缺点是:上一次写入rdb文件和下一次写入rdb文件期间存在变更数据丢失的风险

每次fork子进程的时候都是copy-on-write,如果服务器内存占用量较大的时候,fork完子进程后导致内存占用变大

AOF的实现机制是,将对数据发生变更的写入命令记录在文件中,通过重新执行所有写入命令来恢复数据库状态

开启方式:在redis.conf文件中,appendonly on改为yes即可

保存写入命令的过程是:服务器接收写命令 -> 将写命令保存在aof_buf中,每次事件循环完成之后,通过判断fsync命令参数来决定aof_buf同步到aof文件的频率。fsync包含三种:always、no、everysec。分别代表每次执行完事件循环写入aof文件,不写入aof文件,每秒将aof_buf中的数据写入到aof文件

默认是everyesc。服务器单进程fork一个子进程执行aof_buf往aof文件写入的操作

随着写入命令的增加,AOF文件体积变大,增加磁盘消耗,Redis支持AOF文件重写,重写机制是遍历当前数据库键值对,用一条命令恢复当前数据信息,缩小了AOF文件体积

启动单独的进程执行AOF文件重写,不影响主进程对client端的响应,子进程重写AOF文件时,主进程响应client的写命令并将其追加到aof缓冲区,和aof重写缓冲区,子进程重写完新的aof文件之后发送一个信号函数给主进程,主进程响应之后将aof重写缓冲区的命令追加到新文件中,新文件替换旧文件,完成AOF文件重写

优点:

  • 通过fsync值配置可控制数据丢失的风险,最多丢失1秒的数据,
  • 重写时是新文件,不会对旧的AOF文件造成影响
  • AOF文件是纯追加的,如果遇到写入失败的情况,也可以用redis-check-aof工具修复数据

缺点:AOF文件体积大,恢复数据速度慢

同时打开RDB、AOF文件的时候,服务器启动时优先使用AOF文件回复数据

10、如何选择合适的持久化方式? ✅

如果使用的场景需要高性能,宕机后快速修复并且对数据完成性要求不是那么高,可以采用RDB的方式

如果对数据的完整性要求高,不能接受丢失的数据的话,采用AOF的方式

11、Redis持久化数据和缓存怎么做扩容?

 不会,不知道是哪里的知识点

-----------------------------------------过期键的删除策略-----------------------------------------------------------------------

14、Redis的过期键的删除策略 ✅

定期删除 + 惰性删除。

定时删除:创建键的时候创建一个定时器(Timer)定时器的实现是时间事件,时间时间的实现方式无序链表,查找的复杂度是O(N),处理效率低

惰性删除:读写键的时候,判断键是否过期,如果键过期了一直也不会被访问到的话,会导致无效数据占用内存变大,导致内存泄露

定期删除:Redis服务器每隔一段时间执行一次删除过期键操作,如何合理的设置定期的时长和频率?循环遍历所有数据库取n个数据库,随机去数据库中n个键,全局current_db记录每次遍历的数据库。执行完所有的数据库后current_db重置为0

默认每次检查的数据库数量,默认每个数据库每次检查的键数量

15、Redis key的过期时间和永久有效分别怎么设置? ✅

 EXPIRE   key  5    // 5秒后key过期【生存时间】
 PEXPIRE  key  108903457【秒的时间戳】  // 指定时间戳后key过期【过期时间】
 setex key 1 5 // key的value=1,在5秒后过期,只能用于key是字符串的
 ​
 EXPIREAT  key 5000   //
 PEXPIREAT key 578934270583【毫秒时间戳】
 ​
 最终的实现都是PEXPIREAT
 ​
 ttl key     // 返回key的剩余秒数
 pttl key     // 返回key的剩余毫秒
 ​
 PERSIST  key  // 移除key的过期时间

不设置key的过期时间默认是一直有效

redisDB结构中有键过期字典,存储的都是键对应的过期时间long long类型

16、我们知道通过expire来设置key 的过期时间,那么对过期的数据怎么处理呢? ✅

定时删除的时候断开过期字典中键 的指向【对应的过期时间戳】

持久化的时候对过期键的处理:

RDB持久化下对过期键的处理

  • RDB文件保存时会判断键是否过期,已过期的键不会保存在RDB文件中
  • 载入RDB文件时,主服务器模式下不会载入已过期的键数据

AOF持久化下对过期键的处理:

主从复制期间过期键的处理?

从服务器访问过期键的时候还是会照常返回;访问主服务器数据时过期键不返回,并向从服务器发送del的命令

内存超过maxmemory的时候,触发主动清理策略:在过期键中使用lru算法进行key的剔除,保证不过期数据不会被删除

删除策略:

1、allkeys-lru

2、volatile-lru

3、allkeys-random

4、volatile-random

5、不删除

6、ttl:删除距离存活时间最短的键

-----------------------------------------------------------------------内存相关---------------------------------------------------------

17、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

18、Redis的内存淘汰策略有哪些

19、Redis主要消耗什么物理资源?

20、Redis的内存用完了会发生什么?

21、Redis如何做内存优化?

-------------线程模型--------------

22、Redis线程模型

----------事务-----------

什么是事务?

23、Redis事务的概念

24、Redis事务的三个阶段

25、Redis事务相关命令

26、事务管理(ACID)概述

27、Redis事务支持隔离性吗

28、Redis事务保证原子性吗,支持回滚吗

29、Redis事务其他实现

---------集群方案-----------

哨兵模式 官方Redis Cluster 方案(服务端路由查询) 基于客户端分配 基于代理服务器分片 Redis 主从架构 Redis集群的主从复制模型是怎样的? 生产环境中的 redis 是怎么部署的? 说说Redis哈希槽的概念? Redis集群会有写操作丢失吗?为什么? Redis集群之间是如何复制的? Redis集群最大节点个数是多少? Redis集群如何选择数据库?

blog.csdn.net/ThinkWon/ar…