Redis底层机制(RESP协议、IO模型、淘汰策略和删除策略)

      最后更新:2022-07-11 05:45:24 手机定位技术交流文章

      笔记大纲

      • 1.Resp通信协议
      • 2.雷迪斯线性IO模型
        • 重数6.0中的多线性
          • 2.1.1 Redis6.在0之前是单线吗?
          • 2.1.2 Redis6.为什么不在0之前使用多线性架构?
          • 2.1.3 Redis6.多线性0是什么?
      • 3.内存淘汰策略
        • 3.1 Noeviction
        • 3.2 Allkeys-LRU
        • 3.3 Allkeys-Random
        • 3.4 Voltaile-LRU
        • 3.5 Volatile-TTL
        • 3.6 Volatile-Random
      • 4.删除策略
        • 4.1 定时扫描
        • 4.2 惰性删除
        • 4.3懒惰自由
        • 4.4恢复内存删除

      1.Resp通信协议

      RESP(redis serialization protocol)redis序列化协议,下层使用TCP连接方法,通过tcp传输数据,然后根据分析规则对相关信息进行分析,具有实现简单 、 分析极快、人可读的特点.
      RESP可以序列不同的数据类型,例如整数、字符串、阵列和一个特定的错误类型,因为它使用前缀长度来传输数据,因此是二进制安全的。
      尽管RESP是为Redis设计的,它也可以用于其他C/S软件,但在Redis Cluster聚类模式中,节点-到节点通信协议不是RESP,而是基于 Gossip方法。
      该协议将传输的结构数据分类为五种最小单元类型,最后通过添加返回行符号来统一。
      单行字符串以+符号开始.
      2.多行字符串以$符号开始,并遵循字符串长度。
      整数值是符号的一个字符串形式,它以整数开始并遵循它。
      错误消息以-符号开始.
      该组以*开始,并遵循该组的长度。
      例如,写到Redis中设置小号欢迎命令,相应的协议内容如下: *3rn $3 rn set rn $5 rn minor rn $5 rn hello rn

      2.雷迪斯线性IO模型

      Redis基于Reactor该模型开发了一个专门的网络事件处理器:文件事件处理器FEH,这个处理器是单线程的,通过IO多路复用同时监听多个Client端的socket请求,根据socket的请求事件类型来为其选择对应的事件处理器。
      在这里插入图片描述

      重数6.0中的多线性

      2.1.1 Redis6.在0之前是单线吗?

      当Redis处理客户端请求时,处理接口连接、分析、执行和返回操作都由主线程处理。这就是所谓的单线程架构。但是严格来说,Redis不是单线程架构,除了主要的工作线程外,还有许多处理不同的任务的后端线程,例如, 连接监控, 内存清理等.

      2.1.2 Redis6.为什么不在0之前使用多线性架构?

      雷迪斯的官方解释是:雷迪斯的瓶颈不在CPU中,而是内存和网络。单线程作业的优点是高维护性和低复杂性,虽然多个线程可以带来更好的一致性,但它增加了设计的复杂性, 并改变了环境.单线程机制也降低了在雷迪斯内部实现数据结构的难度。他的 hash 、 set 和其它结构可以设计而不锁定。

      2.1.3 Redis6.多线性0是什么?

      Redis 6.0的多线性架构不会使Redis变成多线性架构,但是他的工作线性架构仍然是一个单线性架构,仅使用多线性模式进行网络IO连接,这可以提高网络IO性能,并共享Redis同步IO读写负载。
      Redis6.0的多线程默认是关闭的,可以通过配置文件开启。

      3.内存淘汰策略

      当雷迪斯内存超过物理内存限度时,内存的数据会开始和磁盘产生频繁的交换(swap)。这次交易将使雷迪斯的表现大幅下降,对于 Redis 来说, 它 的 访问量 相对 频繁,因此, 存储效率基本上是徒劳的.在生产环境中,我们不允许雷迪斯进行交换行为,为了限制内存的最大使用,Redis提供了配置参数maxmemory,以限制存储量超过预期的大小。当实际内存超过最大内存时,Redis提供了多种可选的策略(maxmemory-policy),允许用户决定如何释放新的空间以继续提供读写服务。

      3.1 Noeviction

      在这里插入图片描述

      在这种模式中,写请求将拒绝服务并提供只读请求,这是默认的方式。

      3.2 Allkeys-LRU

      在这里插入图片描述

      在所有键中, 最最近使用的键将被删除.

      3.3 Allkeys-Random

      在这里插入图片描述

      所有钥匙都随机淘汰了。

      3.4 Voltaile-LRU

      在这里插入图片描述

      在过期的密钥中,LRU是最最近用于消除缓冲区的算法。

      3.5 Volatile-TTL

      在这里插入图片描述

      在过期时间的键设置中,剩余ttl时间越小,优先排除就越大。

      3.6 Volatile-Random

      在这里插入图片描述

      一个随机淘汰是设置在过期时间的键。
      Redis使用了一个近似的LRU算法,它与原来的LRU算法不同,因为它占用了大量的额外空间,并修改了数据结构。
      Redis使用随机采样方法模拟LRU,并达到与LRU相似的效果。采样基可以配置,并且越大越接近LRU。
      Redis4.0后新增了一种淘汰策略LFU(最近访问频率)。
      Redis的最近访问时间不是通过调用系统功能获得的,并且每个调用都消耗了更大的系统功能,所以Redis缓存了一个系统时间标记,并每毫秒更新后端计划的任务。

      4.删除策略

      Redis会将每个设置了过期时间的key放入到一个独立的字典中,然后,这个词典将定期经过,以删除应付的键。除了定时遍历之外,它还使用惯性策略去删除过时的钥匙,所谓的惯性策略是当客户访问钥匙时,雷迪斯检查钥匙的有效期,如果过时, 立即删除.及时删除是集中处理的,无动删除是零散处理。

      4.1 定时扫描

      Redis默认的扫描每100ms,而过期的扫描不通过过期词典的所有键,而是使用简单的贪婪策略。
      1, 20个随机键从过期的词典;
      2. 在 这些 20 个 键 中 删除 过时 键 ;
      如果过期键比超过1/4,重复步骤1;
      假设一个大型的Redis实例中的所有键同时终止,会出现怎样的结果?毫无疑问,雷迪斯将继续扫描过期的词典,直到过时的字典中的过时的钥匙变得罕见,才会停止。这导致在行读写请求中显而易见的卡丁现象。另一个原因是,存储管理员需要经常检索存储页,这也导致了某种 CPU 的消耗。因此开发者必须小心拖延时间,如果太多的钥匙已经过期,为延迟时间设置一个随机范围,并非所有的期限都同时过期,避免缓存雪崩。
      没有从库中进行过期扫描,而从库中进行过期扫描的处理是被动的。 当密钥期限满时,主库将Del命令添加到AOF文件中,并将其与所有库同步,并通过执行这个Del命令从库中删除过时的密钥。

      4.2 惰性删除

      谓惰性策略就是在客户端访问这个key的时候,雷迪斯检查钥匙的有效期,如果过期了就立即删除,不会给你返回任何结果。

      4.3懒惰自由

      LazyFree机制使用del命令去删除大量键,或者使用 flushDB和 flushAll来删除包含大量键的数据库,导致 redis 阻塞; 此外,当 redis 清除过期数据并消除内存过时数据时,如果一个密钥偶然撞到一个大容量,服务器将被封锁。
      为了解决以上问题,Redis4.0引入了无懒机制,它可以执行在后端线程中删除键或数据库操作,因此尽量避免服务器阻塞。懒惰的原理并不难想象,逻辑删除仅在对象被删除时进行,然后把物体倒在后面,让后端线程执行真正的破坏,避免由于物体过载而引起的阻塞.例如,解除链接命令允许删除操作传递到后端线程,在执行 flushDB时,还可以在背景中执行额外的非同步命令。

      4.4恢复内存删除

      当Redis数据删除一个键或值时,被数据占有的内存不会立即向操作系统释放,而是向内存分配管理器释放,因此对于操作系统来说,Redis仍然占有这些内存空间。
      4.在0版本之后,雷迪斯提供自动的内存碎片清理,其目的是组织雷迪斯的关键数据,汇集,等等,降低内存碎片率。

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/29524.html

          热门文章

          文章分类