Redis为什么快

Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器的内存的大小和网络的带宽,而且单线程的性能已经非常高了,就没有必要使用多线程了,所以 Redis 是单进程单线程的。 提示:

如果我们运行的服务器是多核服务器,为了充分利用多核优势我们可以在单台服务器起多个 Redis 服务,或者架设 主从复制、哨兵模式、集群模式等多机方案。

Redis 服务运行时只是处理客户端请求是单进程单线程的,但是服务运行时会有其他进程或线程处理其他的事,比如RDB的文件的生成就会在子进程中进行等。

Redis为什么这么快?

  1. 完全基于内存,绝大部分请求是基于内存的操作,而 Redis 的数据结构是类似于HashMap,而 HashMap 的操作时间复杂度是O(1)
  2. Redis 数据结构设计简单,方便操作
  3. 使用单线程,避免了进程或线程的上下文切换相关的消耗,不用考虑锁相关问题消耗。
  4. 使用多路I/O复用模型,非阻塞IO
  5. 使用底层模型不同,底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

什么是多路I/O复用

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。

Redis的数据过期策略

Redis 中数据过期策略采用定期删除和惰性删除策略:

  • 定期删除策略:Redis 启用一个定时器定时监视所有的 key,判断key是否过期,过期的话就删除。这种策略可以保证过期的 key 最终都会被删除,但是也存在严重的缺点:每次都遍历内存中所有的数据,非常消耗 CPU 资源,并且当 key 已过期,但是定时器还处于未唤起状态,这段时间内 key 仍然可以用。

  • 惰性删除策略:在获取 key 时,先判断 key 是否过期,如果过期则删除。这种方式存在一个缺点:如果这个 key 一直未被使用,那么它一直在内存中,其实它已经过期了,会浪费大量的空间。

这两种策略天然的互补,结合起来之后,定时删除策略就发生了一些改变,不在是每次扫描全部的 key 了,而是随机抽取一部分 key 进行检查,这样就降低了对 CPU 资源的损耗,惰性删除策略互补了为检查到的key,基本上满足了所有要求。但是有时候就是那么的巧,既没有被定时器抽取到,又没有被使用,这些数据又如何从内存中消失?没关系,还有内存淘汰机制,当内存不够用时,内存淘汰机制就会上场。

淘汰策略分为:

  1. 当内存不足以容纳新写入数据时,新写入操作会报错。(Redis 默认策略)

  2. 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(LRU推荐使用)

  3. 当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。

  4. 当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。

  5. 当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。

  6. 当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。

注意事项

Redis是基于I/O多路复用的单线程模式,所以 Redis 在处理比较耗时的命令的时候性能会受影响。可以使用 Redis 多机部署方案来应对这样的问题

最后编辑: kuteng  文档更新时间: 2021-09-14 14:49   作者:kuteng