1. ホーム
  2. スクリプト・コラム
  3. ルア

REDISのNULL判定を読み込むサンプルコード

2022-01-09 11:12:15

プリアンブル

なぜredisデータベースの操作にluaスクリプトを使用するのですか?

1. オーバーヘッドの削減 - Redisサーバーへのリクエスト回数を減らす

2. アトミック操作 - redisはluaスクリプトをアトムとして実行します。

3. 3.再利用性 - 既に実行されたluaスクリプトを他のクライアントが使用可能

4. Redisの柔軟性を高める - luaスクリプトでredisができることを増やす

lua スクリプトは、本質的に小さく、高速に起動します。

というわけで、redis 2.6.0からredisにはサーバーサイドにluaインタプリタが内蔵されましたので、さっそく本題に入りましょう。

先日、モバイル側でデバッグ中に、redisのキャッシュをクリアした後にだけ発生するゲートウェイエラーに引っかかりました。そこで、サーバーのログを開いてみると、同じようなエラーが見つかりました。

[error] 7#7: *12030 lua entry thread aborted: runtime error: /data/share/apps/lua/access_check.lua:133: bad argument #1 to 'decode' (string expected, got userdata)

このコードの主な目的は、openresty luaでredisからデータを読み、jsonにデコードすることです。

local access_token = redis_client:read_by_key(token_key)
 if access_token == nil then
  -- do something...
  return false
 end

 local obj_token = cjson.decode(access_token)
 -- do something

その理由は、あるクエリで知ったのですが、luaがredisのデータを読み込んでnullを返すと、返ってくる結果はnilではなく、userdata型のngx.nullになるとのことです。

なぜ、このようなデザインになっているのですか?

luaではnilは特別な意味を持つため、変数にnilを設定すると、その変数は未定義(存在しない)であると伝えることと同じになります。redisクエリの結果がnilに設定され、そのクエリのキーがredisに存在する場合、nilであるクエリと未定義のクエリを区別する方法がなく、明らかに合理的ではありません。そこで、クエリのレコードがnullであることを示すためにuserdata型の値を使用する必要がありますが、未定義の変数(ngx.null)と同じではありません。

そこで、コードを以下のように修正します。

local access_token = redis_client:read_by_key(token_key)
 if access_token == ngx.null or access_token == nil then
  -- do something...
  return false
 end

 local obj_token = cjson.decode(access_token)
 -- do something

概要

上記は、この記事のすべての内容であり、私はあなたの勉強や仕事のためのこの記事の内容は、特定の参照学習価値を持って願って、あなたが交換するメッセージを残すことができる質問がある場合は、スクリプトハウスのあなたのサポートをありがとうございました。