Redis 의 Lua Script 활용

2021. 4. 11. 03:24 NoSQL/redis

개요

 

RDB의 stored procedure와 비슷한 용도로 사용이 가능 합니다. 자주 사용되는 여러 명령어로 묶인 코드를 script로 호출하여, Redis Server Side

에서 한번에 처리 되도록 처리할 수 있습니다. 이를 적절히 잘 활용하면 성능을 향상 시킬수 있으며, 코드도 간단해 집니다.

 

Redis는 single threaded 이므로 Lua Script 실행중에 인터럽트 되지 않습니다. (Atomic)

 

Redis에서 RDB의 transaction과 비슷한 기능을 사용 할 수 있는 기능을 제공 합니다.

MULTI : 트랜잭션시작, EXEC : 커밋, DISCARD : 롤백, WATCH : 변경감시, UNWATCH : 변경감시해제 을 이용한 방법과 lua script를 이용하는 방법이

존재 합니다.

주의) RDBMS와는 큰 차이점이 있는데 multi를 시행중 watch에 의해 변경된 내용을 인지 해도, 이미 실행된 명령어를 자동으로 롤백해 주지 않습니다.

MULTI 이후 명령어들은 EXEC가 호출되기 전까지 단지 명령어 Queue에 쌓고 있을 뿐이고, EXEC가 호출되면 Queue에 쌓인 명령어를 순차적으로

실행 합니다. single thread 이므로 Queue에 쌓인 명령어를 실행하는 중에는 다른 명령을 처리 하지 않습니다. Queue에 쌓는 중에 다른 커넥션에서

WATCH하는 값을 변경 한다면 EXEC에서 실패 된다는 의미 입니다.

Lua Script도 Multi와 같이 한번에 실행되며 실행되는 중간에 다른 명령을 처리 하지 않습니다. 이 때문에 실행 시간이 긴 script를 자주 실행하는 것은

성능에 좋지 않은 영향을 끼칩니다.

 

명령어

 

EVAL : Lua Script를 사용하기 위한 명령어 입니다.

사용법 : EVAL "루아 스크립" 키숫자 key [keys ... ] argv [argvs ... ]

 

EVAL "return {KEYS[1],KEYS[2], KEYS[3], ARGV[1],ARGV[2]}" 3 key1 key2 key3 인자1 인자2

결과 :

 1)  "key1"
 2)  "key2"
 3)  "key3"
 4)  "인자1"
 5)  "인자2"

3 이라는 숫자는 key들의 총 갯수 입니다.

key1 , key2, key3 총 3개의 key와 인자 2개로 구성되어 있습니다. 인자의 갯수는 지정되지 않습니다.

 

SCRIPT LOAD :Lua Script를 script load를 통해 실행하면 Redis memory인 script cache에 저장 됩니다.

실행 결과로 SHA값이 리턴 됩니다. 이 값은 실행된 Lua Script의 식별자로 활용 됩니다. (EVALSHA 명령어로 실행 됩니다.)

리턴된 SHA 값을 기록해서 재활용 하면 됩니다.

 

EVALSHA :Redis script cache에 저장된 Lua Script를 Sha값을 이용해 실행 합니다.

 

script load "return {KEYS[1],KEYS[2], KEYS[3], ARGV[1],ARGV[2]}"

결과 :

"2fc0cb20fa871618b8d9f9cde8bcdab3e33e8933"

 

 evalsha 2fc0cb20fa871618b8d9f9cde8bcdab3e33e8933 3 key1 key2 key3 인자1 인자2

결과 :

 1)  "key1"
 2)  "key2"
 3)  "key3"
 4)  "인자1"
 5)  "인자2"

lua script가 길이가 길다면 매 실행시 마다 script의 모든 코드를 전달하여 실행 하는 것보다 미리 cache된 script를 sha값을 이용해

실행하는것이 성능상 이점을 얻을 수 있습니다.

 

SCRIPT EXISTS : Sha의 script가 존재하는 지 조회 합니다.

예) script exists sha1 sha2 ... [sha...] , 존재할 경우 1, 존재 하지 않을 경우 0을 리턴 합니다.

 

SCRIPT FLUSH : Redis의 script cache에 저장된 모든 script를 삭제 합니다.

예) script flush

 

SCRIPT KILL : 현재 실행중인 script를 종료 합니다. Redis는 기본적으로 single thread로 동작됩니다. 한 명령어가 장시간 실행되면 그 뒤에 호출된

명령어 들은 대기하게 됩니다. 이때 실행중인 script를 종료 하는데 사용 됩니다. 실제 서비스에서 이런 경우가 생기면 서비스 장애로

이어질 가능성이 크므로 해당 script를 개선해야 합니다.

 

출처 : code-factory.tistory.com/13?category=724511

'NoSQL > redis' 카테고리의 다른 글

[Redis, 레디스] 레디스 소개 및 아키텍처, 주의할 점(Redis Overview, Redis Architecture, Tool Tip)  (0) 2023.04.25
Redis - 조회 명령어 정리  (0) 2022.05.09
Redis Lua Script를 활용 예  (0) 2021.04.11
Redis cluster  (0) 2021.04.11
redis Strings  (0) 2021.04.11
redis Lists  (0) 2021.04.11
redis Sorted Sets  (0) 2021.04.11
redis Sets  (0) 2021.04.11