44
loading...
This website collects cookies to deliver better user experience
A single Redis instance can handle some 100,000 operations per second
Example Use-Cases and Data Model
Setup Redis and Implement the Top Categories
Top Users, Latest User Posts, and the Inbox Pattern
Lua Scripting for Atomicity
Final Thoughts and Outlook
See my previous post “How to use Database Sharding and Scale an ASP.NET Core Microservice Architecture” if you are interested in source code and more details about the example application.
SELECT CategoryId, COUNT(PostId) FROM Post GROUP BY CategoryId ORDER BY COUNT(PostId) LIMIT 10;
C:\dev>docker run --name redis -d redis
C:\dev>docker exec -it redis redis-cli
127.0.0.1:6379> ZADD CategoriesByPostCount GT 99 "Category5"
(integer) 1
> ZADD CategoriesByPostCount GT 1 "Category1"
(integer) 1
> ZADD CategoriesByPostCount GT 10 "Category2"
(integer) 1
> ZADD CategoriesByPostCount GT 100 "Category5"
(integer) 1
> ZADD CategoriesByPostCount GT 98 "Category5"
(integer) 0
> ZRANGE CategoriesByPostCount 0 9 WITHSCORES REV
1) "Category5"
2) "100"
3) "Category2"
4) "10"
5) "Category1"
6) "1"
ZRANGE CategoriesByPostCount 10 19 WITHSCORES REV
BEGIN TRANSACTION
INSERT INTO Post (...)
UPDATE Categories SET PostCount = PostCount + 1
COMMIT TRANSACTION
> ZADD {User:5}:PostsByTimestamp 3455667878 '{Title: "MyPostTitle", Category: "Category5", PostId: 13}'
(integer) 1
> ZINCRBY UsersByPostCount 1 "5"
> ZADD {User:5}:PostsByTimestamp 3455667878 '{Title: "MyPostTitle", Category: "Category5", PostId: 13}'
(integer) 0
> ZRANGE UsersByPostCount 0 9 WITHSCORES REV
1) "6"
2) "10"
3) "5"
4) "8"
5) "3"
6) "4"
7) "1"
8) "3"
> ZRANGE {User:5}:PostsByTimestamp 0 9 WITHSCORES REV
1) "{Title: \"MyPostTitle2\", Category: \"Category1\", PostId: 14}"
2) "3455667999"
3) "{Title: \"MyPostTitle\", Category: \"Category5\", PostId: 13}"
4) "3455667878"
The curly braces like in the key “{User:5}:PostsByTimestamp” are signifiers for a Redis hash tag.
> EVAL "if tonumber(redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2])) == 1 then return redis.call('INCR', KEYS[2]) else return redis.call('GET', KEYS[2]) end" 2 {User:8}:PostsByTimestamp {User:8}:PostCount 3455667999 "{Title: \"MyPostTitle2\", Category: \"Category1\", PostId: 14}"
(integer) 1
ZADD UsersByPostCount GT 1 "8"
> SCRIPT LOAD "if tonumber(redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2])) == 1 then return redis.call('INCR', KEYS[2]) else return redis.call('GET', KEYS[2]) end"
"cd9222afab5eb8d579942016a8c22427eff99429"
> EVALSHA "cd9222afab5eb8d579942016a8c22427eff99429" 2 {User:8}:PostsByTimestamp {User:8}:PostCount 4455667999 "{Title: \"MyPostTitle3\", Category: \"Category1\", PostId: 20}"
(integer) 2