redis 속도 제한기를 구현하는 여러 가지 방법.
GET + INCR + EXPIRE
키의 현재 값을 먼저 가져옵니다. 제한을 초과하지 않으면 INCR을 실행하고 1씩 증가시킵니다. 키가 없으면 redis의 트랜잭션을 사용하여 초기화합니다. 키 및 만료 시간.
(권장: 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) }
높은 동시성 문제:
10개의 동시 프로그램이 동시에 GET을 실행하고 nil을 반환하면 이 10개의 동시 프로그램은 모두 Redis 트랜잭션을 실행합니다. 키를 1씩 증가시키되 각 프로그램의 카운트 값은 1이 됩니다. 리미트를 10보다 작은 값으로 설정하면 실제로 실행되는 프로그램은 리미트를 초과하게 됩니다. 트랜잭션을 실행한 후 redis를 다시 확인하고 count에 할당하면 각 프로그램이 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!