Scripting

뾰족머리삼돌이·2024년 10월 17일
0

Spring Data Redis

목록 보기
8/12

EVAL, EVALSHA

2.6 버전이상의 Redis에서는 EVAL,EVALSHA 명령어를 통한 Lua 스트립트를 지원한다.

Lua는 명령형/절차형 프로그래밍 언어다

> EVAL script numkeys [key [key ...]] [arg [arg ...]]
> EVALSHA sha1 numkeys [key [key ...]] [arg [arg ...]]

EVAL 명령의 script는 실행시킬 Lua 스크립트를 뜻하며, EVALSHA명령의 sha1은 스크립트의 SHA1 해시값을 뜻한다.

numkeys는 이어지는 key의 수를 뜻하며, numkeys가 0이라면 뒤에 주어지는 값들은 전부 arg라는 뜻이된다.

Lua

Lua는 명령형/절차형 프로그래밍 언어로, 공식 홈페이지에서 관련 정보를 얻을 수 있다.
문법이 단순하고 가볍다는 특징이 있으며, 함수형 프로그래밍도 어느정도 가능하다.

Spring 에서의 Scripting

Spring Data Redis에서는 직렬화와 자동으로 스크립트 캐시를 실행하는 고수준의 추상화를 제공한다.

RedisTemplateexecute 메서드에서 ScriptExecutor 를 사용해 스크립트를 실행시키며, 기본적으로 템플릿의 직렬화기를 통해 주어진 키와 인수들을 직렬화하고, 스크립트 결과를 역직렬화한다.

스크립트 실행 동작은 1차적으로 EVALSHA 명령을 실행하여 캐시된 스크립트인지 확인하고, 그렇지않다면 EVAL을 실행하는 식으로 동작한다.

Redis 스크립트 캐시는 이전에 실행한 전적이 있는 스크립트를 저장하는 저장소다.

EVALSHA명령은 캐시된 스크립트 명령을 실행하는 명령어다.
스크립트의 SHA1 해시 값을 사용하여 스크립트를 실행한다.

@Bean
public RedisScript<Boolean> script() {

  ScriptSource scriptSource = new ResourceScriptSource(new ClassPathResource("META-INF/scripts/checkandset.lua"));
  return RedisScript.of(scriptSource, Boolean.class);
}

위 예시에서 실행시킬 스크립트는 META-INF/scripts/checkandset.lua에 작성되어 있다.
이를 바탕으로 RedisScript 객체를 생성시키는 메서드다.

public class Example {

  @Autowired
  RedisOperations<String, String> redisOperations;

  @Autowired
  RedisScript<Boolean> script;

  public boolean checkAndSet(String expectedValue, String newValue) {
    return redisOperations.execute(script, singletonList("key"), asList(expectedValue, newValue));
  }
}

이후에 redisOperations.execute을 통해 스크립트를 실행시키는데, 그 과정에서 key와 value를 전달한다.
여기서 expectedValue는 첫번째 arg 값이되며, newValue는 두번째 arg 값이 된다.

-- checkandset.lua
local current = redis.call('GET', KEYS[1])
if current == ARGV[1]
  then redis.call('SET', KEYS[1], ARGV[2])
  return true
end
return false

동작시킬 스크립트를 확인해보면,
key에 저장된 값과 expectedValue이 동일한지 체크하고 newValue로 바꾸는 스크립트다.
즉, KEYS[1]singletonList("key") / ARGV[1]expectedValue / ARGV[2]newValue와 매칭된다.

0개의 댓글

관련 채용 정보