ホームページ  >  記事  >  データベース  >  Redis の有効期限戦略とメモリ削除戦略の使用方法

Redis の有効期限戦略とメモリ削除戦略の使用方法

PHPz
PHPz転載
2023-06-04 09:14:421243ブラウズ

1 キーの有効期限を設定します

expire key seconds
时间复杂度:O(1)

key の有効期限を設定します。タイムアウト後、key は自動的に削除されます。 Redis の用語では、key に関連付けられたタイムアウトは揮発性です。

タイムアウト後は、key で DEL、SET、または GETSET が実行された場合にのみクリアされます。これは、概念的には、key を新しい値に置き換えずに変更するすべての操作で、タイムアウトが変更されないことを意味します。たとえば、INCR を使用してキーの値をインクリメントし、LPUSH を実行して新しい値をリストにプッシュするか、HSET を使用して フィールドを変更します。ハッシュの 、これらの操作はすべてタイムアウトを変更しないままにします。

  • PERSIST コマンドを使用してタイムアウトをクリアし、永続的な key

  • keyRENAME コマンドによって変更された場合、関連するタイムアウト期間は新しい key

  • #if に転送されます。

    key は、RENAME コマンドによって変更されます。たとえば、Key_A はもともと存在していましたが、その後、RENAME Key_B Key_A コマンドが呼び出されます。今回は、元の Key_A## は無視されます。 # 永続的であるかタイムアウトに設定されているかは、Key_B

  • の有効性ステータスによって上書きされます。 EXPIRE/PEXPIRE は、正以外のタイムアウト、または過去の時間を指定して呼び出されることに注意してください。EXPIREAT/PEXPIREAT によってキーは期限切れではなく削除されます (したがって、発行されるキー イベントは期限切れではなく del になります)。

1.1 有効期限の更新

すでに有効期限がある

key

に対して EXPIRE 操作を実行すると、有効期限が更新されます。セッション記録など、このビジネス シナリオには多くのアプリケーションがあります。 1.2 2.1.3 より前の Redis の違い

2.1.3 より前の Redis バージョンでは、値を変更するコマンドを使用して期限切れのセットを持つキーを変更すると、キーが完全に削除される効果があります。 。このセマンティクスは、現在修正されているレプリケーション層の制限のため必要です。

EXPIRE は 0 を返し、タイムアウトが設定されているキーのタイムアウトは変更しません。

1.3 戻り値

  • 1

    有効期限の設定に成功した場合。

  • #0

    key が存在しない場合、または有効期限を設定できない場合。

  • 1.4 例

Redis の有効期限戦略とメモリ削除戦略の使用方法 ユーザーが最近アクセスした最新の N ページに関心のある Web サービスがあるとします。隣接する各ページ ビューが前のページから 60 秒以内であること。概念的には、この一連のページ ビューはユーザーのためのナビゲーション セッションであると考えてください。ユーザーが現在探している製品に関する興味深い情報が含まれているため、関連製品を推奨できるようになります。

このパターンは、次の戦略を使用して Redis で簡単にモデル化できます: ユーザーがページ ビューを実行するたびに、次のコマンドを呼び出します:

MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC</userid></userid>

ユーザーが 60 時間を超えてアイドル状態の場合秒後にキーを削除し、60 秒未満の差がある後続のページビューのみを記録します。このモードは、RPUSH を使用するリストの代わりに INCR を使用するように簡単に変更できます。

1.5 有効期限付きのキー

通常、Redis キーは、関連付けられた生存時間なしで作成されます。キーは、ユーザーが明示的に削除しない限り (DEL コマンドなど) 保持されます。 EXPIRE コマンドを使用して、期限切れのアイテムを特定のキーに関連付けますが、これによりキーが追加のメモリを占有することになります。 Redis は、データが期限切れにならないように、指定された時間が経過すると期限切れのセットを含むキーを自動的に削除します。重要な存続期間は、EXPIRE および PERSIST コマンド (またはその他の厳密なコマンド) を使用して更新または完全に削除できます。

1.6 有効期限の精度

Redis 2.4 の有効期限は正確ではない可能性があり、0 ~ 1 秒の間で変動します。 Redis 2.6 以降、有効期限エラーの範囲は 0 ~ 1 ミリ秒です。

1.7 有効期限と永続性

期限切れの情報のキーを絶対 Unix タイムスタンプとして保存します。ミリ秒レベルの保存方法は、Redis バージョン 2.6 以降に適しています。これは、Redis インスタンスがアクティブでないときでも時間が流れていることを意味します。有効期限を適切に機能させるには、コンピュータの時間が安定している必要があります。クロックに大きな非同期がある 2 台のマシンから RDB ファイルを移動すると、興味深いことが起こる可能性があります (古くなったキーをすべてロードするなど)。インスタンスの実行中であっても、コンピュータの時計は常にチェックされます。たとえば、キーを 1000 秒に設定し、その後コンピュータの時刻を 2000 秒後に設定した場合、キーは 1000 秒持続するのではなく、すぐに期限切れになります。

2 Redis でキーを期限切れにする方法

キーを期限切れにする方法は 2 つあります。パッシブな方法 - 遅延削除、アクティブな方法 - 定期的な削除です。

2.1 遅延削除

クライアントがキーにアクセスしようとすると、キーは受動的に期限切れになります。つまり、Redis はキーに有効期限が設定されているかどうかを確認し、期限切れの場合は、削除されますので、何も返しません。 Redis はキーを自動的に削除しませんが、キーをクエリするときに、キーが削除されたかどうかを遅延チェックします。これは Spring の遅延初期化に似ています。

当然,这是不够的,因为有过期的key,永远不会再访问。无论如何,这些key都应过期,因此请定期 Redis 在具有过期集的key之间随机测试几个key。已过期的所有key将从key空间中删除。

2.2 定期删除

具体来说,如下 Redis 每秒 10 次:

  1. 测试 20 个带有过期的随机键

  2. 删除找到的所有已过期key

  3. 如果超过 25% 的key已过期,从步骤 1 重新开始

这是一个微不足道的概率算法,基本上假设我们的样本代表整个key空间,继续过期,直到可能过期的key百分比低于 25%。在任何特定时刻,已失效的最大键数等于每秒最大写入操作数除以4,这是由内存使用所决定的。

2.3 在复制链路和 AOF 文件中处理过期的方式

为了在不牺牲一致性的情况下获得正确行为,当key过期时,DEL 操作将同时在 AOF 文件中合成并获取所有附加的从节点。这样做的好处是能够将过时的处理过程集中在主节点中,避免出现一致性错误的可能性。

但是,虽然连接到主节点的从节点不会独立过期key(但会等待来自master的 DEL),但它们仍将使用数据集中现有过期的完整状态,因此,当选择slave作为master时,它将能够独立过期key,完全充当master。

由于您没有及时查找和删除大量过期key,这些过期key在Redis中堆积,导致内存严重耗尽

因此还需有内存淘汰机制!

3 内存淘汰

3.1 内存淘汰策略

Redis の有効期限戦略とメモリ削除戦略の使用方法

noeviction(Redis默认策略)

写请求无法继续服务 (DEL 请求除外),但读请求可以继续进行。这样 可以保证不会丢失数据,但是会让线上的业务不能持续进行。

  • config.c

createEnumConfig("maxmemory-policy", NULL, 
	MODIFIABLE_CONFIG, maxmemory_policy_enum, 
		server.maxmemory_policy, 
			MAXMEMORY_NO_EVICTION, NULL, NULL),

allkeys-random

当内存不足以容纳新写入数据时,在键空间中,随机移除某key。凭啥随机呢,至少也是把最近最少使用的key删除。

allkeys-lru(Least Recently Used)

当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,没有设置过期时间的 key 也会被淘汰。

allkeys-lfu(Least Frequently Used)

LRU的关键是看页面最后一次被使用到发生调度的时间长短,而LFU关键是看一定时间段内页面被使用的频率

volatile-lru

优先淘汰最少使用的 key,其中包括设置了过期时间的 key。 没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。与allkey-lru不同,这种策略仅淘汰过期的键集合。

volatile-lfu

volatile-random

淘汰的 key 是过期 key 集合中随机的 key。

volatile-ttl

淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。

volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。

  • 如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。

  • 如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。

3.2 手写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 サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。