TT Lab
Get started
Learn Learning paths Courses

Redis and Caching

Working With Redis Data Structures

Continue in TT Lab

Goal

Use each of Redis's six data structures for its proper purpose, and get hands-on experience with the commands you must never use in production and their alternatives.

Why it matters

Code that uses Redis with only String is everywhere. Everything is serialized as JSON and put in and taken out. It works, but to change a single field you have to read the whole thing, parse it, and write it back, and if two requests do this at the same time, one silently overwrites the other. With a Hash, only one field changes, atomically. One choice of data structure eliminates the race condition. And there is one more thing this lab must leave with you — Redis processes commands on a single thread, so a single O(N) command causes a total freeze. On an instance with millions of keys, a single KEYS * stops every request for several seconds. That is why step 7 has SCAN.

Steps

  1. Save the result of redis-cli PING to /root/rd/ping.txt.
  2. Increment app:hits 3 times. The value must be 3.
  3. In the user:42 hash, put three fields: name, email, and plan. HLEN user:42 is 3.
  4. Put 12 activities into the feed:42 list and trim it to keep only the latest 10. LLEN feed:42 is 10.
  5. Create two sets, tag:redis and tag:cache, and save their intersection to /root/rd/inter.txt. The intersection must have 2 elements.
  6. Put 5 members with scores into the score:game1 sorted set. ZCARD is 5 and ZSCORE score:game1 p3 is 30.
  7. With /root/rd/scan.sh, find all keys matching the user:* pattern using SCAN and write them to /root/rd/scan.out. The script must not contain the string KEYS.
  8. Create a markdown table in /root/rd/mem.md. The row titles are the five values string, hash, list, set, and zset, and the bytes column holds the MEMORY USAGE result.

Notes

Check the connection

Save the result of redis-cli PING to /root/rd/ping.txt.

redis-cli is interactive when run without arguments. In scripts, it is better to pass the command as an argument.

Build a counter with a String

Increment app:hits 3 times. The value must be 3.

The increment command starts from 0 even if the key does not exist. Being atomic is what makes this data structure a good counter.

Store an object with a Hash

In the user:42 hash, put three fields: name, email, and plan. HLEN user:42 is 3.

You put in and take out field by field. Think about how this differs from putting in the whole JSON.

Keep recent activity with a List

Put 12 activities into the feed:42 list and trim it to keep only the latest 10. LLEN feed:42 is 10.

Push new items to the front, and trim so the list does not grow long. There is a separate command for trimming.

Get the tag intersection with a Set

Create two sets, tag:redis and tag:cache, and save their intersection to /root/rd/inter.txt. The intersection must have 2 elements.

There is a command that finds the common elements of two sets. Do not do it with a loop in the application.

Manage scores with a ZSet

Put 5 members with scores into the score:game1 sorted set. ZCARD is 5 and ZSCORE score:game1 p3 is 30.

You put in the score and the member together. After that, you can look up just one member's score.

Iterate with SCAN instead of KEYS

With /root/rd/scan.sh, find all keys matching the user:* pattern using SCAN and write them to /root/rd/scan.out. The script must not contain the string KEYS.

Repeat until the cursor returns to 0. There is also a pattern-matching option.

Build a memory comparison table per data structure

Create a markdown table in /root/rd/mem.md. The row titles are the five values string, hash, list, set, and zset, and the bytes column holds the MEMORY USAGE result.

Store the same data in different structures and measure the actual usage. There is a command that reports usage per key.