expire key seconds 时间复杂度:O(1)
키
의 만료 시간을 설정하세요. 시간 초과 후 키
는 자동으로 삭제됩니다. Redis 용어에서 키
와 관련된 시간 초과는 일시적입니다. key
的过期时间。超时后,将会自动删除该key
。在Redis的术语中一个key
的相关超时是volatile的。
超时后只有对key
执行DEL、SET、GETSET时才会清除。 这意味着,从概念上讲所有改变key
而不用新值替换的所有操作都将保持超时不变。 例如,使用 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,而不是过期)。
对已经有过期时间的key
执行EXPIRE
操作,将会更新它的过期时间。有很多应用有这种业务场景,例如记录会话的session。
在 Redis 版本之前 2.1.3 中,使用更改其值的命令更改具有过期集的密钥具有完全删除key的效果。由于现在修复的复制层中存在限制,因此需要此语义。
EXPIRE 将返回 0,并且不会更改具有超时集的键的超时。
1
如果成功设置过期时间。
0
如果key
key
에서 DEL, SET, GETSET을 실행해야만 지워집니다. 이는 개념적으로 키
를 새 값으로 바꾸지 않고 변경하는 모든 작업이 시간 초과를 변경하지 않고 유지한다는 의미입니다. 예를 들어 INCR
을 사용하여 키 값을 늘리거나, LPUSH
를 실행하여 새 값을 목록에 푸시하거나, HSET
를 사용하여 변경합니다. 해시 /code>의 필드<ul class=" list-paddingleft-2"><li></ul>시간 초과를 지우고 영구적인 <code>키
로 만들려면 PERSIST
명령을 사용하세요
RENAME
명령으로 key
를 수정하면 관련 시간 초과가 새 key
로 전송됩니다.
>key는 <code>RENAME
명령에 의해 수정됩니다. 예를 들어 Key_A
가 원래 존재하다가 RENAME Key_B Key_A
명령이 호출됩니다. . 이때 원래 Key_A는 무시됩니다.
가 영구적인지 또는 시간 초과로 설정되었는지는 Key_B
EXIRE/를 호출하는 것에 따라 무시됩니다. 양수가 아닌 시간 초과가 있는 PEXPIRE 또는 과거 시간이 있는 EXPIREAT/PEXPIREAT는 키가 만료되지 않고 삭제되도록 합니다(따라서 방출된 키 이벤트는 만료되지 않고 del이 됩니다).
이미 만료 시간이 있는 키
에 EXPIRE
작업을 수행하면 만료 시간이 업데이트됩니다. 세션 녹음과 같이 이 비즈니스 시나리오에는 다양한 응용 프로그램이 있습니다.
2.1.3 이전 Redis 버전에서는 값을 변경하는 명령을 사용하여 만료된 세트가 있는 키를 변경하면 키가 완전히 삭제되는 효과가 있었습니다. 현재 수정된 복제 레이어의 제한으로 인해 이 의미가 필요합니다.
1.3 반환 값
1
만료 시간이 성공적으로 설정된 경우. 0
키
가 존재하지 않거나 만료 시간을 설정할 수 없는 경우.
1.4 예 🎜🎜🎜🎜🎜 사용자가 최근 방문한 최신 N 페이지에 관심이 있는 웹 서비스가 있다고 가정합니다. 즉, 각 인접한 페이지 보기는 이전 페이지 이후 60초를 넘지 않습니다. 개념적으로 이 페이지 보기 집합을 사용자를 위한 탐색 세션으로 생각하세요. 여기에는 관련 제품을 추천할 수 있도록 사용자가 현재 찾고 있는 제품에 대한 흥미로운 정보가 포함될 수 있습니다. 🎜🎜이 패턴은 다음 전략을 사용하여 Redis에서 쉽게 모델링할 수 있습니다. 사용자가 페이지 보기를 실행할 때마다 다음 명령을 호출합니다. 🎜MULTI RPUSH pagewviews.user:<userid> http://..... EXPIRE pagewviews.user:<userid> 60 EXEC</userid></userid>
当然,这是不够的,因为有过期的key,永远不会再访问。无论如何,这些key都应过期,因此请定期 Redis 在具有过期集的key之间随机测试几个key。已过期的所有key将从key空间中删除。
具体来说,如下 Redis 每秒 10 次:
测试 20 个带有过期的随机键
删除找到的所有已过期key
如果超过 25% 的key已过期,从步骤 1 重新开始
这是一个微不足道的概率算法,基本上假设我们的样本代表整个key空间,继续过期,直到可能过期的key百分比低于 25%。在任何特定时刻,已失效的最大键数等于每秒最大写入操作数除以4,这是由内存使用所决定的。
为了在不牺牲一致性的情况下获得正确行为,当key过期时,DEL 操作将同时在 AOF 文件中合成并获取所有附加的从节点。这样做的好处是能够将过时的处理过程集中在主节点中,避免出现一致性错误的可能性。
但是,虽然连接到主节点的从节点不会独立过期key(但会等待来自master的 DEL),但它们仍将使用数据集中现有过期的完整状态,因此,当选择slave作为master时,它将能够独立过期key,完全充当master。
由于您没有及时查找和删除大量过期key,这些过期key在Redis中堆积,导致内存严重耗尽
因此还需有内存淘汰机制!
写请求无法继续服务 (DEL 请求除外),但读请求可以继续进行。这样 可以保证不会丢失数据,但是会让线上的业务不能持续进行。
config.c
createEnumConfig("maxmemory-policy", NULL, MODIFIABLE_CONFIG, maxmemory_policy_enum, server.maxmemory_policy, MAXMEMORY_NO_EVICTION, NULL, NULL),
当内存不足以容纳新写入数据时,在键空间中,随机移除某key。凭啥随机呢,至少也是把最近最少使用的key删除。
当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,没有设置过期时间的 key 也会被淘汰。
LRU的关键是看页面最后一次被使用到发生调度的时间长短,而LFU关键是看一定时间段内页面被使用的频率。
优先淘汰最少使用的 key,其中包括设置了过期时间的 key。 没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。与allkey-lru不同,这种策略仅淘汰过期的键集合。
淘汰的 key 是过期 key 集合中随机的 key。
淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。
volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。
如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。
如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。
确实有时会问这个,因为有些候选人如果确实过五关斩六将,前面的问题都答的很好,那么其实让他写一下LRU算法,可以考察一下编码功底
你可以现场手写最原始的LRU算法,那个代码量太大了,不太现实
public class LRUCache<k> extends LinkedHashMap<k> { private final int CACHE_SIZE; // 这里就是传递进来最多能缓存多少数据 public LRUCache(int cacheSize) { // true指linkedhashmap将元素按访问顺序排序 super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); CACHE_SIZE = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { // 当KV数据量大于指定缓存个数时,就自动删除最老数据 return size() > CACHE_SIZE; } }</k></k>
위 내용은 Redis의 만료 전략 및 메모리 제거 전략을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!