【入門編】 Luaスクリプト実行 – Redis

やあ。Redisの世界へようこそ。
Redisをただの「速いデータ置き場」だと思っているなら、それはまだ氷山の一角しか見ていないと言ってもいい。

今日は、Redisが単なる「箱」を超えて「頭脳」を持つための魔法、「Lua(ルア)スクリプト」について話そうと思う。初心者のみんなが躓きやすいポイントを、日常の風景に例えて紐解いていくから、安心してついてきてほしい。

—

1. なぜ「スクリプト」が必要なのか?(魔法のレストランの例え)

君が非常に人気のあるレストランの店長だと想像してほしい。
お客さんが「注文する」という動作には、実は裏でいくつかの手順があるよね。

1. 在庫を確認する
2. 在庫があれば減らす
3. 注文リストに名前を追加する

もし、この3つの手順をバラバラに実行しているとどうなるだろう?「注文の途中で別のスタッフが在庫を動かしてしまい、在庫切れなのに注文を受けてしまう」といった悲劇が起きるかもしれない。

これを防ぐには、「この3つの手順を、誰にも邪魔されず一気にやり遂げる」必要がある。これがRedisにおける「アトミック(不可分)な処理」だ。

RedisのLuaスクリプトを使えば、複雑な手順を一つの「おまじない」としてサーバーに送り込み、実行中に他の誰にも邪魔させず、一瞬で終わらせることができるんだ。

—

2. Luaスクリプトの基本的な道具たち

Redisには、この「おまじない」を扱うためのコマンドがいくつか用意されている。まずはこれだけ覚えておこう。

  • `EVAL`: おまじないをその場で実行する。「今すぐこれをやって!」と命令する感じだね。
  • `SCRIPT LOAD`: おまじないをサーバーに登録する。「この手順を覚えておいて」と教え込むこと。
  • `EVALSHA`: 覚えたおまじないを呼び出す。「さっき教えた手順でやって!」と短縮して命令する。

—

3. やってみよう:在庫管理のコード

では、実際に簡単なコードを見てみよう。ここでは、「在庫が1つ以上あれば減らして、購入成功の印を出す」という処理を書いてみる。

— Luaスクリプトの例
— KEYS[1]は対象の商品、ARGV[1]は減らす数
local stock = tonumber(redis.call(‘get’, KEYS[1])) — 現在の在庫を取得
if stock > 0 then
redis.call(‘decr’, KEYS[1]) — 在庫を1つ減らす
return “OK: 購入完了”
else
return “Error: 売り切れです”
end

これを`EVAL`コマンドで実行するとこうなる。

商品「apple」の在庫を管理する例
1はKEYSの数、”apple”が対象キー
redis-cli EVAL “local stock = tonumber(redis.call(‘get’, KEYS[1])); if stock > 0 then redis.call(‘decr’, KEYS[1]); return ‘OK’; else return ‘Error’; end” 1 apple

どうだい?少し難しく見えるかもしれないが、やっていることは単純だ。「条件を確認して、実行する」という論理をサーバー側で完結させているだけなんだ。

—

4. なぜ「EVALSHA」が伝説のエンジニアに愛されるのか

`EVAL`で毎回長いスクリプトを送ると、ネットワークの帯域を無駄に消費してしまう。そこで登場するのが`SCRIPT LOAD`だ。

1. `SCRIPT LOAD`: 「この長い処理をサーバーに送るから、ハッシュ値(IDのようなもの)を返してくれ」
2. `EVALSHA `: 「さっきのIDのやつを実行して!」

こうすれば、通信量は最小限になる。大規模なシステムになればなるほど、この「通信の節約」がパフォーマンスに直結するんだ。まさに、熟練のエンジニアが好むテクニックだね。

—

5. 最後に:無理して使わなくていい

ここまで読んでくれた君に、一つだけアドバイスがある。
Luaスクリプトは強力だが、「なんでもかんでもスクリプトに詰め込まないこと」が大事だ。

スクリプトが複雑すぎると、実行中は他の処理が待たされてしまい、Redis全体のパフォーマンスが落ちる可能性がある。あくまで「複数のコマンドをアトミックに実行したい時」の切り札として使ってほしい。

ここをマスターすれば、君はもうRedisの基礎を飛び越えて、「Redisを支配する側」に一歩近づいたことになる。

もし分からないことがあれば、いつでも聞いてくれ。エンジニアとしての旅路は長いが、焦らず一歩ずつ進めば、必ず素晴らしい景色が見えるはずだ。

応援しているよ。

コメント

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