반응형

사내 서비스 중 Redis 에서 Lua 를 많이 사용하여 이번 기회에 Lua 메모리 관련하여 정리해 보았습니다.

 

Lua 스크립트란 ?

  • 스크립트 언어로써, 문자열 함수와 수학 함수를 제공
  • 그래픽 시뮬레이션을 위한 스크립트 언어로 개발된 언어로써 타 스크립트 언어보다 빠른 성능을 제공
  • 변수를 제거하거나 미리 선언을 위한 별도의 처리가 필요 없음

 

Redis 에서 Lua 스크립트

  • 프로그래밍 방식 제어구조를 사용하고 db에 access 하여 실행하는 대부분의 명령을 사용 가능
    • redis.call('set', key, value) 형태
  • 지역 변수를 사용해야 함
    • ex) 변수 선언 시 : local src = keys[1]
  • eval 명령어를 이용하여 수행하고자 하는 스크립트를 redis로 전송하여 사용 가능
  • script load 명령을 이용하여 redis server에 등록 시킨 후 사용 가능
    • 데이터가 존재하는 곳에서 실행되기 때문에 전체 대기 시간 뿐만 아니라 네트워크 리소스 절약 가능
    • Application 로직의 일부를 Redis 내에서 실행이 가능하며 여러키에 걸쳐 조건부 업데이트 수행 가능하며 다른 데이터 유형을 함께 처리도 가능
  • Script는 Lua 엔진(Lua5.1) 에 의해 실행
  • 기본적으로 Eval script는 클라이언트 일부로 간주하기 때문에 서버에 persistence 하게(영구) 저장이 되지 않기에(단순 Caching-휘발성), Redis server가 재시작 되거나 한다면 re-Load 해야 함
    • 7.0에서 부터는 redis function 추가 프로그래밍 로직으로 서버 자체를 확장할 수 있는 프로그래밍 가능성에 의해 persitence 하게 저장이 가능 (모든 client에서 사용이 가능)
    • 7.0 부터는 read-only script 가 가능 (read replica에서 지원)
    • https://redis.io/docs/manual/programmability/
  • 메모리 각 내용
    • used_memory_lua :   Lua 엔진에 의해 사용된 메모리 크기 (byte)
    • used_memory_scripts :  5.0 추가   (mh->lua_caches) 생성된 루아 스크립트가 사용하는 메모리 양
      • 모니터링 진행 할 때 used_memory_scripts  를 확인하면 되며, set 명령어만 이루어진 스크립트는 별도로 used_memory_scripts  영역이 변경되지 않음
    • redis server에서 실행되는 lua script는 원자성(Atomicity)하게 처리된다. (lua가 실행되는 동안 다른 레디스 명령어는 실행 안되는 것을 의미-다른 모든 명령어 차단)
      • 이 부분은 single thread 때문이 아닐까...
    • 스크립트 내용이 동일한 동작!!!을 하더라도, 조금이라도 다르다면 다른 스크립트로 인식 하기 때문에, 의미만 변경되는 스크립트 들에 대해서는 변수 처리로 하여 사용하면 캐싱 절약 효과를 얻을 수 있음
#아래는 동일한 동작을 하지만 내용이 다르기 때문에 서로 다른 내용으로 인식하여 used_memory_lua / used_memory_scripts 값 둘다 변경
eval "return 'hellow world?'" 0
eval "return 'hellow world????'" 0

#아래는 동일한 내용을 호출한 경우 캐싱되어 있기 때문에 memory 변화값이 없음을 확인
eval "return 'hellow world????'" 0
eval "return 'hellow world????'" 0

 

테스트 1.

 

이번에는 재밌는 테스트를 진행 하였다.
동일한 redis 구문이지만, return 을 하고 안하고의 차이 이다.
둘다 명령어는 get 명령어로 값을 리턴을 하지만, 이것을 결국 client까지 return을 하느냐 안 하느냐 차이일 것 같은데, 스크립트는 역시 이것을 다른 script로 인식을 하는 것을 확인

eval "redis.call('get', 'lua_test_2555')" 0
eval "return redis.call('get', 'lua_test_2555')" 0
  • 당연히 get 명령어이고 lua script를 호출이기 때문에 used_memory_scripts / used_memory_lua 모두 값이 변경 된 것을 확인할 수 있다.

  • 이번에는 명령어는 동일하지만 return 을 하는 명령어 실행
    • used_memory_scripts / used_memory_lua 모두 값이 변경 된 것을 확인할 수 있다.

  • 당연하겠지만, 기존에 캐싱되어 있는 영역을 다시 조회 시
    • used_memory_scripts / used_memory_lua 모두 값이 변경 되지 않은 것을 확인

  • 결국은 lua 는 내부 모두 동일해야 동일한 script로 인식하여 캐싱 여부를 사용할지 정하는 척도
    • 데이터 변경이 일어나는 곳이라면 당연히 파라메터로 작성하여 사용 하는 것을 의미하며 이렇게 사용할 것을 권고

테스트 2.

  • 추가로 set 명령어는 lua 엔진을 사용할 뿐, used_memory_scripts 의 값이 변경 되는 내역은 없음
    • 기존 get 명령어나 return 하는 명령어의 경우 used_memory_scripts  값이 변경 되는 것을 확인할 수 있으나, 오로지 set 명령어의 경우 lua engine 의 값만 변경(used_memory_lua ) 되는 것을 확인 할  수 있다.
local src = KEYS[1]  
for i=1, src, 2 do  
	local test_key = 'lua_test_' .. i  
	redis.call('set', test_key, i)  
end;  
-> 한마디로 set lua_test_홀수번호 홀수번호  
EVAL "local src = KEYS[1] for i=1, src, 2 do local test_key = 'lua_test_' .. i redis.call('set', test_key, i) end;"
  1. 초기 값 확인
    1. used_memory_lua : 32768 / used_memory_scripts : 0 / number_of_cached_scripts : 0  
  2. lua 스크립트로 캐싱 진행
    1. used_memory_lua : 33792 / used_memory_scripts : 216 / number_of_cached_scripts : 1
    2. lua 엔진 및 메모리에 적재 된 것을 확인 (스크립트 등록 시 기본 동작 하는 것으로 확인)
  3. lua 스크립트 실행
    1. used_memory_lua : 63488 / used_memory_scripts : 216 / number_of_cached_scripts : 1
    2. lua 엔진은 사용하였지만, get 명령어 같이 조회 하거나 하는 것이 아니기 때문에 lua 메모리 쪽에 적재 되는 것은 없는 것으로 확인
  4. 다시 한번 lua 스크립트 실행
    1. 동일하게 lua 엔진은 사용하였지만, memory 는 사용 하지 않은 것을 확인
    2. 바로 lua 로 실행 하여도 동일하게  engine 은 사용하지만, memory는 변경 되지 않는 것을 확인 완료

결론

  • 동일한 의미로 보이는 Lua 스크립트라고 하더라도, 내용이 조금이라도 다르면 서로 다른 스크립트로 인식
  • 동일한 명령어 이라고 하더라도, return  의 유무에 따라 위의 의미와 같이 서로 다른 스크립트로 인식
  • set 명령어로만 이루어진 lua  스크립트는, 별도의 메모리를 사용하지 않음 (lua 엔진만 메모리 사용)
  • 그 외 메모리 사용률을 확인 하기 위해서는 used_memory_scripts  를 모니터링 하며, used_memory_lua 는 평소와 비슷한지 체크하면 좋을 듯 합니다.
  • Elasticache 를 이용한다면, Lua script 내용이 get 형태의 읽기로만 이루어진 내용이라면, read를 이용하는 것을 추천합니다.(Lua의 수행속도가 오래 걸린다면 write 뿐만 아니라 redis 자체가 싱글 스레드로 동작하기 때문에 대기를 하게 되지만, 적어도 read를 이용한다면 write에 대해서만큼은 영향을 덜 미치기 때문 / 하지만 Lua 성능 최적화는 꼭 합시다.)

그외

AWS 의 경우 Cloudwatch 상에서 Elasticache 지표에서는 used_momory_scripts / lua 등을 제공을 하지 않기 때문에 BytesUsedForCache 와 FreeableMemory 의 변화로 모니터링 하는 것으로 우회 하거나, 해당 지표를 직접 조회하여 모니터링 하는 것을 추천 드립니다.

 

참고

다양한 샘플을 참고 할 수 있음 : https://bstar36.tistory.com/348
https://redis.io/docs/manual/programmability/eval-intro/
AWS  Support 최원 님 도움 주셔서 감사합니다.

반응형
반응형
  1. 개요 및 아키텍처
    1. 개요
      1. 메모리 DB (높은 처리량 - Replication 읽기 및 쓰기, 대기 시간 등 높은 처리 가능)
      2. 레디스와 호환이 되며, 레디스 관련한 것들을 모두 사용 가능 (v6.2)
      3. Multi-AZ 를 지원하여 빠르게 failover 및 복구, 재시작이 가능
    2. 특징
      1. Primary / Replica 간의 강력한 일관성 보장
      2. ms 단위의 읽기,쓰기 지연시간 (클러스터당 최대 1억6천만 tps)
      3. redis 호환
      4. 빠른 데이터 복구 및 재시작 제공 (multi-az, transaction log )
      5. multi-az를 통한 자동 페일오버 및 노드 fail에 대한 감지 및  복구
      6. replication 및 shard를 이용한 노드 추가, scale out, scale up-down 가능
      7. primary 에 대한 read/write 일관성 보장 및 복제 노드에 대한 일관성 보장 가능(read / write concern으로 예상)
      8. 사용자 인증 및 네트워크 인증, 암호화 기능 제공
      9. s3로 자동 스냅샷 (최대 35일 - rds 와 동일)
      10. 하나의 클러스터로 최대 500개 노드 및 100tb 이상의 storage 지원(레플리카 포함)
      11. AWS KMS keys를 사용한 TLS 암호화(8번과 동일)
      12. Redis를 통한 사용자 인증 및 권한 부여(ACL)(8번과 동일)
      13. AWS Graviton2 인스턴스 유형 지원
      14. VPC, Cloudwatch, CloudTrail, AWS SNS 서비스와의 통합
      15. 완전 관리형 소프트웨어 패치 및 업그레이드 지원
      16. 관리 API를 위한 AWS IAM(Identity and Access Management) 통합 및 태그 기반 액세스 제어
    3. 주요 기능
      1. Cluster
        1. MemoryDB 서비스를 운영하는 하나 이상의 노드 모음 (서비스의 개념)
        2. Shard는 Memory DB Set 단위들의 모임으로 Cluster 내에 존재
          1. Noes ⊂ Shard ⊂ Cluster  = 서비스 DB
        3. Memory DB Set 에는 하나의 Primary 와 최대 5개의 Replica 노드들을 보유 가능
        4. Primary 는 read/write 가능하며, Replica node들은 only read 만 처리
        5. Primary 장애 시 replica node들 중 하나를 primary 로 승격
        6. cluster 생성 시 redis 버전을 지정
        7. cluster 내 Memory DB 기능
          1. cluster 추가
          2. cluster 수정
          3. cluster 스냅샷 가져오기
          4. cluster 삭제
          5. cluster 내 요소 보기
          6. cluster 에 비용 할당 태그 추가 / 삭제
      2. Nodes
        1. MemoryDB 구성 중 가장 작은 단위 (EC2 기반)
        2. 클러스터에 속하며, cluster 생성 시 정해진 버전의 엔진 기반
        3. 필요한 경우 클러스터의 노드를 다른 유형으로 up / down 가능
        4. 단독으로 up / down 가능은 체크 필요
      3. Shards
        1. 하나의 샤드에는 1~6개의 노드로 구성되며, primary 1개에 5개의 replica 로 구성
        2. MemoryDB Cluster는 항상 적어도 하나의 샤드로 구성
        3. 클러스터 내 최대 500개의 샤드를 생성 가능
          1. 최대 500개 노드를 가질 수 있으므로, 1샤드=1 Primary 노드로 하는 경우 500샤드 구성 가능
          2. 단, IP주소가 충분한지 체크 필요
      4. Parameter groups
        1. parameter group 을 적용함으로써 각기 다른 parameter 를 적용 가능
        2. RDS 와 동일 개념
      5. Subnet Groups
        1. VPC 내 subnet group 으로 구성
      6. Access Control Lists
        1. Redis ACL 규칙을 적용 가능 (Access Control List)
      7. Users
        1. 이름과 암호를 가진 User를 생성하여 접속 가능

        2. 2. 사용자는 ACL 구성원
  2. Redis vs Elasticache Redis vs MemoryDB for Redis
    1. 성능 : Elasticache 가 Memory DB 보다 쓰기 읽기 성능이 더 좋음
  Redis ElastiCache for Redis MemoryDB for Redis
내구성 AOF, RDB 로 내구성 처리
(AOF 파일에 쓰기 전 장애 시 데이터 손실 발생 가능성)
Primary 리턴 응답이라, Replica node에 데이터 적재 전 장애 시 손실 발생 가능성 존재
Redis 데이터구조 및 API
내구성이 뛰어난 Inmemory DB (장애 시 무손실 복구)
(Transaction log 까지 작성 후 응답이기 때문에 무손실 가능)
Redis 데이터구조 및 API
성능 12만/sec read/write : μs (마이크로초) read : μs (마이크로초)
write : ms (한자리 Millisecond)
Cluster mode Cluster mode 활성화 비활성화 모두 가능 cluster mode 활성화, 비활성화 모두 가능 cluster mode 활성화 필수
접속 redis-cli 로 접속
백업
  • 조건부 RDB 백업 가능
  • AOF 로 모든 DML 쿼리 저장
  • 24시간 동안 20개까지 스냅샷 생성 제한
    • cluster mode에서만 백업
  • 해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
  • 24시간 동안 20개까지 스냅샷 생성 제한
    • cluster mode에서만 백업
  • 해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
복원
  • RDB 시점 복원 가능
  • AOF 이용하여 원하는 명령문까지 복원 가능
  • RDB 스냅샷 복원
  • 별도의 Replica node가 없을 경우 유실(마지막 스냅샷 이후 부터 유실)
  • RDB 스냅샷 복원
  • 특정시점복원은 불가 (Point in  time Recovery 불가)
  • Transaction log를 이용하여 장애 최종 복원 가능
고가용성 replica
shard 구성
Replica
Shard 구성
 
replica node의 복제가 실패하는 경우
  • 실패 노드를 감지하여 오프라인 전환 및 동일한 AZ에 교체노드를 실행하여 동기화 진행
MemoryDB Multi-AZ primary 장애
  • MemoryDB에서 Primary 오류 감지하면, replica node들 중 primary 정합성체크 후 primary 승격 후 다른 AZ에 있는 primary를 spin up 이후 동기화 진행
    (다른 AZ의 primary 를 spin up 이후 동기화 하는 것보다 더 빠름)
복제 replica 구성
  • async 복제
    • rdb로 먼저 전체 복제
    • 복제 버퍼 내용 복제
replica 구성
  • async 복제
    • rdb 전체 복제
    • (Reserved Memory) 내용 복제
transaction log를 사용하는 async 복제
  • transaction log에 저장(영구저장)하므로 데이터 손실될 위험이 없음
  • Multi-AZ 강력히 권장
  1. 가격 및 Region
    1. 가격
      1. https://aws.amazon.com/ko/memorydb/pricing/ 참고
      2. Elastic Cache 보다 하루 1달러 더 비싸다고 공유 받음
    2. 지원 region
      1. 현재 지원하고 있는 내역 리스트
      2. US East (N. Virginia), US East (Ohio), US West (Oregon), US West (Northern California), EU (Ireland), EU (London), EU (Stockholm), Asia Pacific (Mumbai), Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo),  Canada (Central), and South America (Sao Paulo)  - 21년10월 정보

 

참고

https://docs.aws.amazon.com/memorydb/latest/devguide/what-is-memorydb-for-redis.html
https://docs.aws.amazon.com/memorydb/latest/devguide/components.html

Elasticache vs MemoryDB 성능 : https://www.sentiatechblog.com/benchmark-series-amazon-memorydb-and-how-it-stands-compared-to-amazon
https://youtu.be/Jbq_XZMZEKY

반응형
반응형
  1. 개요 및 아키텍처
    1. 개요
      1. 메모리 DB (높은 처리량 - Replication 읽기 및 쓰기, 대기 시간 등 높은 처리 가능)
      2. 레디스와 호환이 되며, 레디스 관련한 것들을 모두 사용 가능 (v6.2)
      3. Multi-AZ 를 지원하여 빠르게 failover 및 복구, 재시작이 가능
    2. 특징
      1. Primary / Replica 간의 강력한 일관성 보장
      2. ms 단위의 읽기,쓰기 지연시간 (클러스터당 최대 1억6천만 tps)
      3. redis 호환
      4. 빠른 데이터 복구 및 재시작 제공 (multi-az, transaction log )
      5. multi-az를 통한 자동 페일오버 및 노드 fail에 대한 감지 및  복구
      6. replication 및 shard를 이용한 노드 추가, scale out, scale up-down 가능
      7. primary 에 대한 read/write 일관성 보장 및 복제 노드에 대한 일관성 보장 가능(read / write concern으로 예상)
      8. 사용자 인증 및 네트워크 인증, 암호화 기능 제공
      9. s3로 자동 스냅샷 (최대 35일 - rds 와 동일)
      10. 하나의 클러스터로 최대 500개 노드 및 100tb 이상의 storage 지원(레플리카 포함)
      11. AWS KMS keys를 사용한 TLS 암호화(8번과 동일)
      12. Redis를 통한 사용자 인증 및 권한 부여(ACL)(8번과 동일)
      13. AWS Graviton2 인스턴스 유형 지원
      14. VPC, Cloudwatch, CloudTrail, AWS SNS 서비스와의 통합
      15. 완전 관리형 소프트웨어 패치 및 업그레이드 지원
      16. 관리 API를 위한 AWS IAM(Identity and Access Management) 통합 및 태그 기반 액세스 제어
    3. 주요 기능
      1. Cluster
        1. MemoryDB 서비스를 운영하는 하나 이상의 노드 모음 (서비스의 개념)
        2. Shard는 Memory DB Set 단위들의 모임으로 Cluster 내에 존재
          1. Noes ⊂ Shard ⊂ Cluster  = 서비스 DB
        3. Memory DB Set 에는 하나의 Primary 와 최대 5개의 Replica 노드들을 보유 가능
        4. Primary 는 read/write 가능하며, Replica node들은 only read 만 처리
        5. Primary 장애 시 replica node들 중 하나를 primary 로 승격
        6. cluster 생성 시 redis 버전을 지정
        7. cluster 내 Memory DB 기능
          1. cluster 추가
          2. cluster 수정
          3. cluster 스냅샷 가져오기
          4. cluster 삭제
          5. cluster 내 요소 보기
          6. cluster 에 비용 할당 태그 추가 / 삭제
      2. Nodes
        1. MemoryDB 구성 중 가장 작은 단위 (EC2 기반)
        2. 클러스터에 속하며, cluster 생성 시 정해진 버전의 엔진 기반
        3. 필요한 경우 클러스터의 노드를 다른 유형으로 up / down 가능
        4. 단독으로 up / down 가능은 체크 필요
      3. Shards
        1. 하나의 샤드에는 1~6개의 노드로 구성되며, primary 1개에 5개의 replica 로 구성
        2. MemoryDB Cluster는 항상 적어도 하나의 샤드로 구성
        3. 클러스터 내 최대 500개의 샤드를 생성 가능
          1. 최대 500개 노드를 가질 수 있으므로, 1샤드=1 Primary 노드로 하는 경우 500샤드 구성 가능
          2. 단, IP주소가 충분한지 체크 필요
      4. Parameter groups
        1. parameter group 을 적용함으로써 각기 다른 parameter 를 적용 가능
        2. RDS 와 동일 개념
      5. Subnet Groups
        1. VPC 내 subnet group 으로 구성
      6. Access Control Lists
        1. Redis ACL 규칙을 적용 가능 (Access Control List)
      7. Users
        1. 이름과 암호를 가진 User를 생성하여 접속 가능

        2. 2. 사용자는 ACL 구성원
  2. Redis vs Elasticache Redis vs MemoryDB for Redis
    1. 성능 : Elasticache 가 Memory DB 보다 쓰기 읽기 성능이 더 좋음
  Redis ElastiCache for Redis MemoryDB for Redis
내구성 AOF, RDB 로 내구성 처리
(AOF 파일에 쓰기 전 장애 시 데이터 손실 발생 가능성)
Primary 리턴 응답이라, Replica node에 데이터 적재 전 장애 시 손실 발생 가능성 존재
Redis 데이터구조 및 API
내구성이 뛰어난 Inmemory DB (장애 시 무손실 복구)
(Transaction log 까지 작성 후 응답이기 때문에 무손실 가능)
Redis 데이터구조 및 API
성능 12만/sec read/write : μs (마이크로초) read : μs (마이크로초)
write : ms (한자리 Millisecond)
Cluster mode Cluster mode 활성화 비활성화 모두 가능 cluster mode 활성화, 비활성화 모두 가능 cluster mode 활성화 필수
접속 redis-cli 로 접속
백업
  • 조건부 RDB 백업 가능
  • AOF 로 모든 DML 쿼리 저장
  • 24시간 동안 20개까지 스냅샷 생성 제한
    • cluster mode에서만 백업
  • 해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
  • 24시간 동안 20개까지 스냅샷 생성 제한
    • cluster mode에서만 백업
  • 해당 Region에서 수동 스냅샷 보유 개수 제한은 없음
복원
  • RDB 시점 복원 가능
  • AOF 이용하여 원하는 명령문까지 복원 가능
  • RDB 스냅샷 복원
  • 별도의 Replica node가 없을 경우 유실(마지막 스냅샷 이후 부터 유실)
  • RDB 스냅샷 복원
  • 특정시점복원은 불가 (Point in  time Recovery 불가)
  • Transaction log를 이용하여 장애 최종 복원 가능
고가용성 replica
shard 구성
Replica
Shard 구성
 
replica node의 복제가 실패하는 경우
  • 실패 노드를 감지하여 오프라인 전환 및 동일한 AZ에 교체노드를 실행하여 동기화 진행
MemoryDB Multi-AZ primary 장애
  • MemoryDB에서 Primary 오류 감지하면, replica node들 중 primary 정합성체크 후 primary 승격 후 다른 AZ에 있는 primary를 spin up 이후 동기화 진행
    (다른 AZ의 primary 를 spin up 이후 동기화 하는 것보다 더 빠름)
복제 replica 구성
  • async 복제
    • rdb로 먼저 전체 복제
    • 복제 버퍼 내용 복제
replica 구성
  • async 복제
    • rdb 전체 복제
    • (Reserved Memory) 내용 복제
transaction log를 사용하는 async 복제
  • transaction log에 저장(영구저장)하므로 데이터 손실될 위험이 없음
  • Multi-AZ 강력히 권장
  1. 가격 및 Region
    1. 가격
      1. https://aws.amazon.com/ko/memorydb/pricing/ 참고
      2. Elastic Cache 보다 하루 1달러 더 비싸다고 공유 받음
    2. 지원 region
      1. 현재 지원하고 있는 내역 리스트
      2. US East (N. Virginia), US East (Ohio), US West (Oregon), US West (Northern California), EU (Ireland), EU (London), EU (Stockholm), Asia Pacific (Mumbai), Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo),  Canada (Central), and South America (Sao Paulo)  - 21년10월 정보

 

참고

https://docs.aws.amazon.com/memorydb/latest/devguide/what-is-memorydb-for-redis.html
https://docs.aws.amazon.com/memorydb/latest/devguide/components.html

Elasticache vs MemoryDB 성능 : https://www.sentiatechblog.com/benchmark-series-amazon-memorydb-and-how-it-stands-compared-to-amazon
https://youtu.be/Jbq_XZMZEKY

반응형

+ Recent posts