A shop that must answer in a blink
A shop's website must know who is logged in on every click. It must also count visitors and show the last five pages each one saw.
A normal database could do this, but it is slow when thousands of people click at once. A key-value store keeps these small facts in memory and answers in a fraction of a millisecond.
By the end of this lesson
Note
I can choose a key-value store for the right job.
Key words
| Word | What it means | Example |
|---|---|---|
| Key-value store | a database that keeps a value under a name | |
| Key | the name you use to find a value | session:ada |
| Expiry | a time after which a key is removed by itself | |
| Atomic | done in one step that cannot be cut in half | |
| List | many values in order under one key | |
| Hash | named fields under one key |
The cells students fill in are left blank in this preview.
A key-value store works like a dictionary
A key-value store keeps a value under a key and gives it back when you ask for the key. It works much like a Python dictionary, but on a server that many programs share.
Valkey is a free store that keeps everything in memory. You send it a command such as SET or GET. Each reply starts with a symbol: + for a short reply, $ for text, : for a number and * for a list of replies.
Worked example: reading replies
| You send | Reply | It means |
|---|---|---|
| SET stock:mug 40 | +OK | Stored |
| GET stock:mug | $2, then 40 | Text of length 2, which is 40 |
| INCR visits | :1 | A number, the new value |
| GET nosuchkey | $-1 | Nothing is there |
The cells students fill in are left blank in this preview.
Make a tiny client called v
v() ( printf '%s\r\n' "$*" | nc -w 1 valkey 6379 )Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Store the stock of a mug
v SET stock:mug 40Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask for it back
v GET stock:mugShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A key can expire by itself
A login session must not last for ever. With EX 60 a key lives for 60 seconds, then the store removes it. You write no cleanup code.
TTL asks how many seconds are left. When a key has gone, GET answers $-1.
Store a session for a minute
v SET session:ada token123 EX 60Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask how long it has left
v TTL session:adaShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
When does a key stop existing?
# A key with an expiry is a value and the time it stops existing.
entry = ["token123", 1060]
for now in [1000, 1059, 1060, 1100]:
if now < entry[1]:
print(now, "still there:", entry[0])
else:
print(now, "expired")
# Change 1060 to 1090 and run again.
Counters and lists do work for you
INCR adds 1 to a number and returns the new value. It is atomic: a thousand visitors at once are all counted. A normal read, add and write could lose some.
A list keeps values in order under one key. RPUSH adds to the end and LLEN gives its length. A hash keeps named fields, such as a profile.
Counting views by hand
# Counting page views in a dictionary: one read, one add, one write.
visits = {}
for page in ["home", "cart", "home", "home"]:
if page in visits:
visits[page] = visits[page] + 1
else:
visits[page] = 1
print(visits)
# A key-value store does this add in one step, so many writers cannot clash.
Count a visit to the home page
v INCR visits:homeShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Record three pages Ada saw
v RPUSH recent:ada home cart payShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask what kind of value a key holds
v TYPE recent:adaShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Keep two fields of Ada's profile
v HSET user:ada name Ada city LeedsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read every field back
v HGETALL user:adaShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think a key-value store is a safe home for all data. Memory is limited, and a key can expire. Keep the master record in a database. Use the store for fast, short-lived facts.
Going further: five tries a minute
A login page allows five tries a minute for each user. Build that limit from two commands you know: INCR on a key such as tries:bo, and EXPIRE tries:bo 60 after the first try.
Run your commands six times. Write down the sixth reply and what the page should do with it.