expire key seconds 时间复杂度:O(1)
key
の有効期限を設定します。タイムアウト後、key
は自動的に削除されます。 Redis の用語では、key
に関連付けられたタイムアウトは揮発性です。
タイムアウト後は、key
で DEL、SET、または GETSET が実行された場合にのみクリアされます。これは、概念的には、key
を新しい値に置き換えずに変更するすべての操作で、タイムアウトが変更されないことを意味します。たとえば、INCR
を使用してキーの値をインクリメントし、LPUSH
を実行して新しい値をリストにプッシュするか、HSET
を使用して フィールドを変更します。ハッシュの
、これらの操作はすべてタイムアウトを変更しないままにします。
PERSIST
コマンドを使用してタイムアウトをクリアし、永続的な key
key
が RENAME
コマンドによって変更された場合、関連するタイムアウト期間は新しい key
key は、
RENAME コマンドによって変更されます。たとえば、
Key_A はもともと存在していましたが、その後、
RENAME Key_B Key_A コマンドが呼び出されます。今回は、元の
Key_A## は無視されます。 # 永続的であるかタイムアウトに設定されているかは、Key_B
1.1 有効期限の更新
に対して EXPIRE
操作を実行すると、有効期限が更新されます。セッション記録など、このビジネス シナリオには多くのアプリケーションがあります。 1.2 2.1.3 より前の Redis の違い
EXPIRE は 0 を返し、タイムアウトが設定されているキーのタイムアウトは変更しません。
1.3 戻り値
有効期限の設定に成功した場合。
key
が存在しない場合、または有効期限を設定できない場合。
ユーザーが最近アクセスした最新の N ページに関心のある Web サービスがあるとします。隣接する各ページ ビューが前のページから 60 秒以内であること。概念的には、この一連のページ ビューはユーザーのためのナビゲーション セッションであると考えてください。ユーザーが現在探している製品に関する興味深い情報が含まれているため、関連製品を推奨できるようになります。
このパターンは、次の戦略を使用して Redis で簡単にモデル化できます: ユーザーがページ ビューを実行するたびに、次のコマンドを呼び出します:
MULTI RPUSH pagewviews.user:<userid> http://..... EXPIRE pagewviews.user:<userid> 60 EXEC</userid></userid>
ユーザーが 60 時間を超えてアイドル状態の場合秒後にキーを削除し、60 秒未満の差がある後続のページビューのみを記録します。このモードは、RPUSH を使用するリストの代わりに INCR を使用するように簡単に変更できます。
1.5 有効期限付きのキー
1.6 有効期限の精度
1.7 有効期限と永続性
2 Redis でキーを期限切れにする方法
2.1 遅延削除
当然,这是不够的,因为有过期的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 中国語 Web サイトの他の関連記事を参照してください。