干货 | Redis高频面试题

本文介绍了Redis,一种高性能的Key-Value数据库,其特点包括快速操作、内存存储、多数据结构支持、持久化机制、过期键处理和数据淘汰策略。文章还讨论了Redis的事务、分布式锁、单线程优化以及内存管理,对比了与Memcached的区别,并列举了其主要数据类型和应用场景。
摘要由CSDN通过智能技术生成

1、简单说一下什么是Redis

关键字:Key-Value类型的内存数据库,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB,支持保存多种数据结构,支持Key-Value设置expire时间释放内存。

Redis的全称是:Remote Dictionary.Server,本质上是一个Key-Value类型的内存数据库,很像Memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。

Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。

因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。

Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 Memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。

比方说用他的List来做FIFO双向链表,实现一个轻量级的高性能消息队列服务,用他的Set可以做高性能的tag系统等等。

另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的Memcached来用。 Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

2、Redis基本数据类型与常用指令

关键词:String、List、Set、Zset、Hash

String

redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象。

List 链表(Redis用双端链表实现List)。

使用List结构,我们可以轻松地实现最新消息排队功能(比如新浪微博的TimeLine)。List的另一个应用就是消息队列,可以利用List的 PUSH 操作,将任务存放在List中,然后工作线程再用 POP 操作将任务取出进行执行。

Set 无序集合。

集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

Zset

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

3、Redis持久化机制

关键词:

RDB,即 Redis DataBase:把 Redis 服务器中内存的数据保存到一个 dump 文件中,数据的集合AOF,即 Append-only file:把所有对 Redis 服务器进行修改的命令保存到一个 aof 文件中,命令的集合

RDB,即 Redis 的内存快照,它是在某一个时间点将 Redis 的内存数据全量写入一个临时文件,当写入完成后,用该临时文件替换上一次持久化生成的文件,这样就完成了一次持久化过程。

触发过程

RDB 持久化触发分为手动和自动两种方式。

手动方式有两种:save 命令和 bgsave 命令。

自动触发方式save m n该方式在 redis.conf 中进行了说明,m 表示"间隔时间",n 表示 "变更次数",只有同时符合这两个条件才会

触发,否则"变更次数"会被继续累加到下一个"间隔时间"上。同时,该方式也不会阻塞。这个可以认为是 bgsave 的自动触发过程。

4、Redis对于过期键的删除策略

关键字:定时删除、惰性删除、定期删除

定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作;

惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过

期,那就返回该键;

定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于删除多少过期键,以及要检查多少个数据库,则

由算法决定。

5、Redis有哪几种数据淘汰策略

关键字:6种 1默认、2allkeys、3volatile

默认

  • noenviction:Redis 的默认策略,不回收数据,当达到最大内存时,新增数据返回 error

allkeys 是从全部数据集淘汰数据

  • allkeys-lru:从数据集(server.db[i].dict)中,使用LRU算法  淘汰最近最少使用的数据

  • allkeys-random:从数据集(server.db[i].dict)中,随机淘汰数据

volatile 是对已设置过期时间的数据集淘汰数据:

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中,使用LRU算法  淘汰最近最少使用的数据

  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中,越早过期的越优先被淘汰

  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中,随机淘汰数据

6、你是怎么理解Redis事务的

关键词:开启事务multi、命令入列、执行事务exec/放弃事务discard

事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命令后,才会继续处理此客户端的其他命令。事务也是其他关系型数据库  所必备的基础功能。

开启事务,multi 命令用于开启事务,multi 命令可以让客户端从非事务模式状态,变为事务模式状态,不支持嵌套使用。

命令入列,客户端进入事务状态之后,执行的所有常规 Redis 操作命令(非触发事务执行或放弃和导致入列异常的命令)会依次入列,命令入列成功后会返回 QUEUED。

执行事务的命令是 exec,放弃事务的命令是 discard。

不支持事务回滚

7、简单说明 Redis 分布式锁

关键词:单线程、重复值不可插入并返回false

使用Redis分布式锁的原理:首先,redis是单线程的,这是前提条件。redis中有值超时的设置以及重复值不可插入并返回false功能

能保证在一个进程执行了一个访问公共资源的方法时,往redis中设置了一个标识(加锁)等另一个进程同样操作这个方法时,再去

加锁,就发现已经有了,就等待,并不停的尝试加锁。

8、单线程的redis对应多核CPU怎样提升效率

关键字:多个redis

同一个服务器部署多个Redis的实例

9、Redis常见性能问题和解决方案

关键字: 持久化、同一个局域网内、单向链表结构

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

10、Redis如何做内存优化

关键字:散列表

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。

11、Redis使用场景

使用场景就很多了,可以根据项目过成中的应用场景进行描述也可以从一下几个方面进行思考

会话缓存(Session Cache)、全页缓存(FPC)、队列排行榜/计数器发布/订阅


Redis优缺点?

优点

  1. 基于内存操作,内存读写速度快。
  2. Redis是单线程的,避免线程切换开销及多线程的竞争问题。单线程是指网络请求使用一个线程来处理,即一个线程处理所有网络请求,Redis 运行时不止有一个线程,比如数据持久化的过程会另起线程。
  3. 支持多种数据类型,包括String、Hash、List、Set、ZSet等。
  4. 支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能可以有效地避免数据丢失问题。
  5. 支持事务。Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  6. 支持主从复制。主节点会自动将数据同步到从节点,可以进行读写分离。

缺点

  1. 对结构化查询的支持比较差。
  2. 数据库容量受到物理内存的限制,不适合用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的操作。
  3. Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

Redis为什么这么快?

  • 基于内存:Redis是使用内存存储,没有磁盘IO上的开销。数据存在内存中,读写速度快。

  • 单线程实现( Redis 6.0以前):Redis使用单个线程处理请求,避免了多个线程之间线程切换和锁资源争用的开销。

  • IO多路复用模型:Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间。

  • 高效的数据结构:Redis 每种数据类型底层都做了优化,目的就是为了追求更快的速度。

Redis为何选择单线程

  • 避免过多的上下文切换开销。程序始终运行在进程中单个线程内,没有多线程切换的场景。
  • 避免同步机制的开销:如果 Redis选择多线程模型,需要考虑数据同步的问题,则必然会引入某些同步机制,会导致在操作数据过程中带来更多的开销,增加程序复杂度的同时还会降低性能。
  • 实现简单,方便维护:如果 Redis使用多线程模式,那么所有的底层数据结构的设计都必须考虑线程安全问题,那么 Redis 的实现将会变得更加复杂。

Redis6.0为何引入多线程?

Redis支持多线程主要有两个原因:

  • 可以充分利用服务器 CPU 资源,单线程模型的主线程只能利用一个cpu;

  • 多线程任务可以分摊 Redis 同步 IO 读写的负荷。

Redis应用场景有哪些?

  1. 缓存热点数据,缓解数据库的压力。
  2. 利用 Redis 原子性的自增操作,可以实现计数器的功能,比如统计用户点赞数、用户访问数等。
  3. 简单的消息队列,可以使用Redis自身的发布/订阅模式或者List来实现简单的消息队列,实现异步操作。
  4. 限速器,可用于限制某个用户访问某个接口的频率,比如秒杀场景用于防止用户快速点击带来不必要的压力。
  5. 好友关系,利用集合的一些命令,比如交集、并集、差集等,实现共同好友、共同爱好之类的功能。

Memcached和Redis的区别?

  1. Redis 只使用单核,而 Memcached 可以使用多核。
  2. MemCached 数据结构单一,仅用来缓存数据,而 Redis 支持多种数据类型
  3. MemCached 不支持数据持久化,重启后数据会消失。Redis 支持数据持久化
  4. Redis 提供主从同步机制和 cluster 集群部署能力,能够提供高可用服务。Memcached 没有提供原生的集群模式,需要依靠客户端实现往集群中分片写入数据。
  5. Redis 的速度比 Memcached 快很多。
  6. Redis 使用单线程的多路 IO 复用模型,Memcached使用多线程的非阻塞 IO 模型。

Redis 数据类型有哪些?

基本数据类型

1、String:最常用的一种数据类型,String类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。

2、Hash:Hash 是一个键值对集合。

3、Set:无序去重的集合。Set 提供了交集、并集等方法,对于实现共同好友、共同关注等功能特别方便。

4、List:有序可重复的集合,底层是依赖双向链表实现的。

5、SortedSet:有序Set。内部维护了一个score的参数来实现。适用于排行榜和带权重的消息队列等场景。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值