またたく間に答える
書店のサイトは、クリックのたびに、誰がログイン中かを知る必要があります。訪問者の数を数え、一人ひとりの直近5ページも覚えなければなりません。
普通のデータベースでもできますが、何千人もが同時に押すと遅くなります。キーバリューストアは、こうした小さな事実をメモリに置き、千分の一秒以下で答えます。
このレッスンのゴール
メモ
用途に合わせて、キーバリューストアを選べます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| キーバリューストア | 名前をつけた値を保存するデータベース | |
| キー | 値を取り出すときに使う名前 | session:aya |
| 有効期限 | キーが自動で消える時刻 | |
| アトミック | 1つの手順で終わり、途中で分けられないこと | |
| リスト | 順番のある複数の値を、1つのキーの下に置いたもの | |
| ハッシュ | 名前のついた欄を、1つのキーの下に置いたもの |
学生が入力するセルは、このプレビューでは空白です。
キーバリューストアは辞書に似ている
キーバリューストアは、キーの下に値を置き、キーを渡すと値を返します。Pythonの辞書に似ていますが、多くのプログラムが共有するサーバー上にあります。
Valkeyは、すべてをメモリに置くオープンソースのストアです。SET や GET のようなコマンドを送ります。応答は記号で始まります。+ は短い応答、$ は文字、: は数字、* は応答の並びです。
例: 応答の読み方
| 送るもの | 応答 | 意味 |
|---|---|---|
| SET stock:cup 40 | +OK | 保存した |
| GET stock:cup | $2、そして 40 | 長さ2の文字で、値は40 |
| INCR visits | :1 | 数字で、新しい値 |
| GET no-such-key | $-1 | 何もない |
学生が入力するセルは、このプレビューでは空白です。
小さなクライアント v を作る
v() ( printf '%s\r\n' "$*" | nc -w 1 valkey 6379 )ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
コップの在庫を入れる
v SET stock:cup 40ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
もう一度尋ねる
v GET stock:cupここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
キーは自分で期限切れになる
ログインの記録は、いつまでも続いてはいけません。EX 60 をつけると、キーは60秒生きて、ストアが消します。後片付けのコードは要りません。
TTL は、残りの秒数を尋ねます。キーが消えたあとの GET は $-1 です。
1分間のセッションを入れる
v SET session:aya token123 EX 60ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
残り時間を尋ねる
v TTL session:ayaここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
存在しないキーを尋ねる
v GET session:missingここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
キーはいつ消えるのか
# 期限つきのキーは、値と、それが消える時刻の組です。
entry = ["token123", 1060]
for now in [1000, 1059, 1060, 1100]:
if now < entry[1]:
print(now, "まだある:", entry[0])
else:
print(now, "期限切れ")
# 1060 を 1090 に変えて、もう一度実行してみましょう。
カウンターとリストが働く
INCR は数字に1を足し、新しい値を返します。これはアトミックです。千人が同時に押しても、全員が数えられます。読む、足す、書くを別々に行うと、取りこぼすことがあります。
リストは、順番のある値を1つのキーの下に置きます。RPUSH は末尾に足し、LLEN は長さを返します。ハッシュは、プロフィールのように名前のついた欄を置きます。
閲覧数を手で数える
# ページの閲覧数を辞書で数えます。読む、足す、書く、の順です。
visits = {}
for page in ["home", "cart", "home", "home"]:
if page in visits:
visits[page] = visits[page] + 1
else:
visits[page] = 1
print(visits)
# キーバリューストアは、この足し算を1つの手順で行います。複数の書き手がいても邪魔し合いません。
トップページの閲覧を1つ数える
v INCR visits:homeここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
あやさんが見た3ページを控える
v RPUSH recent:aya home cart checkoutここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
入っている値の種類を尋ねる
v TYPE recent:ayaここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
あやさんのプロフィールをハッシュに入れる
v HSET user:aya name Aya city Sendaiここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ハッシュの欄をすべて読む
v HGETALL user:ayaここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
キーバリューストアは、すべてのデータの安全な置き場だと考えがちです。メモリには限りがあり、キーは期限切れにもなります。台帳となる記録は、データベースに置きましょう。ストアは、素早く短命な事実のために使います。
さらに先へ: ログインの回数制限
ログイン画面は、1分間に5回までしか試させないことにします。INCR と EXPIRE を使って、そのための2つのコマンドを考えてください。キーは tries:aya にします。
6回目の INCR は何を返しますか。その応答を見たら、ログイン画面は何をすべきですか。