Lua Introduction

레디스 개발자 교육 신청 레디스 정기점검/기술지원
Redis Technical Support
레디스 엔터프라이즈 서버
Redis Enterprise Server

소개

Redis 버전 2.6.0부터 Lua interpreter를 내장해서 Lua script를 실행할 수 있습니다.   Lua 5.1을 사용합니다.   이 문서는 Redis 버전 5.0.7을 기준으로 작성했습니다.

명령 설명

EVAL

  • Lua script를 실행합니다. 인수(argument)없이 사용할 경우
    > EVAL "return redis.call('set', 'key', 'value')" 0
    OK
    > EVAL "return redis.call('get', 'key')" 0
    value
    여기서 마지막 0은 인수로 입력할 키 개수입니다. 없으면 0입니다.

SCRIPT LOAD, EVALSHA

  • 스크립트를 반복해서 사용할 경우 스크립트를 LOAD하면 SHA 값이 리턴됩니다. 이 값으로 스크립트를 반복해서 실행할 수 있습니다. 스크립트는 레디스에 캐시됩니다.
    EVALSHA를 사용할 경우 인수를 사용하면 효과적으로 반복 사용할 수 있습니다.
    > SCRIPT LOAD "return redis.call('set', KEYS[1], ARGV[1])"
    "55b22c0d0cedf3866879ce7c854970626dcef0c3"
    > EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 key10 value10
    OK
    > EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 key11 value11
    OK
    키가 여러개 있을 경우
    > SCRIPT LOAD "return redis.call('mset', KEYS[1], ARGV[1], KEYS[2], ARGV[2])"
    "e290a9e5f8bdb9b954e332de5e6b661e4ea31c08"
    > EVALSHA e290a9e5f8bdb9b954e332de5e6b661e4ea31c08 2 key10 key11 value10 value11
    OK
  • 스크립트 사이즈가 클경우 LOAD해서 사용하면 매번 EVAL로 실행하는 것보다 network 통신량을 줄이는데 도움이 됩니다.

SCRIPT INFO

  • Lua interpreter가 사용하는 메모리, 캐시된 스크립트가 사용하는 메모리, 스크립트 개수를 조회합니다. 여기에 표시되는 정보는 info memory에서 표시되는 Lua 정보와 같습니다.

SCRIPT LIST

  • 캐시된 스크립트 리스트를 조회합니다. Sha와 Script 70바이트까지 표시됩니다. FULL 옵션을 사용하면 32767바이트까지 조회할 수 있습니다.

SCRIPT GET

  • Sha로 Script를 조회합니다. 이때는 스크립트 크기에 제한없이 전체를 조회합니다.

SCRIPT EXISTS

  • SHA로 스크립트가 캐시(load)되어 있는지 확인합니다.
    > SCRIPT EXISTS e290a9e5f8bdb9b954e332de5e6b661e4ea31c08
    1) (integer) 1

SCRIPT FLUSH

  • 메모리에 캐시된 Lua 스크립트를 모두 지웁(flush)니다.

SCRIPT KILL

  • 실행중인 Lua 스크립트를 죽입니다.
    조건은 lua-time-limit가 지났고, Script내에서 쓰기(write) 명령을 실행하지 않았을 때입니다.
    자세한 내용은 SCRIPT KILL 명령을 참조하세요.

INFO MEMORY

  • Lua 스크립트 관련 정보를 볼 수 있습니다.
    > info memory
    ... 중간 생략 ...
    used_memory_lua:90112   -> 루아 엔진에서 사용하는 메모리
    used_memory_lua_human:88.00K
    used_memory_scripts:3976   -> 스크립트가 사용하는 메모리 (5.0 추가)
    used_memory_scripts_human:3.88K
    number_of_cached_scripts:27   -> 스크립트 개수 (5.0 추가)

AOF, 복제(Replication)

  • 레디스 5.0부터는 MULTI/EXEC 명령으로 기록되고 복제노드에 전파됩니다.
    > EVAL "return redis.call('set','key','value')" 0
    OK
    AOF
  • 레디스 4.x까지는 스크립트가 기록되고 전파됩니다.
  • 하지만 이 버전에서도 redis.replicate_commands()를 실행하면 명령이 기록됩니다.
    > EVAL "redis.replicate_commands() return redis.call('set','key','value')" 0
  • AOF REWRITE: 기록되지 않습니다.
  • RDB: 기록됩니다. 복제 노드에 전파됩니다.

SELECT

  • DB를 선택하는 select 명령은 사용가능합니다. 단, 스크립트 내에서만 적용됩니다.
    > EVAL "redis.call('select',2) return redis.call('set','key','value')" 0

SCRIPT 내에서 사용할 수 없는 명령

  • 대부분의 명령은 사용하는 하나, 다음 몇 가지 명령은 사용할 수 없습니다.
  • BLPOP, BRPOP, BZPOPMIN, BZPOPMAX같은 Blocking 명령은 사용할 수 없습니다.
  • PUBLISH 명령은 사용가능하나, SUBSCRIBE 명령은 사용할 수 없습니다.
  • EVAL, SCRIPT, MULTI, EXEC 명령은 사용할 수 없습니다.
  • 관리(admin) 명령 사용 불가: SAVE, BGSAVE, BEREWRITEAOF, LATENCY, SLOWLOG, REPLICAOF, DEBUG, ROLE, AUTH, SHUTDOWN, ...

Lua 관련 파라미터

  • lua_time_limit 5000(5초): 이 시간이 지나면 실행중인 스크립트를 kill 시킬 수 있습니다.

Lua Script 활용

  • keys myset* : 키 리스트 조회
    > EVAL "return redis.call('keys','myset*')" 0
    1) "myset1"
    2) "myset2"
  • 개수 보기: 앞에 #을 붙이면 개수를 조회합니다.
    > EVAL "return #redis.call('keys','myset*')" 0
    (integer) 2
  • 조회한 키들이 SET일 경우 키들의 맴버를 조회한다.
    > EVAL "local members = redis.call('keys','myset*') local results = {} for index,key in ipairs(members) do results[index] = redis.call('smembers',key) end return results" 0
    1) 1) "BBB"
        2) "AAA"
    2) 1) "DDD"
        2) "EEE"
        3) "CCC"
  • 이 경우 조회한 키가 SET이 아니면 "(empty list or set)"를 리턴한다. 이 경우 SET data type만 조회하기 위해서 Enterprise 버전에서는 'set' 옵션을 추가할 수 있다.
    > EVAL "local members = redis.call('keys','myset*','set') local results = {} for index,key in ipairs(members) do results[index] = redis.call('smembers',key) end return results" 0
  • STRING 키들의 값 합계를 구한다.
    > set key10 10
    > set key20 20
    > set key30 30
    > EVAL "local members = redis.call('keys','key*','string') local total = 0 for index,key in ipairs(members) do total = total + redis.call('get',key) end return total" 0
    (integer) 60
  • Hash 샘플 데이터 입력
    script load "local num = 0 while num < tonumber(ARGV[1]) do num = num + 1 redis.call('hset','myhash','field-'..num, 'value-'..num) end return num"

Lua 명령어 리스트

CommandsVersionSyntaxDescription
EVAL2.6.0Script스크립트 실행
EVALSHA2.6.0SHA저장된 스크립트 실행
SCRIPT LOAD2.6.0Script스크립트 로드
SCRIPT INFOEnt 6.0.0스크립트 정보 조회
SCRIPT LISTEnt 6.0.0Full스크립트 리스트 조회
SCRIPT GETEnt 6.0.0SHA스크립트 조회
SCRIPT EXISTS2.6.0SHA확인
SCRIPT FLUSH2.6.0 메모리에서 스크립트 지우기
SCRIPT KILL2.6.0 실행중인 스크립트 죽이기
SCRIPT DEBUG3.2.0 디버그

Total : 10


<< Pub/Sub Intro Lua Script Intro EVAL >>

Email 답글이 올라오면 이메일로 알려드리겠습니다.