Minor problems encountered during the use of Redis and Lua

  • 2020-09-16 07:51:28
  • OfStack

The problem

When Redis executes key or field in which get or hget does not exist, the return value at the terminal is explicitly (nil), as follows


127.0.0.1:6379> get test_version
(nil)

If the value obtained in the Lua script is null or not, it will cause a confusing problem, thinking that the null value can be judged using nil, but the goose is not the case, as shown below:


127.0.0.1:6379> get test_version
(nil)
127.0.0.1:6379> EVAL "local a = redis.call('get',KEYS[1]) print(a) if a == 'nil' then return 1 else return 0 end" 1 test_version test_version
(integer) 0

Let's take a look at the data type that executes the Lua script and returns the result


127.0.0.1:6379> get test_version
(nil)
127.0.0.1:6379> EVAL "local a = redis.call('get',KEYS[1]) return type(a)" 1 test_version test_version
"boolean"

As you can see from the above script, when Redis returns a result of (nil), its real data type is boolean, so we can directly determine that nil is problematic.

Redis official document

Look through the official documents and find the following paragraph.

Redis to Lua conversion table.

Redis integer reply - > Lua number Redis bulk reply - > Lua string Redis multi bulk reply - > Lua table (may have other Redis data types nested) Redis status reply - > Lua table with a single ok field containing the status Redis error reply - > Lua table with a single err field containing the error Redis Nil bulk reply and Nil multi bulk reply - > Lua false boolean type

Lua to Redis conversion table.

Lua number - > Redis integer reply (the number is converted into an integer) Lua string - > Redis bulk reply Lua table (array) - > Redis multi bulk reply (truncated to the first nil inside the Lua array if any) Lua table with a single ok field - > Redis status reply Lua table with a single err field - > Redis error reply Lua boolean false - > Redis Nil bulk reply.

The solution

According to the official documents, we know that the judgment Lua script returns null value, so we should directly judge true/false, and modify the judgment script as shown below


127.0.0.1:6379> get test_version
(nil)
127.0.0.1:6379> EVAL "local a = redis.call('get',KEYS[1]) if a == false then return 'empty' else return 'not empty' end" 1 test_version test_version
"empty"

conclusion


Related articles: