为什么redis取出来是null_redis过期策略与淘汰策略

  • redis过期策略有哪几种?
惰性策略
定期策略
  • 惰性策略
含义:
key过期的时候不删除,每次从数据库获取key的
时候去检查是否过期,若过期,则删除,返回null。

优点:删除操作只发生在从数据库取出key的时候
发生,而且只删除当前key,所以对CPU时间的占用
是比较少的,(如果此时还不删除的话,我们就会
获取到了已经过期的key了)

缺点:若大量key过期,长时间没有被获取过,那么可能
发生内存泄露(无用的垃圾占用了大量的内存)
  • 定期策略
含义:
每隔一段时间执行一次删除过期key操作,每次删除随机数量

优点:
通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用,

缺点:
在内存友好方面,不如"定时删除"
在CPU时间友好方面,不如"惰性删除"

难点:
合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)
  • 定期策略为什么每次删除随机数量的过期key,而不是一次性全删除
减少性能的消耗
  • 惰性策略的实现
代码流程
  • 定期策略的实现
代码流程
  • RDB对过期key的处理
  • AOF对过期key的处理
  • 当过期key较多,定期删除漏掉了一部分,也没有走惰性删除,那么就会有大量的过期key堆积在内存中,导致redis内存耗尽,这个问题如何解决-Redis的内存淘汰机制?
noeviction: 当内存不足以容纳新写入数据时,
新写入操作会报错。(默认策略)

allkeys-lru:当内存不足以容纳新写入数据时,
在键空间(server.db[i].dict)中,移除最近
最少使用的 key(这个是最常用的)。

allkeys-random:当内存不足以容纳新写入数据时,
在键空间(server.db[i].dict)中,随机移除某个 key。

volatile-lru:当内存不足以容纳新写入数据时,
在设置了过期时间的键空间(server.db[i].expires)
中,移除最近最少使用的 key。

volatile-random:当内存不足以容纳新写入数据时,
在设置了过期时间的键空间(server.db[i].expires)
中,随机移除某个 key。

volatile-ttl:当内存不足以容纳新写入数据时,
在设置了过期时间的键空间(server.db[i].expires
)中,有更早过期时间的 key 优先移除
  • 淘汰如何生效
当Redis收到一条会添加数据的命令

Redis检查内存使用情况,是否超过最大内存限制

超过则执行内存淘汰策略,然后执行命令
  • 近似LRU策略淘汰
Redis实现的是一个近似的LRU算法,近似LRU算法通过
随机采样法淘汰数据,每次随机出5(默认)个key
,从里面淘汰掉最近最少使用的key。

Redis为了实现近似LRU算法,给每个key增加了一个
额外增加了一个24bit的字段,用来存储该key最后
一次被访问的时间。
  • 3.0针对 近似LRU的优化
新算法会维护一个候选池(大小为16),
池中的数据根据访问时间进行排序,第一次
随机选取的key都会放入池中,随后每次随机
选取的key只有在访问时间小于池中最小的时
间才会放入池中,直到候选池被放满。当放满后,
当需要淘汰时,需要从池中捞出最久没被访问的
key淘汰掉就行了


添加时增加了时间限制,为淘汰时提供了更多更优秀的
候选者
  • 参数配置优化淘汰效果
Redis LRU算法的重要意义在于,您可以通过更改样
本数量来检查每次逐出,从而调整算法的精度。

此参数由以下配置指令控制
maxmemory-samples 5
  • 新旧算法图对比

255add6a1e2f7afc33077d837d6d2f08.png
首先介绍下不同颜色的含义:
- 浅灰色带是被逐出的对象
- 灰带是未逐出的对象。
- 绿带是添加的对象


第一张图为理论的LRU结果,是理想情况,当新增绿色时,浅灰色被淘汰,灰色给予保留

第三张是redis2.8 5个样本的情况,被淘汰的浅灰色分散比较广泛,

第四张图,redis3.0 5个样本时,删选淘汰对象时增加了时间比较,绿色中几乎是没有被淘汰的
而且灰色中大部分给予保留,而浅灰色给予淘汰

第二张图,则增加样本数量,效果非常接近理论的LRU,但是CPU会消耗的更多
  • 为什么不用真正的LRU
redis之所以不使用真正的LRU实现,是因为它占用更多内存。
而近似LRU实际上与理论几乎等效
  • LFU淘汰策略
从Redis 4.0开始,可以使用新的“ 最少使用”逐出模式。
在某些情况下,此模式可能会更好地工作(提供更好的
命中率/未命中率),因为使用LFU Redis会尝试跟踪物品
的访问频率,因此,极少使用的物品会被驱逐,而经常使
用的物品则有更高的机会保留在内存中

  • 问题
1. 为什么近似LRU策略使用的内存比理论的LRU要少?
  • 参考文章
  1. redis过期策略
  2. redis内存管理
  3. redis内存管理与过期策略
  4. lru-cache lfu
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值