2015-08-05 3 views
2

Я пишу некоторую логику для Redis внутри Lua и почти каждый из моих сценариев есть что-то общее, было бы очень удобно, чтобы выйти из этого к общей функции, ноRedis, как уменьшить Lua копипаст

  1. Redis не может использовать Lua требуют ничего о
  2. официально вы не можете вызвать другую функцию Redis (см https://stackoverflow.com/a/22599862/1812225)

Например, у меня есть этот фрагмент буквально везде

local prefix = "/" .. type 
if typeId then 
    prefix = prefix .. "(" .. typeId .. ")" 
end 

Я думал о какой-то пост-обработки перед подачей сценариев для Redis, но это кажется более-убить ...

Что является лучшей практики для решения/уменьшить эту проблему?

Обновлено:

local registryKey = "/counters/set-" .. type 
local updatedKey = "/counters/updated/set-" .. type 
if typeId then 
    redis.call("SAdd", updatedKey, name .. ":" .. typeId) 
    redis.call("SAdd", registryKey, name .. ":" .. typeId) 
else 
    redis.call("SAdd", updatedKey, name) 
    redis.call("SAdd", registryKey, name) 
end 

еще один пример кода, и он не может быть тривиальным переехал на стороне клиента, как он вызывает Redis команды, и работает как часть сделки

Спасибо!

+1

Предположим на мгновение, что этот общий общий фрагмент можно использовать совместно - вы действительно хотите его использовать? Иными словами, здесь есть мирская задача, которую нужно делать много раз ...Нажатие его в сценарий Lua означает, что вы будете использовать ресурсы из своей базы данных Redis, чтобы выполнить что-то, что можно было бы сделать в другом месте. Я не говорю, что это неправильно, но, как правило, я стараюсь придерживаться такой логики вне базы данных, когда это возможно. –

+0

Что касается этого одного фрагмента, вы, вероятно, правы @ itamar-haber. Но у меня есть другой случай, когда мне нужно делать что-то с условной логикой, которая снова и снова запускает команды redis ... Его нельзя легко переместить на сторону клиента. – let4be

+0

С другой стороны, я, вероятно, должен просто создать другой скрипт с повторяющимися шагами и использовать их как внутри «MULTI», т. е. «MULTI EVALSHA EVALSHA ...» Это просто кажется не идеальным с точки зрения пропускной способности, но не должно быть большой проблемой. – let4be

ответ

3

"Hack" # 1

После того как вы SCRIPT LOAD что-то, вы получаете назад SHA1 хэш, который можно использовать с EVALSHA. Такое же значение sha1 можно использовать для вызова этого сценария от внутри другого сценария - просто вызовите функцию f_<sha1>. Тем не менее, есть некоторые отличия в том, как вы передаете структуры KEYS/ARGV при их использовании.

Обратите внимание, что это недокументированное поведение, а это означает, что поведение может измениться в будущей версии Redis.

Кредит за то, что он учит меня, относится к доктору Джосиа Карлсону, который, в свою очередь, кредитует кого-то другого (IIRC Fritzy). Для получения дополнительной информации, проверить его Lua-вызов Python обертку: https://github.com/josiahcarlson/lua-call

«Hack» # 2

Redis песочницы Lua и ставит несколько ограничений на него, чтобы сохранить здравомыслие. Вы можете обойти некоторые из них, например. войдите в _G и определите свою функцию утилиты там, чтобы она была доступна для всех скриптов (например, я сделал с https://github.com/redislabs/redis-lua-debugger).

Однако это также довольно рискованно - помимо возможных проблем с репликацией это использование не проверено и, следовательно, может привести к неопределенному поведению (мне удалось свернуть несколько экземпляров с моим маленьким скриптом;)).

P.S.

Оба хака требуют дополнительной административной работы, чтобы гарантировать, что эти «глобальные» сценарии фактически загружены до того, как их вызовет любой другой сценарий.

+0

Спасибо за подробный ответ. Интересно, будет ли в конечном итоге стандартизованный способ использования кода утилиты для экземпляров Redis. Я предвижу, что я использую некоторый код снова и снова во многих сценариях (обертки redis.log, библиотеки, такие как underscore.lua и т. П.). – Ignacio

+0

Предложения/идеи/PR-ресурсы всегда приветствуются в сообществе Redis - почему бы не представить свое дело и не начать обсуждение? –

+0

Действительно ли Hack # 1 использует недокументированное поведение? Sha1 - это * * способ, которым клиент получит дескриптор загруженного сценария. (Является ли это вызовом f_ , это проблема?) –

Смежные вопросы