IT/AWS

[AWS] ElastiCache Redis Cluster

물통꿀꿀이 2019. 1. 6. 19:20

ElastiCache Redis Cluster

AWS의 Managed Service인 ElastiCache에서 Redis를 Cluster 모드로 적용하여 사용할 수 있다.


그림 1. ElastiCache Redis Cluster


위의 그림 1에서도 확인 할 수 있듯이, AWS에서 Redis는 Cluster 모드를 사용하지 않을 때에는 Replication만 적용할 수 있지만 Cluster 모드를 사용할 때에는 Replication 뿐만 아니라 Data Partitioning 또한 적용 할 수 있다. 

(물론, Redis Cluster 자체가 데이터 분산을 위한 방법이긴 하지만.)

Redis Cluster 구성에 대한 자세한 부분은 아래 글을 참조해보자.


Shard

Shard는 단순히 관련된 Node의 집합이다. 그렇다고 무한정의 Node를 가지고 있는 것은 아니고 최대 6개* 까지 가질 수 있다.

* 최대 6개는 Primary Node 1개와 Replica Node 최대 5개를 의미한다.

그리고 Cluster 환경에서는 최대 15개까지 사용가능하다. (그렇기 때문에 Cluster 환경에서 전체 Node의 개수는 최대 90개가 될 수 있다.)


그림 2. Shard


그림 2에서도 확인 할 수 있듯이 Cluster 환경에서 Shard는 최대 6개의 Node를 가지고 있지만 이 중에서 단 하나만이 Primary Node이다. 

즉, Master Node이면서 Read/Write 2 개의 작업을 수행할 수 있다. (나머지는 Slave Node로 Read 작업만 수행 할 수 있다.)


그림 3. Add Shard


이를 바탕으로 실제 AWS Redis에서 Shard를 추가하려하면 그림 3과 같은 화면을 볼 수 있다. 

설명을 추가하자면 "현재 샤드 수 3"은 해당 Cluster의 Shard가 총 3개라는 의미이며 "현재 샤드당 복제본 수 4"는 Shard에 Replica가 4개가 포함된다는 의미이다. 즉, Shard의 전체 Node의 개수는 5개이다.


Node

Redis Cluster의 최소 단위이자 가장 중요한 구성 요소이다. 

(아래 페이지 참조) 이전 글에서도 설명했지만, Cluster Node라고도 명명되는 이 Node는 자신이 Master인지 Slave인지 자각하고 있다.

http://timewizhan.tistory.com/entry/Reids-Cluster-Overview?category=1009915

http://timewizhan.tistory.com/entry/Redis-Cluster-Redirection?category=1009915


그림 4. Add Node


그래서 그림 4와 같이 Node를 추가 할 때, Primary Node의 Replica로 추가 된다. 

(AWS Redis에서 Node 추가는 Replica로써만 추가된다.)


그림 5. Shard Hash Slot


그림 5를 확인해보면, 각 Shard 마다 Hash Slot의 번호가 지정되어 있다. Redis Cluster에서는 16383개의 Hash Slot을 가질 수 있는데 Shard가 2개이기 떄문에 Shard 1에는 0~8191 그리고 Shard 2에는 8192~16383로 나누어져 있다. (물론 사용자 임의로 Hash Slot을 설정할 수 있다.)


그림 6. Slot/Key Space


이를 바탕으로 실제 AWS ElastiCache를 확인해보면 그림 6과 같다. (Shard가 총 3개이고 Slot을 균등 분배)


Practice

AWS ElastiCache의 Redis Cluster 환경을 사용하기 위해서는 특별한 라이브러리를 사용해야 한다. (아래 페이지 참조)

(https://redis.io/topics/cluster-tutorial#playing-with-the-cluster)

물론 일반적인 Redis 라이브러리를 사용해도 되지만, 접근 에러 등등과 같은 추가 로직을 따로 구현해야 하기 때문에 Cluster 환경 전용 라이브러리를 사용하는 것이 보다 손쉽다.


지금 부터는 한 번 Cluster 환경에 직접 접근해서 사용해 보려고 한다.

그림 7. AWS Redis Cluster Environment


먼저, Redis Cluster 환경에 접근하기 위해 구성 엔드포인트를 사용한다. 

Cluster 환경이 아닌 Redis는 기본 엔드포인트를 사용하게 되는데 그 이유는 No Cluster 환경에서는 Primary Node 하나만 접근하면 되기 때문에 기본 엔드포인트를 제공해준다. 반면에 Cluster 환경에서는 구성 엔드포인트에서 Cluster 환경의 모든 Node를 알고 있기 때문에 기본적인 접근은 구성 엔드포인트로 한다.


그렇다면 Cluster 라이브러리인 redis-py-cluster를 사용하면 코드는 아래와 같다.

(https://github.com/Grokzen/redis-py-cluster)


from rediscluster import StrictRedisCluster


# Requires at least one node for cluster discovery. Multiple nodes is recommended.

startup_nodes = [{"host": Configuration Endpoint, "port": Port}]


rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True, skip_full_coverage_check=True) 


위의 코드를 적용하여 Redis에 키 값을 저장하면 모든 작업이 정상적으로 수행된다.

그런데 정말 정상적으로 수행되는지 확인하기 위해 Cluster를 지원하지 않는 redis-py 라이브러리를 사용해보면 다음과 같다.


try:

        r.set('cluster-test', 'cluster-test-value')

        print(r.get('cluster-test'))

except Exception as e:

        print(e) 


먼저 Cluster 라이브러리를 사용해서 "cluster-test"를 Redis에 저장한다. 그 이후에 No Cluster 라이브러리를 적용해서 사용해보면 아래와 같은 결과를 얻을 수 있다.

MOVED 14783 <IP>:<Port>


이는 구성 엔드포인트 DNS의 실제 Node가 Cluster의 모든 Node를 알고 있기 때문에 해당 키에 맞는 Slot 즉, 적합한 Node를 Redirection 한 것이다.


그림 8. Shard Slot (그림 6과 같음)


뿐만 아니라, Slot 14783에 맞지 않는 Shard 1이나 2에 접근했을 때 (그림 8 참조) 같은 Redirection 에러를 확인 할 수 있다.

그런데 Slot 14783이 포함되어 있는 Shard의 Replica에 접근했을 때에도 같은 에러가 발생하는데 이는 Cluster 환경에서 Slave Node로 접근 할 수 없기 때문*이다.

(https://redis-py-cluster.readthedocs.io/en/master/readonly-mode.html)

*Cluster 라이브러리에서는 readonly-mode를 만들어 Slave Node에도 접근하게 한다.


한 가지, Cluster 라이브러리에서 구성 엔드포인트를 사용하지 않고 각 Node의 엔드포인트를 사용해도 Redis Cluster를 원활히 사용 할 수 있다.

이 것은 이전 글에서도 언급했지만 각각의 Node가 주변의 모든 Node를 알고 있기 때문에 자연스럽게 사용자의 요청을 다른 Node로 Redirect해서 결과를 반환해주기 때문이다.


Reference

https://docs.aws.amazon.com/ko_kr/AmazonElastiCache/latest/red-ug/WhatIs.html?shortFooter=true