Redisにおけるluaスクリプトの適用について

2324 ワード

Redisにおけるluaスクリプトの適用について
Redisはredis-cliクライアントからでも不思議なことを実現することができ、もちろん特定の言語を選択してクライアントに対応するようにすることができます.しかし、C/Sアーキテクチャの下では、luaスクリプトを導入する必要がある論理的または安全に実装できない機能がある場合があります.LuaはRedisに統合されたスクリプト言語で、luaを使用してクライアントとサーバの間で伝送する必要がなく、コードを自動的に実行できます.
サンプル要件
hash構造のフィールドに値を追加する必要があります.Redisはappendを使用して文字列タイプ変数の追跡値に名前を付けることが容易であることを知っていますが、hash構造のフィールドに値を追加するコマンドはありません.まずクライアントからフィールド値を取得し、新しい内容を追加し、最後にhashフィールド値を新しい設定するのは良い方法ではありません.一歩一歩原子ではないので、
no
Client #1
Client #2
1
HGET myhash myfield – “hello”
2
[client appends “world” to “hello”]
HSET myhash myfield goodbye – 0
3
HSET myhash myfield “hello world” – 0
4
HGET myhash myfield – “hello world”
2行目の更新フィールドの値が「goodbye」で失われているのを見ました.luaスクリプトアシスタントを使用して、この問題を解決し、クライアントから情報を送信および受信する伝送負荷を排除できます.
luaスクリプト実装
テキストエディタに次のスクリプトを入力し、happendと名前を付けます.lua:
local original = redis.call('HGET',KEYS[1],ARGV[1])
return redis.call('HSET',KEYS[1], ARGV[1], original .. ARGV[2])

最初の行では、hashフィールドの現在の値を格納するためにローカル変数originalを宣言し、keys[1]でキーを指定し、argv[1]でフィールド名を指定します.ここでluaスクリプトにおけるキーと非キーの実行の違いを理解する必要がある.
2行目は同じキーとフィールドでHSETコマンドを実行し、元の値と入力されたパラメータ値:ARGV[2]を接続してRedisを返すので、HSETの戻り値を保持します.
スクリプトの実行
evalコマンドを使用して直接実行できます.これは面倒で効率的ではありません.redisにはスクリプトキャッシュメカニズムが内蔵されており、スクリプトをプリロードした後、スクリプトに対してSHA 1サマリーを実行することで参照されます.次のコードはcatとredis-cliを使用してスクリプトをロードします.
$ redis-cli -a yourRedisPassword SCRIPT LOAD "$(cat ./happend.lua)"
"d30c7f6d0c23fcfe6d4630b11f4e3db4cb2db099"

注意:スクリプトに文字差が1つしかない場合でも、生成されるサマリースクリプトの値はまったく異なります.
redia-cliでevalsha実行スクリプトを使用して追加機能を実現できるようになりました.
> HSET mynewhash greeting "Hello"
(integer) 1
> EVALSHA d30c7f6d0c23fcfe6d4630b11f4e3db4cb2db099 1 mynewhash greeting " world"
(integer) 0
> HGET mynewhash greeting
"Hello world"

evalshaコマンドについて詳しく説明しましょう.
最初のパラメータは、script loadコマンドを使用してスクリプトを作成したsha 1サマリー情報です.2番目のパラメータはキーの数を表し、この例では1つのキーしかないので1に設定します.3番目のパラメータは操作が必要なキーで、4番目のパラメータのときに変更したいフィールドです.最後のパラメータは追加フィールドの値です.
追加はluaスクリプトで実行され、原子に属し、完全に同時に実行されるため、上述したシーンは発生しません.
まとめ
Luaはとても役に立ち、多くの問題を解決できますが、慎重に使うべきです.スクリプトの実行は、サーバをブロックし、データベースが応答しない可能性があります.スライスの場合、スクリプトはバッチ間エラーを回避するために、すべての操作を1つのサーバに保存しようとします.