pc网站转换成wap,wordpress多语言企业网站,云南文山属于哪个市,网站开发工程师课程1 设置带过期时间的 key
# 时间复杂度#xff1a;O#xff08;1#xff09;#xff0c;最常用方式
expire key seconds# 字符串独有方式
setex(String key, int seconds, String value)除了string独有设置过期时间的方法#xff0c;其他类型都需依靠expire方法设置时间O1最常用方式
expire key seconds# 字符串独有方式
setex(String key, int seconds, String value)除了string独有设置过期时间的方法其他类型都需依靠expire方法设置时间若
未设置时间则缓存永不过期设置过期时间但之后又想让缓存永不过期使用persist 设置key的过期时间。超时后将会自动删除该key。在Redis的术语中一个key的相关超时是volatile的。 生存时间可以通过使用 DEL 命令来删除整个 key 来移除或者被 SET 和 GETSET 命令覆写(overwrite)。这意味着如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话那么生存时间不会被改变。 如使用 INCR 递增key的值执行 LPUSH 将新值推到 list 中或用 HSET 改变hash的field这些操作都使超时保持不变。
使用 PERSIST 命令可以清除超时使其变成一个永久key若 key 被 RENAME 命令修改相关的超时时间会转移到新key若 key 被 RENAME 命令修改比如原来就存在 Key_A然后调用 RENAME Key_B Key_A 命令这时不管原来 Key_A 是永久的还是设为超时的都会由Key_B的有效期状态覆盖 注意使用非正超时调用 EXPIRE/PEXPIRE 或具有过去时间的 EXPIREAT/PEXPIREAT 将导致key被删除而不是过期因此发出的key事件将是 del而不是过期。 1.1 刷新过期时间 对已经有过期时间的key执行EXPIRE操作将会更新它的过期时间。有很多应用有这种业务场景例如记录会话的session。
1.2 Redis 之前的 2.1.3 的差异 在 Redis 版本之前 2.1.3 中使用更改其值的命令更改具有过期集的密钥具有完全删除key的效果。由于现在修复的复制层中存在限制因此需要此语义。 EXPIRE 将返回 0并且不会更改具有超时集的键的超时。
1.3 返回值
1如果成功设置过期时间。0如果key不存在或者不能设置过期时间。
1.4 示例 假设有一 Web 服务对用户最近访问的最新 N 页感兴趣这样每个相邻页面视图在上一个页面之后不超过 60 秒。从概念上讲可以将这组页面视图视为用户的导航会话该会话可能包含有关ta当前正在寻找的产品的有趣信息以便你可以推荐相关产品。 可使用以下策略轻松在 Redis 中对此模式建模每次用户执行页面视图时您都会调用以下命令
MULTI
RPUSH pagewviews.user:userid http://.....
EXPIRE pagewviews.user:userid 60
EXEC 如果用户空闲超过 60 秒则将删除该key并且仅记录差异小于 60 秒的后续页面视图。此模式很容易修改使用 INCR 而不是使用 RPUSH 的列表。
1.5 带过期时间的 key 通常创建 Redis 键时没有关联的存活时间。key将永存除非用户以显式方式例如 DEL 命令将其删除。 EXPIRE 族的命令能够将过期项与给定key关联但代价是该key使用的额外内存。当key具有过期集时Redis 将确保在经过指定时间时删除该key。 可使用 EXPIRE 和 PERSIST 命令或其他严格命令更新或完全删除生存的关键时间。
1.6 过期精度 在 Redis 2.4 中过期可能不准确并且可能介于 0 到 1 秒之间。 Redis 2.6过期误差从 0 到 1 毫秒。
1.7 过期和持久化 过期信息的键存储为绝对 Unix 时间戳Redis 版本 2.6 或更高版本为毫秒。这意味着即使 Redis 实例不处于活动状态时间也在流动。 要使过期工作良好必须稳定计算机时间。若将 RDB 文件从两台计算机上移动其时钟中具有大 desync则可能会发生有趣的事情如加载时加载到过期的所有key。 即使运行时的实例也始终会检查计算机时钟例如如果将一个key设置为 1000 秒然后在将来设置计算机时间 2000 秒则该key将立即过期而不是持续 1000 秒。
2 过期策略 Redis 所有的数据结构都可以设置过期时间时间一到就会自动删除。你可以想象 Redis 内部有一个死神时刻盯着所有设置了过期时间的 key寿命一到就会立即收割。 你还可以进一步站在死神的角度思考会不会因为同一时间太多的 key 过期以至于忙不过来。同时因为 Redis 是单线程的收割的时间也会占用线程的处理时间如果收割的太过于繁忙会不会导致线上读写指令出现卡顿。在过期这件事上Redis 非常小心。
2.1 过期 key 集合 redis 会将每个设置了过期时间的 key 放入到一个独立的字典中以后会定时遍历这个字典来删除到期的 key。除了定时遍历之外它还会使用惰性策略来删除过期的 key所谓惰性策略就是在客户端访问这个 key 的时候redis 对 key 的过期时间进行检查如果过期了就立即删除。定时删除是集中处理惰性删除是零散处理。
2.2 定时扫描策略 Redis 默认会每秒进行十次过期扫描过期扫描不会遍历过期字典中所有的 key而是采用了一种简单的贪心策略。
从过期字典中随机 20 个 key删除这 20 个 key 中已经过期的 key如果过期的 key 比率超过 1/4那就重复步骤 1 同时为了保证过期扫描不会出现循环过度导致线程卡死现象算法还增加了扫描时间的上限默认不会超过 25ms。 设想一个大型的 Redis 实例中所有的 key 在同一时间过期了会出现怎样的结果 毫无疑问Redis 会持续扫描过期字典 (循环多次)直到过期字典中过期的 key 变得稀疏才会停止 (循环次数明显下降)。这就会导致这期间线上读写 QPS 下降明显。还有另外一种原因是内存管理器需要频繁回收内存页这也会产生一定的 CPU 消耗。 这里解析一下假如单台 Redis 读写请求 QPS 是 10w也就是每个请求需要 0.00001s 来完成每秒执行十次过期扫描每次过期扫描都达到上限 25ms那么每秒过期扫描总花费 0.25s相当于 QPS 降低了 2.5W。 所以业务开发人员一定要注意过期时间如果有大批量的 key 过期要给过期时间设置一个随机范围而不能全部在同一时间过期。
#在目标过期时间上增加一天的随机时间redis.expire_at(key, random.randint(86400) expire_ts)
2.3 从库的过期策略 从库不会进行过期扫描从库对过期的处理是被动的。主库在 key 到期时会在 AOF 文件里增加一条 del 指令同步到所有的从库从库通过执行这条 del 指令来删除过期的 key。 因为指令同步是异步进行的所以主库过期的 key 的 del 指令没有及时同步到从库的话会出现主从数据的不一致主库没有的数据在从库里还存在。
2.4 懒惰删除策略 Redis 为什么要懒惰删除(lazy free) 删除指令 del 会直接释放对象的内存大部分情况下这个指令非常快没有明显延迟。不过如果删除的 key 是一个非常大的对象比如一个包含了千万元素的 hash又或者在使用 FLUSHDB 和 FLUSHALL 删除包含大量键的数据库时那么删除操作就会导致单线程卡顿。 redis 4.0 引入了 lazyfree 的机制它可以将删除键或数据库的操作放在后台线程里执行 从而尽可能地避免服务器阻塞。
2.4.1 unlink指令 unlink 指令它能对删除操作进行懒处理丢给后台线程来异步回收内存。
unlink keyOK
2.4.2 flush指令 flushdb 和 flushall 指令用来清空数据库这也是极其缓慢的操作。Redis 4.0 同样给这两个指令也带来了异步化在指令后面增加 async 参数就可以将整棵大树连根拔起扔给后台线程慢慢焚烧。
flushall asyncOK
2.4.3 异步队列 主线程将对象的引用从「大树」中摘除后会将这个 key 的内存回收操作包装成一个任务塞进异步任务队列后台线程会从这个异步队列中取任务。任务队列被主线程和异步线程同时操作所以必须是一个线程安全的队列。 不是所有的 unlink 操作都会延后处理如果对应 key 所占用的内存很小延后处理就没有必要了这时候 Redis 会将对应的 key 内存立即回收跟 del 指令一样。
2.5 惰性删除流程 在进行get或setnx等操作时先检查key是否过期
若过期删除key然后执行相应操作若没过期直接执行相应操作
2.5.1 RDB处理过期key 过期key对RDB无影响
从内存数据库持久化数据到RDB文件持久化key之前会检查是否过期过期的key不进入RDB文件
从RDB文件恢复数据到内存数据库数据载入数据库之前会对Key进行过期检查若过期不导入数据库主库情况
2.5.2 AOF处理过期Key 过期key对AOF没有任何影响。
2.5.2.1 从内存数据库持久化到AOF文件
当key过期后还没有被删除此时进行执行持久化操作该key不会进入aof文件因为没有发生修改命令当key过期后在发生删除操作时程序会向aof文件追加一条del命令在将来的以aof文件恢复数据的时候该过期的键就会被删掉
2.5.2.2 AOF重写 重写时会先判断key是否过期已过期的key不会重写到aof文件
2.5.2.3 在复制链路和 AOF 文件中处理过期的方式 为了在不牺牲一致性的情况下获得正确行为当key过期时DEL 操作将同时在 AOF 文件中合成并获取所有附加的从节点。这样过期的这个处理过程集中到主节点中还没有一致性错误的可能性。 但是虽然连接到主节点的从节点不会独立过期key但会等待来自master的 DEL但它们仍将使用数据集中现有过期的完整状态因此当选择slave作为master时它将能够独立过期key完全充当master。 默认每台Redis服务器有16个数据库默认使用0号数据库所有的操作都是对0号数据库的操作
# 设置数据库数量。默认为16个库默认使用DB 0可使用select 1来选择一号数据库
# 注意由于默认使用0号数据库那么我们所做的所有的缓存操作都存在0号数据库上
# 当你在1号数据库上去查找的时候就查不到之前set过的缓存
# 若想将0号数据库上的缓存移动到1号数据库可以使用move key 1
databases 16
memcached只是用了惰性删除而redis同时使用了惰性删除与定期删除这也是二者的一个不同点可以看做是redis优于memcached的一点对于惰性删除而言并不是只有获取key的时候才会检查key是否过期在某些设置key的方法上也会检查eg.setnx key2 value2该方法类似于memcached的add方法如果设置的key2已经存在那么该方法返回false什么都不做如果设置的key2不存在那么该方法设置缓存key2-value2。假设调用此方法的时候发现redis中已经存在了key2但是该key2已经过期了如果此时不执行删除操作的话setnx方法将会直接返回false也就是说此时并没有重新设置key2-value2成功所以对于一定要在setnx执行之前对key2进行过期检查 可是很多过期key你没及时去查定期删除也漏掉了大量过期key堆积内存Redis内存殆耗尽因此内存满时还需有内存淘汰机制这就是 Redis 自己 主动删除 数据了
3 Redis 内存淘汰机制 Redis 数据库可以通过配置文件来配置最大缓存当写入的数据发现没有足够的内存可用的时候Redis 会触发内存淘汰机制。Redis 为了满足多样化场景提供了八种策略可以在 redis.config 文件中配置
volatile-lru从已设置过期时间的数据集中挑选最近最少使用的数据淘汰volatile-ttl从已设置过期时间的数据集中挑选将要过期的数据淘汰volatile-random从已设置过期时间的数据集中任意选择数据淘汰volatile-lfu从已设置过期时间的数据集中挑选使用频率最低的数据淘汰allkeys-lru从所有数据集中挑选最近最少使用的数据淘汰allkeys-lfu从所有数据集中挑选使用频率最低的数据淘汰allkeys-random从所有数据集中任意选择数据淘汰noenviction不回收任何数据返回一个写操作的错误信息。这也是默认策略
参考链接
Redis 详解_罗志宏的博客-CSDN博客
Redis 的过期策略_redis key过期策略_胖虎·的博客-CSDN博客
Redis键过期策略详解-云社区-华为云
详细聊聊Redis的过期策略_Redis_脚本之家
Redis的过期策略以及内存淘汰机制_redis过期策略以及内存淘汰机制_Felix-Yuan的博客-CSDN博客
Redis 详解_王叮咚的博客-CSDN博客