redis 速度リミッターを実装するいくつかの方法。
GET INCR EXPIRE
まずキーの現在値を取得します。制限を超えていない場合は、INCR を実行して 1 ずつインクリメントします。キーが存在しない場合は、 、redisのトランザクションを使用してキーとExpirationを初期化します。
(推奨: redis ビデオ チュートリアル)
疑似コード:
count = redis.GET(key) if redis return nil { redis.MULTI redis.INCR(key) redis.EXPIRE(key, expire_time) redis.EXEC count = 1 } if count > limit { return 超出限制 } else { redis.INCR(key) }
高同時実行下での問題:
同時実行プログラムが GET を実行して nil を返した場合、これら 10 個の同時実行プログラムは Redis トランザクションを実行してキーを 1 つ増やしますが、各プログラムのカウント値は 1 です。制限で設定された値が 10 未満の場合、実際に実行されるプログラムは制限を超えています。トランザクションの実行後に redis が再度チェックされ、カウントに割り当てられた場合、各プログラムは 10 を返す可能性があるため、プログラムは実行を続行できません。
キーがすでに存在する場合、GET、INCR の順で実行するロジックによっても、実際に実行されるプログラムの数が制限を超える可能性があります。
INCR EXPIRE
最初の INCR、値が 1 の場合、キーが設定されたばかりであることを意味し、EXPIRE
疑似コードを実行します。 :
count = redis.INCR(key) if count == 1 { redis.EXPIRE(key, expire_time) } if count > limit { return 超出限制 }
使用には注意が必要です
INCR および EXPIRE が実行されなかった後にプログラムがハングする場合、キーには有効期限がありません。具体的な影響はニーズによって異なります。
lua script
local current current = redis.call("incr",KEYS[1]) if tonumber(current) == 1 then redis.call("expire",KEYS[1],1) end
redis の詳細については、redis 入門チュートリアル 列に注目してください。
以上がRedis に速度リミッターを実装するいくつかの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。