환경

서버 : 2 vCPU, 4G Memory, 30G Disk 마스터 3대

OS : Ubuntu 24.04 LTS

Redis : redis-cli 7.0.15 ( redis-cli -v 또는 redis-cli 로 접속 후 info 명령어 수행후 redis_server 확인)

 

Redis 설치

각각의 서버에 Redis server를 설치한다.

$ sudo apt upgrade
$ sudo apt install redis-server

 

 redis.conf 파일 수정

각 서버의 /etc/redis/redis.conf 파일을 아래와 같이 수정한다. <master_IP> 와 <redis_password> 부분은 각자의 IP와 패스워드를 입력한다.

port 7000
bind <master_IP> -::1
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
requirepass <redis_password>
appendonly yes

 

Create a Redis Cluster

아래 명령어 수행 시 

redis-cli --cluster create master01_ip:7000 master02_ip:7000 master03_ip:7000

 

" [ERR] Node ip_addr:7000 DENIED Redis is running in protected mode ... " 오류가 발생했다.

  • 원인 : 호스트를 개방해줘도 redis에 protected mode가 가동중이기때문에 외부 접속이 안된다
  • 조치 :    

          1. redis가 설치된 우분투 사용 곧 외부접속이 아닌 내부접속 사용 : 물리적으로 다른 서버를 사용하므로 해당없음
          2. 보호모드 사용 중지 : /etc/redis/redis.conf 파일의 protecte mode yes를 protecte mode no로 변경
          3. redis 비밀번호를 설정하여 외부접속 : /etc/redis/redis.conf 의 requirepass <password> 설정

 

본 문서에서는 3번째 방법을 사용했다. 위에 redis.conf 파일 수정 부분에  requirepass <redis_password> 이 부분을 먼저 설정한 경우에는 이 오류가 발생하지 않는다. 단 수정 후 redis-server를 재기동해야 한다.

 

"[ERR] Node ip_addr:7000 NOAUTH Authentication required.

  • 원인 : redis-cli 수행 시 패스워드가 설정되어 있지 않음.
  • 조치 :   -a 'redis_password' 처럼 -a 옵션으로 패스워드 입력후 명령어 수행

의문점 : 각각의 master에서 수행해야 하는 것인지? 하나의 마스터에서만 수행하면 되는지? 일단, 하나의 마스터에서 수행하였다. 

               그리고 각각의 redis-server 정보를 info cluster 명령어로 확인해 보니 cluster_enabled:1 로 설정되었다.

               하나의 마스터에서만 수행하면 된다.

 

아래 화면은 cluster가 구성된 화면인다. Master 3대가 조인되었고 각 서버당 대략 5461개의 slot이 할당되었다.      

 

" Waiting for the cluster to join" 메시지가 출력된 상태로 진행이 되지 않을 경우

Every Redis Cluster node requires two TCP connections open. The normal Redis TCP port used to serve clients, for example 6379, plus the port obtained by adding 10000 to the data port, so 16379 in the example.

--> 방화벽 OPEN. 만약 다른 포트(7000)를 사용했다면 앞에 1을 붙여(17000) port가 오픈되어 있어야 한다.

 

 

 

 

테스트

set 테스트

redis-server -h [서버IP] -p 7000 -c -a [비밀번호] 를 입력하여 redis-server 에 클러스터 모드로 접속한다. (-c 입력 필수)

클러스터 모드로 접속하지 않으면 key setting 할 경우 아래처럼 오류가 발생한다.

[master01_ip]:7000> set id "hi. nice to meet you"
(error) MOVED 7568 [master02_ip]:7000

set id "hi. nice to meet you"는 key slot이 7568번이라서 2번 노드에 할당되어야 하는데, 클러스터 모드로 접근하지 않아 redis-cli 가 다른 노드에 접속하지 못하여 발생하는 오류이다.

 

아래처럼 -c 옵션으로 클러스터 모드로 접속한다.

redis-cli -h <master01_ip> -p 7000 -a <redis_password> -c

 

 

클러스터 모드로 redis-cli 접속한 후 아래와 같이 set 명령어를 수행하면 redis 프롬프트가 할당된 슬롯이 있는 해당 서버로 접속되는 것을 볼 수 있다. 아래 예제는 master02 서버로 접속하여 get 하는 명령어이다.

[master01_ip]:7000> set id "hi. nice to meet you"
-> Redirected to slot [7568] located at [master02_ip]:7000
OK
[master02_ip]:7000> get id
"hi. nice to meet you"

--> sharding 으로 데이터를 관리하므로 데이터가 있는 서버로 접속한다.

 

Redis Cluster 에 데이터를 저장하고 불러오는 Python 프로그램 

1) redis-py-cluster 라이브러리를 설치

pip install redis-py-cluster


오류 : rediscluster 모듈 실치 시 아래와 같은 오류가 발생했는데, 

pip install rediscluster 명령어가 아닌 pip install redis-py-cluster 명령어를 수행했다.

python3.12 버전에 맞는 rediscluster 는 pip install redis-py-cluster 명령어로 설치해야 한다.

ubuntu@ip-172-31-11-88:~$ pip install rediscluster
Defaulting to user installation because normal site-packages is not writeable
Collecting rediscluster
  Using cached rediscluster-0.5.3.tar.gz (9.9 kB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error
  
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [10 lines of output]
  .... 하략 ....

 

 

아래는 Redis 클러스터에 데이터를 설정하는 Python 예제 코드이다.

from rediscluster import RedisCluster

# Redis 클러스터 노드 구성
startup_nodes = [
    {"host": "master01_ip", "port": "7000"},
    {"host": "master02_ip", "port": "7000"},
    {"host": "master03_ip", "port": "7000"}
]

# Redis 클러스터 초기화
try:
    redis_cluster = RedisCluster(startup_nodes=startup_nodes, password=<redis_password>, decode_responses=True)
except Exception as e:
    print(f"Could not connect to Redis cluster: {e}")
    exit(1)

# 데이터 설정
key = "example_key"
value = "example_value"

try:
    redis_cluster.set(key, value)
    print(f"Key '{key}' set with value '{value}'")
except Exception as e:
    print(f"Could not set data in Redis cluster: {e}")

 

 

 

설명

+ Recent posts