【入門編】 スクリプトの決定論的実行 – Redis

こんにちは!インフラエンジニアの先輩です。
今日は、Redisのデータ構造と操作の中でも、特に重要な「スクリプトの決定論的実行(けっていロンテキじっこう)」についてお話ししますね。

「なんだか漢字が多くて難しそう…」って身構えちゃいました?
大丈夫。専門用語はできるだけ排除して、日常の「あるある」に例えて優しく解説していくので、リラックスして聞いてください。

ここをしっかりとクリアすれば、Redisの裏側の仕組みまで見通せる、ワンランク上のエンジニアにグッと近づけますよ。それでは、さっそく行ってみましょう!

—

1. Redisの「メモ帳」と「コピーロボット」の仕組み

まず、前提としてRedisがどんなふうに動いているかをおさらいしましょう。

Redisは、超高速で動く「超高性能なメモ帳」のようなデータベースです。
そして、本番のシステムでは、このメモ帳が壊れたときのために、全く同じ内容を記録する「コピーロボット(別サーバー)」を必ず控えています。

さらに、メモ帳に起きた出来事を最初から順にノートに書き留めていく仕組み(AOFと呼ばれます)もあります。これによって、万が一電源がプツンと切れても、ノートを読み返せばデータを完全に復元できるわけです。

—

2. 「気まぐれなシェフ」が引き起こす大惨事

さて、ここからが本題です。
Redisの中では、複数の処理をまとめて一気に実行するための「スクリプト(プログラムの台本)」という機能が使えます。

ここで、料理のレシピ(スクリプト)を想像してみてください。
もし、レシピの中にこんな指示があったらどうでしょう?

  • 「その時の気分で、塩を適量入れる」
  • 「今の正確な時刻を測って、それに応じたスパイスを振る」
  • 「ランダムで当たった人に激辛ソースをかける」

メインの料理人(マスターサーバー)がこれを作るときは、「まあ、いっか」で済みます。
しかし、その作業を後ろでじっと見ているコピーロボットや、あとでノートを見返す復元係はどう思うでしょうか?

マスター:「今の気分で塩を小さじ2杯入れたよ」
コピー:「えっ、僕の今の気分だと小さじ1杯なんだけど……!?」

結果として、マスターの食べた料理と、コピーロボットが作った料理の味が全く違うものになってしまいますよね。これが、分散システムの世界で最も恐れられている「データの不整合」です。

—

3. Redisが求める「決定論」という名のルール

この「誰が、いつ、どこで実行しても、100%同じ結果にならなければならない性質」のことを、エンジニアの世界では「決定論的(Deterministic)である」と呼びます。

Redisのスクリプト実行において、このルールは絶対です。

  • 今何時かを勝手に調べちゃダメ!
  • 運任せ(ランダム)の機能を使っちゃダメ!
  • 外部の不安定なデータを勝手に読み込んじゃダメ!

もしスクリプトの中でこういう「気まぐれな行動」を許してしまうと、マスターサーバーとコピーロボットのデータの足並みが乱れ、システム全体が崩壊してしまいます。

—

4. 具体的にどう書けばいいの?(コード例)

初心者の方でもイメージしやすいように、簡単な例を見てみましょう。
Redisでは「Lua(ルア)」という優しいプログラミング言語を使ってスクリプトを書くことができます。

❌ やってはいけない例(気まぐれなスクリプト)

— 【NG】現在時刻を勝手に取得する(これは実行するたびに結果が変わる!)
local current_time = os.time()
redis.call(“SET”, “last_access”, current_time)
return “OK”

  • なぜダメなの?:実行する瞬間の「時間」によって記録される値が変わってしまうため、コピーロボットと値がズレる原因になります。

⭕ 正しい例(決定論を守ったスクリプト)

— 【OK】外から「時間」や「データ」を引数として受け取る
— スクリプト自体は、渡された材料をルール通りに調理するだけにする

— KEYS[1] = “user:1:score”, ARGV[1] = 10 (加算する点数)
local current_score = redis.call(“GET”, KEYS[1])

— スコアがまだなければ0にする
if not current_score then
current_score = 0
end

local new_score = tonumber(current_score) + tonumber(ARGV[1])
redis.call(“SET”, KEYS[1], new_score)

return new_score

  • ここがポイント!:このスクリプトは、いつ、どこで、何回実行しても、外から同じ「材料(ARGV)」さえ渡せば、絶対に同じ計算結果になります。だから、コピーロボットも安心して同じ結果を再現できるのです。

—

5. まとめ:ここをクリアすればバッチリ!

いかがでしたでしょうか?

  • Redisはコピーロボットや復元ノートとデータを同期している
  • だから、スクリプトの実行結果はいつでも・どこでも完全に一致(決定論的)しないといけない
  • 「時間」「ランダム」「外部の気まぐれ」をスクリプト内に持ち込んではいけない

この本質さえ押さえておけば、Redisのレプリケーションやバックアップの仕組みで迷うことはもうありません。

「スクリプトを書くときは、ロボットでも再現できる料理のレシピにするんだな」――そう思っていただければ完璧です。
この概念をクリアしたあなたなら、Redisの裏側で起きているドラマをしっかりと理解できる実力派エンジニアになっていますよ。

それでは、次回の解説もお楽しみに!

コメント

タイトルとURLをコピーしました