首页 > 编程知识 正文

redis面试题大全,redis面试题及答案

时间:2023-05-06 05:06:29 阅读:202481 作者:453

一、什么是redis

Redis是一个开源的内存中的数据结构存储系统,可以作为数据库、中间件、缓存。

二、redis的访问数量级是多少?

Redis的访问数量级问10W+/s,链接数越多访问速度越慢。

三、redis的数据结构和使用场景

redis的数据结构  https://blog.csdn.net/qq_37186247/article/details/83716627 

使用场景

1、缓存
缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多。

2、排行榜
很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。

3、计数器
什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览都得给+1,并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis提供的incr命令来实现计数器功能,内存操作,性能非常好,非常适用于这些计数场景。

4、分布式会话
集群模式下,在应用不多的情况下一般使用容器自带的session复制功能就能满足,当应用增多相对复杂的系统中,一般都会搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,而是由session服务及内存数据库管理。

5、分布式锁
在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如全局ID、减库存、秒杀等场景,并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应用中要考虑的细节要更多。

6、 社交网络
点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很方便的的实现这些功能。

7、最新列表
Redis列表结构,LPUSH可以在列表头部插入一个内容ID作为关键字,LTRIM可用来限制列表的数量,这样列表永远为N个ID,无需查询最新的列表,直接根据ID去到对应的内容页即可。

8、消息系统
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。

四、redis的单线程 |————Redis为什么这么快?

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路I/O复用模型,非阻塞IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

|—————Redis为什么是单线程?

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。所以对Redis来说,单线程和多线程结果都差不多,还不如单线程减少线程切换的消耗。

|—————Redis单线程有什么安全风险吗?

因为Redis是单线程的,很大程度上规避了线程安全的风险。但是,毕竟Redis是多线程的,所以也会出现阻塞的现象,但是在实际开发中,采用的是主从建构。所以阻塞也是很难出现的。除非是单一架构。

五、Redis的持久化机制? |————RDB     ||    快照存储

RDB的工作流程: 

1. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。

2. 父进程执行fork操作创建子进程,fork操作过程中父进程被阻塞。

3. 父进程fork完成后,bgsave命令返回“* Background saving started by pid xxx”信息,并不再阻塞父进程,可以继续响应其他命令。

4. 父进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。根据lastsave命令可以获取最近一次生成RDB的时间,对应info Persistence中的rdb_last_save_time。

5. 进程发送信号给父进程表示完胜,父进程更新统计信息。

 

|————AOF      ||      记录每次对服务器写的操作

AOF工作流程

1)所有的写入命令会追加到aof_buf中。

2)AOF缓冲区根据对应的策略向硬盘做同步操作。

3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。

4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

|——————比较

1、aof文件比rdb更新频率高,优先使用aof还原数据。

2、aof比rdb更安全也更大

3、rdb性能比aof好

4、如果两个都配了优先加载AOF

|————————RESP的解释和特点

RESP 是redis客户端和服务端之前使用的一种通讯协议;

RESP 的特点:实现简单、快速解析、可读性好

六、Redis的主从架构 |————————单机模式

特点:简单

问题:

1、内存容量有限 2、处理能力有限 3、无法高可用。

|————————主从复制

Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。

特点:

1、master/slave 角色

2、master/slave 数据相同

3、降低 master 读压力在转交从库

问题:

无法保证高可用

没有解决 master 写的压力

|————————哨兵

Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:

监控(Monitoring):    Sentinel  会不断地检查你的主服务器和从服务器是否运作正常。

提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。

特点:

1、保证高可用

2、监控各个节点

3、自动故障迁移

缺点:主从模式,切换需要时间丢数据

没有解决 master 写的压力

哨兵的介绍和配置:https://www.jianshu.com/p/06ab9daf921d

|————————集群(proxy 型)

Twemproxy 是一个 Twitter 开源的一个 redis 和 memcache 快速/轻量级代理服务器; Twemproxy 是一个快速的单线程代理程序,支持 Memcached ASCII 协议和 redis 协议。

特点:1、多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins 

2、支持失败节点自动删除

3、后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

缺点:增加了新的 proxy,需要维护其高可用。

 

failover 逻辑需要自己实现,其本身不能支持故障的自动转移可扩展性差,进行扩缩容都需要手动干预

|————————集群(直连型)

从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

特点:

1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

缺点:

1、资源隔离性较差,容易出现相互影响的情况。

2、数据通过异步复制,不保证数据的强一致性

七、Redis的穿透和雪崩

缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

八、Redis的常用指令

Keys pattern

*表示区配所有

以bit开头的

查看Exists  key是否存在

Set

设置 key 对应的值为 string 类型的 value。

setnx

设置 key 对应的值为 string 类型的 value。如果 key 已经存在,返回 0,nx 是 not exist 的意思。

删除某个key

第一次返回1 删除了 第二次返回0

Expire 设置过期时间(单位秒)

TTL查看剩下多少时间

返回负数则key失效,key不存在了

Setex

设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。

Mset

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。

Getset

设置 key 的值,并返回 key 的旧值。

Mget

一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。

Incr

对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一个不存在的 key,则设置 key 为 1

incrby

同 incr 类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0

Decr

对 key 的值做的是减减操作,decr 一个不存在 key,则设置 key 为-1

Decrby

同 decr,减指定值。

Append

给指定 key 的字符串值追加 value,返回新字符串值的长度。

Strlen

取指定 key 的 value 值的长度。

persist xxx(取消过期时间)

选择数据库(0-15库)

Select 0 //选择数据库

move age 1//把age 移动到1库

Randomkey随机返回一个key

Rename重命名

Type 返回数据类型

参考文献:https://www.cnblogs.com/jasontec/p/9699242.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。