Redis fundamentalsmedium3-5 years
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?
Each of the three commands is atomic on its own, but the sequence of three isn't — two concurrent requests from the same user can both run ZCARD and both see, say, nine entries (under the limit of 10), and both proceed to ZADD their own entry, because neither one's ZCARD saw the other's not-yet-added entry. The result is 11 allowed instead of 10. The fix is exactly the same principle as INCR replacing GET-then-SET: put all three steps — trim, count, conditionally add — inside one Lua script, which Redis runs as a single atomic unit, so no other client's commands can land in the middle of the check-then-add.
PreviousA scraper walking through sequential product ids, many of which don't exist, is sending every one of those requests straight through the cache to the database, even though the service already uses cache-aside. Why doesn't cache-aside help here, and what closes the gap?Next 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?
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?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?