Redis fundamentalseasy0-2 years
A service increments a page-view counter in Redis by doing `GET counter`, adding one in application code, then `SET counter <newValue>`. Under load from several instances, the final count is consistently lower than the number of requests. What's happening, and what's the one-line fix?
GET and SET are each individually atomic, but the pair of them together is not — nothing stops two clients from both reading the same value, both adding one in their own application code, and both writing back the same new value, so one of the two increments is silently lost. Redis's own INCR command does the read-modify-write as a single command that runs to completion before anything else touches the key, so it can never lose an increment this way. The fix is to replace GET + application math + SET with INCR counter (or INCRBY counter <n>) and let Redis do the increment itself.
A sliding-window rate limiter — allow 10 requests per rolling second per user — is implemented by calling `ZREMRANGEBYSCORE` to trim old entries, then `ZCARD` to count what's left, then conditionally `ZADD`, as three separate Redis commands from application code. Under concurrent requests from the same user, more than 10 get allowed in some windows. What's wrong, and how does wrapping it in a Lua script fix it?A work queue built on `LPUSH` + `BRPOP` loses in-flight items whenever a worker crashes mid-job, because a popped list item is already gone from Redis the moment it's popped. A Redis stream with a consumer group is proposed instead. What does the pending entries list actually guarantee, and what obligation does it put on the workers?