Redis Lua 스크립팅

RedisBeginner
지금 연습하기

소개

이 랩에서는 Redis Lua 스크립팅을 탐구하며, 복잡한 작업을 효율적으로 수행하기 위해 Lua 스크립트를 Redis 내에서 직접 실행하는 데 중점을 둡니다. 이 랩에서는 EVAL 명령을 사용하여 스크립트를 실행하고, 스크립트에 인수를 전달하며, SCRIPT LOAD를 사용하여 스크립트를 로드하고, EVALSHA를 사용하여 로드된 스크립트를 실행하는 방법을 다룹니다.

먼저 EVAL을 사용하여 Redis 카운터를 증가시키는 간단한 Lua 스크립트를 실행하여 스크립트, 액세스하는 키의 수, 키 이름을 지정하는 방법을 보여줍니다. 그런 다음, 스크립트를 Redis 에 로드하고 SHA1 해시를 사용하여 실행하는 방법을 배우고, 반복적인 스크립트 전송을 방지하여 성능을 향상시킵니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 90%입니다.학습자들로부터 84%의 긍정적인 리뷰율을 받았습니다.

EVAL 로 Lua 스크립트 실행

이 단계에서는 EVAL 명령을 사용하여 Redis 내에서 직접 Lua 스크립트를 실행하는 방법을 살펴봅니다. 이를 통해 단일 요청으로 데이터에 대한 복잡한 작업을 수행하여 네트워크 대기 시간을 줄이고 성능을 향상시킬 수 있습니다.

시작하기 전에 EVAL의 기본 사항을 이해해 보겠습니다. EVAL 명령은 두 가지 주요 인수를 사용합니다.

  1. 문자열 형태의 Lua 스크립트 자체.
  2. 스크립트가 액세스할 키의 수, 그 다음 실제 키 이름 및 스크립트에 전달하려는 추가 인수.

시작하기 위한 간단한 예제가 있습니다. Redis 카운터를 증가시키고 새 값을 반환하는 Lua 스크립트를 만들겠습니다.

  1. 터미널을 열고 Redis 명령줄 인터페이스 (redis-cli) 를 사용하여 Redis 서버에 연결합니다.

    redis-cli
  2. 이제 EVAL을 사용하여 Lua 스크립트를 실행해 보겠습니다. 이 스크립트는 mycounter라는 카운터를 증가시키고 증가된 값을 반환합니다.

    EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounter

    이 명령을 분석해 보겠습니다.

    • EVAL "local current = redis.call('INCR', KEYS[1]); return current": 이것이 Lua 스크립트 자체입니다. redis.call('INCR', KEYS[1])을 사용하여 KEYS[1]에 지정된 키의 값을 증가시킵니다. KEYS 배열에는 스크립트에 전달된 키 이름이 포함되어 있습니다. 마지막으로 증가된 값을 반환합니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • mycounter: 스크립트가 액세스할 키의 이름입니다.

    다음과 유사한 출력이 표시됩니다.

    (integer) 1

    동일한 명령을 다시 실행하면 카운터가 증가하는 것을 볼 수 있습니다.

    EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounter

    출력:

    (integer) 2
  3. GET 명령을 사용하여 mycounter 키의 값을 확인해 보겠습니다.

    GET mycounter

    출력:

    "2"

    보시다시피 Lua 스크립트는 카운터를 성공적으로 증가시켰습니다.

  4. 이제 다른 예를 시도해 보겠습니다. 이번에는 키가 아직 존재하지 않는 경우 특정 값으로 키를 설정하는 스크립트를 만들겠습니다.

    EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalue

    이 명령에서:

    • EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end": 이것이 Lua 스크립트입니다. 키 KEYS[1]이 존재하는지 확인합니다. 존재하지 않으면 키를 값 ARGV[1]로 설정하고 1을 반환합니다. 그렇지 않으면 0을 반환합니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • mykey: 키의 이름입니다.
    • myvalue: 키가 존재하지 않는 경우 설정할 값입니다.

    다음과 유사한 출력이 표시됩니다.

    (integer) 1

    이는 mykey 키가 myvalue로 설정되었음을 나타냅니다.

  5. mykey의 값을 확인해 보겠습니다.

    GET mykey

    출력:

    "myvalue"

    EVAL 명령을 다시 실행하면:

    EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalue

    출력:

    (integer) 0

    이번에는 키가 이미 존재했기 때문에 스크립트가 0을 반환했습니다.

  6. redis-cli를 종료합니다. 변경 사항이 기록되려면 이것이 중요합니다.

    exit

EVAL 로 스크립트에 인수 전달

이전 단계에서는 EVAL을 사용하여 Lua 스크립트를 실행하고 키에 액세스하는 방법을 배웠습니다. 이제 이러한 스크립트에 인수를 전달하는 방법을 살펴보겠습니다. 이를 통해 보다 동적이고 재사용 가능한 스크립트를 사용할 수 있습니다.

EVAL 명령은 다음 인수를 사용한다는 것을 기억하십시오.

  1. 문자열 형태의 Lua 스크립트 자체.
  2. 스크립트가 액세스할 키의 수.
  3. 키 이름.
  4. 스크립트에 전달하려는 추가 인수. 이러한 인수는 ARGV 배열을 사용하여 Lua 스크립트 내에서 액세스됩니다.

예시부터 시작해 보겠습니다. Redis 카운터에 값을 추가하는 Lua 스크립트를 만들겠습니다. 카운터의 키와 추가할 값은 인수로 전달됩니다.

  1. Redis 명령줄 인터페이스 (redis-cli) 를 사용하여 Redis 서버에 연결합니다.

    redis-cli
  2. 이제 EVAL을 사용하여 지정된 양만큼 카운터를 증가시키는 Lua 스크립트를 실행해 보겠습니다.

    EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current" 1 mycounter 5

    이 명령을 분석해 보겠습니다.

    • EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": 이것이 Lua 스크립트입니다. redis.call('INCRBY', KEYS[1], ARGV[1])을 사용하여 KEYS[1]에 지정된 키의 값을 ARGV[1]에 지정된 양만큼 증가시킵니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • mycounter: 스크립트가 액세스할 키의 이름입니다.
    • 5: 스크립트에 전달되어 ARGV[1]로 액세스될 인수입니다.

    다음과 유사한 출력이 표시됩니다 (이전 단계에서 mycounter가 2 였다고 가정).

    (integer) 7

    스크립트는 mycounter 키를 5 만큼 증가시켰습니다.

  3. GET 명령을 사용하여 mycounter 키의 값을 확인해 보겠습니다.

    GET mycounter

    출력:

    "7"
  4. 이제 문자열 인수를 사용하여 다른 예를 시도해 보겠습니다. 키와 값 모두 인수로 전달되는 키를 값으로 설정하는 스크립트를 만들겠습니다.

    EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]" 1 mynewkey mynewvalue

    이 명령에서:

    • EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": 이것이 Lua 스크립트입니다. 키 KEYS[1]을 값 ARGV[1]로 설정하고 값을 반환합니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • mynewkey: 키의 이름입니다.
    • mynewvalue: 설정할 값입니다.

    다음과 유사한 출력이 표시됩니다.

    "mynewvalue"
  5. mynewkey의 값을 확인해 보겠습니다.

    GET mynewkey

    출력:

    "mynewvalue"

    스크립트는 mynewkey 키를 값 mynewvalue로 성공적으로 설정했습니다.

  6. 스크립트에 여러 인수를 전달할 수 있습니다. 예를 들어, 인수로 전달된 두 개의 문자열을 연결하고 결과를 키로 설정하는 스크립트를 만들어 보겠습니다.

    EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result" 1 combinedkey hello world

    이 명령에서:

    • EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": 이것이 Lua 스크립트입니다. .. 연산자를 사용하여 ARGV[1]ARGV[2]를 연결하고, 키 KEYS[1]을 결과로 설정하고, 결과를 반환합니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • combinedkey: 키의 이름입니다.
    • hello: 첫 번째 문자열 인수입니다.
    • world: 두 번째 문자열 인수입니다.

    다음과 유사한 출력이 표시됩니다.

    "helloworld"
  7. combinedkey의 값을 확인해 보겠습니다.

    GET combinedkey

    출력:

    "helloworld"
  8. redis-cli를 종료합니다. 변경 사항이 기록되려면 이것이 중요합니다.

    exit

SCRIPT LOAD 로 스크립트 로드

이전 단계에서는 EVAL 명령을 사용하여 Lua 스크립트를 직접 실행했습니다. 이는 간단한 스크립트에는 유용하지만, 더 크고 복잡한 스크립트의 경우 번거로워질 수 있습니다. Redis 는 SCRIPT LOAD 명령을 제공하여 스크립트를 Redis 서버의 스크립트 캐시에 로드합니다. 이를 통해 매번 전체 스크립트를 보낼 필요 없이 스크립트를 여러 번 실행할 수 있어 성능이 향상됩니다.

SCRIPT LOAD 명령은 Lua 스크립트 자체라는 단일 인수를 사용합니다. 스크립트의 SHA1 해시를 반환하며, 이 해시를 사용하여 EVALSHA 명령 (다음 단계에서 다룰 예정) 을 통해 스크립트를 실행할 수 있습니다.

작동 방식을 살펴보겠습니다.

  1. Redis 명령줄 인터페이스 (redis-cli) 를 사용하여 Redis 서버에 연결합니다.

    redis-cli
  2. 이제 SCRIPT LOAD를 사용하여 Lua 스크립트를 로드해 보겠습니다. 지정된 양만큼 카운터를 증가시키는 이전 단계의 동일한 스크립트를 사용합니다.

    SCRIPT LOAD "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current"

    이 명령은 스크립트를 Redis 서버의 스크립트 캐시에 로드하고 스크립트의 SHA1 해시를 반환합니다. 다음과 유사한 출력이 표시됩니다.

    "6b1e8dd2999cb08546e74339c0c9489f9f89a84b"

    이것이 스크립트의 SHA1 해시입니다. 다음 단계에서 필요하므로 이 해시를 기록해 두십시오. 정확한 해시 값은 다를 수 있습니다.

  3. 이제 키와 값 모두 인수로 전달되는 키를 값으로 설정하는 스크립트를 로드해 보겠습니다.

    SCRIPT LOAD "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]"

    다음과 유사한 출력이 표시됩니다.

    "a8b2b3648969459a8198262a9166e945e890987c"

    다시, 이 해시를 기록해 두십시오.

  4. 인수로 전달된 두 개의 문자열을 연결하고 결과를 키로 설정하는 스크립트를 로드해 보겠습니다.

    SCRIPT LOAD "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result"

    다음과 유사한 출력이 표시됩니다.

    "d2a800a974ca96849295220424f9a0664a495345"

    이 해시도 기록해 두십시오.

  5. SCRIPT EXISTS 명령을 사용하여 스크립트가 로드되었는지 확인할 수 있습니다. 이 명령은 하나 이상의 SHA1 해시를 인수로 사용하고 0 과 1 의 배열을 반환합니다. 여기서 1 은 해당 해시가 있는 스크립트가 로드되었음을 나타내고 0 은 로드되지 않았음을 나타냅니다.

    예를 들어, 로드한 첫 번째 스크립트가 여전히 로드되었는지 확인하려면 2 단계에서 얻은 해시로 해시를 대체하여 다음 명령을 사용하십시오.

    SCRIPT EXISTS 6b1e8dd2999cb08546e74339c0c9489f9f89a84b

    출력:

    1) (integer) 1

    이는 스크립트가 로드되었음을 나타냅니다.

    로드되지 않은 스크립트를 확인하려고 하면:

    SCRIPT EXISTS 0000000000000000000000000000000000000000

    출력:

    1) (integer) 0

    이는 스크립트가 로드되지 않았음을 나타냅니다.

  6. redis-cli를 종료합니다. 변경 사항이 기록되려면 이것이 중요합니다.

    exit

EVALSHA 로 로드된 스크립트 실행

이전 단계에서는 SCRIPT LOAD 명령을 사용하여 Lua 스크립트를 Redis 서버의 스크립트 캐시에 로드하는 방법을 배웠습니다. 이제 EVALSHA 명령을 사용하여 로드된 해당 스크립트를 실행하는 방법을 배우겠습니다.

EVALSHA 명령은 다음 인수를 사용합니다.

  1. 로드된 스크립트의 SHA1 해시.
  2. 스크립트가 액세스할 키의 수.
  3. 키 이름.
  4. 스크립트에 전달하려는 추가 인수.

EVALSHA를 사용하면 동일한 스크립트를 여러 번 실행해야 할 때 EVAL보다 효율적입니다. 매번 전체 스크립트를 서버로 보낼 필요가 없기 때문입니다.

작동 방식을 살펴보겠습니다.

  1. Redis 명령줄 인터페이스 (redis-cli) 를 사용하여 Redis 서버에 연결합니다.

    redis-cli
  2. 이제 EVALSHA를 사용하여 지정된 양만큼 카운터를 증가시키는 Lua 스크립트를 실행해 보겠습니다. 스크립트 local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current에 대해 이전 단계에서 얻은 SHA1 해시를 기억하십니까? 그렇지 않은 경우 SCRIPT LOAD를 사용하여 스크립트를 다시 로드해야 합니다. 이 예에서는 해시가 6b1e8dd2999cb08546e74339c0c9489f9f89a84b라고 가정합니다.

    EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5

    이 명령을 분석해 보겠습니다.

    • EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: SHA1 해시 6b1e8dd2999cb08546e74339c0c9489f9f89a84b를 사용하여 스크립트를 실행하려는 것을 지정합니다.
    • 1: 스크립트가 하나의 키에 액세스함을 나타냅니다.
    • mycounter: 스크립트가 액세스할 키의 이름입니다.
    • 5: 스크립트에 전달되어 ARGV[1]로 액세스될 인수입니다.

    다음과 유사한 출력이 표시됩니다 (이전 단계에서 mycounter가 7 이었다고 가정).

    (integer) 12

    스크립트는 mycounter 키를 5 만큼 증가시켰습니다.

  3. GET 명령을 사용하여 mycounter 키의 값을 확인해 보겠습니다.

    GET mycounter

    출력:

    "12"
  4. 이제 EVALSHA를 사용하여 키를 값으로 설정하는 스크립트를 실행해 보겠습니다. 스크립트 redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]에 대해 이전 단계에서 얻은 SHA1 해시를 기억하십니까? 그렇지 않은 경우 SCRIPT LOAD를 사용하여 스크립트를 다시 로드해야 합니다. 이 예에서는 해시가 a8b2b3648969459a8198262a9166e945e890987c라고 가정합니다.

    EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalue

    다음과 유사한 출력이 표시됩니다.

    "anothervalue"
  5. anotherkey의 값을 확인해 보겠습니다.

    GET anotherkey

    출력:

    "anothervalue"
  6. 잘못된 SHA1 해시로 스크립트를 실행하려고 하면 오류가 발생합니다.

    EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalue

    출력:

    (error) NOSCRIPT No matching script. Please use EVAL.

    이는 지정된 SHA1 해시가 있는 스크립트가 로드되지 않았음을 나타냅니다.

  7. redis-cli를 종료합니다. 변경 사항이 기록되려면 이것이 중요합니다.

    exit

요약

이 랩에서는 Redis Lua 스크립팅을 탐구했으며, EVAL 명령을 사용하여 스크립트를 직접 실행하는 데 중점을 두었습니다. EVAL은 Lua 스크립트를 문자열로, 액세스된 키의 수, 그리고 키 이름 자체를 인수로 사용한다는 것을 배웠습니다. EVAL 내에서 Lua 스크립트를 사용하여 Redis 카운터를 증가시키는 연습을 했으며, 스크립트가 지정된 키에 액세스하고 수정하는 방식을 관찰했습니다.

또한, Lua 스크립트에 인수를 전달하고, SCRIPT LOAD를 사용하여 스크립트를 Redis 에 로드하고, EVALSHA를 사용하여 로드된 스크립트를 실행하는 방법을 배웠습니다. 각 단계 후에 redis-cli를 종료하여 명령이 올바르게 기록되도록 하는 것을 잊지 마십시오. 이를 통해 복잡한 스크립트를 보다 효율적으로 실행할 수 있습니다.