Skip to content

Redis高频题

Redis 常用的数据结构有哪些?

  • 5 种基础数据结构 :String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
  • 3 种特殊数据结构 :HyperLogLogs(基数统计)、Bitmap (位存储)、Geospatial (地理位置)。

Redis 为什么那么快

Redis 内部做了非常多的性能优化,比较重要的主要有下面 3 点:

  • Redis 基于内存,内存的访问速度是磁盘的上千倍;
  • Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型,主要是单线程事件循环和 IO 多路复用,减少了线程上下文切换带来的开销。
  • Redis 内置了多种优化过后的数据结构实现,性能非常高。

Redis 除了做缓存,还能做什么?

  • 常规数据: 比如 session、token、、序列化后的对象 的缓存;
  • 计数: 比如用户单位时间的请求数(简单限流可以用到)、页面单位时间的访问数;
  • 分布式锁 : 通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。关于 Redis 实现分布式锁的详细介绍,可以看我写的这篇文章:分布式锁详解 。
  • 限流 : 一般是通过 Redis + Lua 脚本的方式来实现限流。
  • 消息队列 : Redis 自带的 list 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka,有主题和消费组的概念,支持消息持久化以及 ACK 机制。
  • 复杂业务场景 : 通过 Redis 以及 Redis 扩展(比如 Redisson)提供的数据结构,我们可以很方便地完成很多复杂的业务场景比如通过 bitmap 统计活跃用户、通过 sorted set 维护排行榜。

Redis 事务的特性和限制是什么?

Redis事务提供了一种将多个命令打包,然后一次性、顺序地执行的机制。其特性包括:

1、原子性: 事务中的所有命令作为一个整体被执行,要么全部执行,要么一个都不执行。

2、隔离性: 事务执行期间,事务内的命令请求不会被其他客户端命令请求所中断。

3、顺序性: 事务中的命令按照添加到事务的顺序依次执行。

然而,Redis事务也有其限制:

1、不支持回滚: 如果事务中某个命令执行失败,事务的其余命令仍将被执行。

2、没有隔离级别的概念: 在Redis事务执行期间,其他客户端提交的命令可能会在事务命令之间执行。

多说一句,就把redis的事务当个笑话吧~~

Redis key过期策略

  reids key的删除策略有两种:惰性删除、定期删除

惰性删除:

  惰性删除不会主动的删除数据,而是在访问数据的时候判断该key是否过期,如果过期则删除并返回null给客户端,未过期则返回value值。有点是简单,不需要对过期数据做额外的处理,对CPU友好,对内存不友好。如果过期的key一直没有被访问则数据一直存在内存中。

定期删除:

  Redis 会周期性的随机测试一批设置过期时间的key进行处理,发现过期的key则删除。

  • 定时删除:

  在设置某个key的过期时间同事,我们创建一个定时器,让定时器在过期时间到达是,立即执行删除操作。如果key过多,会存在大量的定时器,对CPU是一个负担。

  • 定期删除:

  每隔一段时间,我们对一些key进行检查,删除里面过期的key。可以通过限制删除操作执行的时长和评率来减少删除操作对CPU的影响。

Redis 内存淘汰策略

  Redis 是不断的删除一些过期数据,但也有很多数据未设置过期时间,如果Redis内存不足是,Redis 会出发内存淘汰策略,删除一些不常用的数据,已保证Redis服务器正常运行,根据不同的淘汰策略有不同的效果,淘汰策略如下:

Redis 4.0之前

  • volatile-lru: 利用LRU算法移除设置过期时间的key
  • allkeys-lru: 根据键的最近访问时间来淘汰数据,即淘汰最久未被访问的键。该策略适用于热点数据较多的场景,能够保留最近被访问过的数据。
  • volatile-ttl: 从设置已过期时间的数据集(server.db[i].expires)中选择将要过期的数据淘汰。
  • volatile-random(带过期时间的随机淘汰): 在设置了过期时间的键中,随机选择键来淘汰。
  • allkeys-random(任意数据随机淘汰): 从数据集server.db[i].dict 中任意选择数据淘汰。
  • no-eviction(不淘汰): 当内存不足时,直接返回错误,不淘汰任何数据。该策略适用于禁止数据淘汰的场景,但需要保证内存足够。

Redis 4.0以后

  • volatile-lfu: 从已设置过期时间的数据集中,选择最不常用的数据淘汰。
  • allkeys-lfu: 在键空间中,移除最不常用的key