Контекст
Знаете ли вы, что в Redis можно запустить скрипт? Если вы не знаете, возможно, пришло время попробовать. Эта возможность выполнения сценариев предназначена для оптимизации производительности работы Redis. Однако, вероятно, вы можете добиться такой же производительности, используя функцию Redis Pipeline. В зависимости от сценариев использования, эта возможность сценариев доступна, если у вас есть очень убедительный сценарий использования.
В этой статье мы расскажем вам о различных вариантах использования скриптов Redis Lua, которые облегчат вам жизнь, а также о возможных вариантах их применения в повседневной жизни.
1. Члены HGet
Описание
Если у вас есть хэш и набор, где набор определяет определенные ключи хэша.
Пример
Допустим, у вас есть транспортные средства, 3 автомобиля Honda, 1 автомобиль Mercedes и 2 скутера. Мы можем использовать этот скрипт для подсчета количества автомобилей.
> hset cars honda 3
(integer) 1
> hset cars mercedes 1
(integer) 1
> hset motorbikes scooters 1
(integer) 1
> sadd cars honda mercedes
(integer) 2
> evalsha 700c06c5ce9835bf9eef2198c8bc4d268b3b5095 2 cars produce
1) 1) "honda"
2) "3"
2) 1) "mercedes"
2) "1"
Источник Lua:
local fields = redis.call("SMEMBERS", KEYS[2])
local values = redis.call("HMGET", KEYS[1], unpack(fields))
local result = {}
for i,k in ipairs(fields) do result[i] = {k, values[i]} end
return result
2. HINCR IF-EXISTS
Описание
Если необходимо увеличить существующее значение в Hash карте с дополнительной проверкой на существование ключа.
Пример
> evalsha 3cb0d65c399fda8a1d4eb93b2fe85311671bc969 1 top_scorer budi 1
(nil)
> hset top_scorer budi 80
(integer) 1
> evalsha 3cb0d65c399fda8a1d4eb93b2fe85311671bc969 1 top_scorer budi 1
(integer) 91
> evalsha 3cb0d65c399fda8a1d4eb93b2fe85311671bc969 1 top_scorer budi 1
(integer) 92
Источник Lua:
if redis.call("HEXISTS", KEYS[1], ARGV[1]) == 1 then
return redis.call("HINCRBY", KEYS[1], ARGV[1], ARGV[2])
else
return nil
end
3. HMSET-Extended
Описание
В хэш-сетах обычно требуется задавать значение по одному. Вы можете использовать Lua для установки нескольких ключей из args.
Пример
> evalsha 8c4bbf1b37784149128a5b96e55073538a7401d9 1 mykey foo 1 bar 2
(integer) 1
> hgetall mykey
1) "foo"
2) "1"
3) "bar"
4) "2"
> evalsha 8c4bbf1b37784149128a5b96e55073538a7401d9 1 mykey foo 1 bar 3 baz 4
(integer) 0
> hgetall mykey
1) "foo"
2) "1"
3) "bar"
4) "2"
Источник Lua:
if redis.call('exists', KEYS[1]) == 0 then
redis.call('hmset', KEYS[1], unpack(ARGV))
return 1
end
return 0
4. Простое ограничение скорости
Описание
Если вы используете Redis для ограничения скорости, Lua может помочь вам составить логику ограничения скорости.
Пример
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:127.0.0.1 5 10000
(integer) 1
Источник Lua:
local cnt = redis.call('INCR', KEYS[1])
if cnt > tonumber(ARGV[1])
then
return 1
end
if cnt == 1
then
redis.call('PEXPIRE', KEYS[1], ARGV[2])
end
return 0
5. Значение в нескольких наборах
Описание
Если у вас есть сценарий использования, где вам нужно проверить значение в нескольких наборах. Этот скрипт Lua определенно поможет в реализации и позволит избежать сетевых вызовов.
Пример
> sadd users alice bob
(integer) 2
> sadd admin jenny
(integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 2 users admin alice
(integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 3 users admin guests jenny
(integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 2 users admin abner
(integer) 0
Источник Lua:
-- Is an item in any of several sets? Call with:
-- EVALSHA n set1 set2 ... setn key
for i=1,#KEYS do
if redis.call('sismember', KEYS[i], ARGV[1]) == 1 then
return 1
end
end
return 0
Источник: https://www.redisgreen.com/library/