Search
πŸ™ˆ

Redis Cluster

Intro::

Redis Cluster에 λŒ€ν•œ μ •λ¦¬λ³Έμž…λ‹ˆλ‹€.

Redis Cluster λž€??

Redis ν΄λŸ¬μŠ€ν„°λŠ” Redis의 λΆ„μ‚° λ²„μ „μœΌλ‘œ, 데이터λ₯Ό μ—¬λŸ¬ λ…Έλ“œμ— λΆ„μ‚° μ €μž₯ν•˜μ—¬ κ³ κ°€μš©μ„±κ³Ό ν™•μž₯성을 μ œκ³΅ν•˜λŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. Redis ν΄λŸ¬μŠ€ν„°λŠ” μ—¬λŸ¬ Redis μΈμŠ€ν„΄μŠ€λ₯Ό ν•˜λ‚˜μ˜ ν΄λŸ¬μŠ€ν„°λ‘œ κ΅¬μ„±ν•˜μ—¬ 데이터λ₯Ό μžλ™μœΌλ‘œ μƒ€λ”©ν•˜κ³ , λ…Έλ“œ μž₯μ•  μ‹œ μžλ™μœΌλ‘œ λ³΅κ΅¬ν•©λ‹ˆλ‹€.

νŠΉμ§•

1.
μžλ™ 샀딩:
β€’
Redis ν΄λŸ¬μŠ€ν„°λŠ” 데이터λ₯Ό μžλ™μœΌλ‘œ μ—¬λŸ¬ λ…Έλ“œμ— λΆ„μ‚° μ €μž₯ν•©λ‹ˆλ‹€. μ΄λŠ” 데이터λ₯Ό κ· λ“±ν•˜κ²Œ λΆ„λ°°ν•˜μ—¬ 각 λ…Έλ“œμ˜ λΆ€ν•˜λ₯Ό μ€„μž…λ‹ˆλ‹€.
2.
κ³ κ°€μš©μ„±:
β€’
ν΄λŸ¬μŠ€ν„° λ‚΄μ˜ 각 λ…Έλ“œλŠ” μ£Ό λ…Έλ“œ(λ§ˆμŠ€ν„°)와 보쑰 λ…Έλ“œ(슬레이브)둜 κ΅¬μ„±λ©λ‹ˆλ‹€. λ§ˆμŠ€ν„° λ…Έλ“œκ°€ μž₯μ• λ₯Ό μΌμœΌν‚€λ©΄ 슬레이브 λ…Έλ“œκ°€ μžλ™μœΌλ‘œ μŠΉκ²©λ˜μ–΄ λ§ˆμŠ€ν„° 역할을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
3.
ν™•μž₯μ„±:
β€’
λ…Έλ“œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ œκ±°ν•˜μ—¬ ν΄λŸ¬μŠ€ν„°λ₯Ό μ‰½κ²Œ ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” ν΄λŸ¬μŠ€ν„°μ˜ μ €μž₯ μš©λŸ‰κ³Ό 처리 λŠ₯λ ₯을 μœ μ—°ν•˜κ²Œ μ‘°μ •ν•  수 있게 ν•©λ‹ˆλ‹€.
4.
λ…Έλ“œ κ°„ 톡신:
β€’
Redis ν΄λŸ¬μŠ€ν„°μ˜ λ…Έλ“œλ“€μ€ μ„œλ‘œ ν†΅μ‹ ν•˜λ©°, 데이터 λΆ„μ‚°κ³Ό 볡제λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.
5.
νŒŒν‹°μ…”λ‹:
β€’
데이터λ₯Ό νŒŒν‹°μ…”λ‹ν•˜μ—¬ 각 λ…Έλ“œμ— λΆ„λ°°ν•©λ‹ˆλ‹€. Redis ν΄λŸ¬μŠ€ν„°λŠ” ν•΄μ‹œ μŠ¬λ‘―μ„ μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό 16384개의 μŠ¬λ‘―μ— λ§€ν•‘ν•˜κ³ , 이λ₯Ό λ…Έλ“œμ— λΆ„λ°°ν•©λ‹ˆλ‹€.

μž₯점

1.
높은 κ°€μš©μ„±:
β€’
λ…Έλ“œ μž₯μ•  μ‹œ μžλ™μœΌλ‘œ λ³΅κ΅¬λ˜λ―€λ‘œ μ„œλΉ„μŠ€μ˜ κ°€μš©μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
2.
μˆ˜ν‰μ  ν™•μž₯:
β€’
λ…Έλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ μ €μž₯ μš©λŸ‰κ³Ό 처리 μ„±λŠ₯을 μ‰½κ²Œ ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
3.
μžλ™ 데이터 λΆ„λ°°:
β€’
데이터λ₯Ό μžλ™μœΌλ‘œ λΆ„μ‚° μ €μž₯ν•˜μ—¬ 각 λ…Έλ“œμ˜ λΆ€ν•˜λ₯Ό 쀄이고, μ„±λŠ₯을 ν–₯μƒμ‹œν‚΅λ‹ˆλ‹€.
4.
고속 μ„±λŠ₯:
β€’
λΆ„μ‚°λœ λ…Έλ“œλ“€μ΄ λ³‘λ ¬λ‘œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ―€λ‘œ, 높은 μ„±λŠ₯을 μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

단점

1.
λ³΅μž‘ν•œ μ„€μ •:
β€’
ν΄λŸ¬μŠ€ν„°λ₯Ό μ„€μ •ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” 과정이 단일 μΈμŠ€ν„΄μŠ€ Redis에 λΉ„ν•΄ λ³΅μž‘ν•©λ‹ˆλ‹€.
2.
λ„€νŠΈμ›Œν¬ μ˜€λ²„ν—€λ“œ:
β€’
λ…Έλ“œ κ°„ ν†΅μ‹ μœΌλ‘œ 인해 λ„€νŠΈμ›Œν¬ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
3.
일관성 문제:
β€’
λ„€νŠΈμ›Œν¬ λΆ„ν•  λ˜λŠ” λ…Έλ“œ μž₯μ•  μ‹œ μΌμ‹œμ μΈ 일관성 λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
4.
μ œν•œλœ 데이터 νƒ€μž… 지원:
β€’
νŠΉμ • 데이터 νƒ€μž…μ΄λ‚˜ λͺ…λ Ήμ–΄λŠ” ν΄λŸ¬μŠ€ν„° λͺ¨λ“œμ—μ„œ μ™„μ „νžˆ μ§€μ›λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

Dockerfile.redis

FROM redis:latest CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]
Bash
볡사

Dockerfile.alpine

FROM alpine:latest RUN apk add --no-cache redis
Bash
볡사

redis.conf

port 6379 daemonize no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 3000 appendonly yes requirepass λΉ„λ°€λ²ˆν˜Έ masterauth λΉ„λ°€λ²ˆ
Bash
볡사

docker-compose.yml

services: redis-master-1: container_name: redis-master-1 build: context: . dockerfile: Dockerfile.redis ports: - "6379:6379" volumes: - redis-master-1-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-master-2: container_name: redis-master-2 build: context: . dockerfile: Dockerfile.redis ports: - "6380:6379" volumes: - redis-master-2-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-master-3: container_name: redis-master-3 build: context: . dockerfile: Dockerfile.redis ports: - "6381:6379" volumes: - redis-master-3-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-slave-1: container_name: redis-slave-1 build: context: . dockerfile: Dockerfile.redis ports: - "6382:6379" volumes: - redis-slave-1-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-slave-2: container_name: redis-slave-2 build: context: . dockerfile: Dockerfile.redis ports: - "6383:6379" volumes: - redis-slave-2-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-slave-3: container_name: redis-slave-3 build: context: . dockerfile: Dockerfile.redis ports: - "6384:6379" volumes: - redis-slave-3-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf networks: - redis-cluster-net redis-setup: container_name: redis-setup build: context: . dockerfile: Dockerfile.alpine depends_on: - redis-master-1 - redis-master-2 - redis-master-3 - redis-slave-1 - redis-slave-2 - redis-slave-3 environment: - REDIS_PASSWORD=password volumes: - ./setup-redis-cluster.sh:/usr/local/etc/redis/setup-redis-cluster.sh networks: - redis-cluster-net command: ["sh", "-c", "chmod +x /usr/local/etc/redis/setup-redis-cluster.sh && /usr/local/etc/redis/setup-redis-cluster.sh"] volumes: redis-master-1-data: redis-master-2-data: redis-master-3-data: redis-slave-1-data: redis-slave-2-data: redis-slave-3-data: networks: redis-cluster-net:
Bash
볡사

setup-redis-cluster.sh

#!/bin/sh # Install redis-cli apk add --no-cache redis echo "Waiting for Redis nodes to start..." sleep 10 echo "Creating Redis cluster with masters..." yes yes | redis-cli --cluster create \ redis-master-1:6379 \ redis-master-2:6379 \ redis-master-3:6379 \ --cluster-replicas 0 \ -a ${REDIS_PASSWORD} echo "Adding slaves to the cluster..." redis-cli --cluster add-node redis-slave-1:6379 redis-master-1:6379 --cluster-slave -a ${REDIS_PASSWORD} redis-cli --cluster add-node redis-slave-2:6379 redis-master-2:6379 --cluster-slave -a ${REDIS_PASSWORD} redis-cli --cluster add-node redis-slave-3:6379 redis-master-3:6379 --cluster-slave -a ${REDIS_PASSWORD}
Bash
볡사

데이터 확인 예제

# μ»¨ν…Œμ΄λ„ˆ 접속 docker exec -it redis-master-1 sh # ν΄λŸ¬μŠ€ν„° λͺ¨λ“œ λ ˆλ””μŠ€ cli 접속 redis-cli -c -a password # key value μ €μž₯ set key1 "Hello, Redis!" # 데이터 확인 get key1 "Hello, Redis!" # 데이터가 μ‹€μ œλ‘œ μ €μž₯된 ν‚€μŠ¬λ‘―ν™•μΈ CLUSTER KEYSLOT key1 (integer) 9189 # λ…Έλ“œλ³„ λ‹΄λ‹Ή ν‚€μŠ¬λ‘―λ²”μœ„λ₯Ό ν™•μΈν•˜μ—¬ μ–΄λŠ λ…Έλ“œκ°€ κ΄€λ¦¬ν•˜κ³  μžˆλŠ”μ§€ νŒŒμ•… κ°€λŠ₯ CLUSTER NODES 2dc5480b5c9521c5d987d56136ef23cc4422cfa2 172.19.0.2:6379@16379 slave 3376c85cb33ca95be7a30ef980019e2c50da7afb 0 1721288671554 3 connected 3376c85cb33ca95be7a30ef980019e2c50da7afb 172.19.0.5:6379@16379 master - 0 1721288671554 3 connected 10923-16383 121edfec52734ec5d1d3c3e7fc4e6da91996d0f7 172.19.0.4:6379@16379 slave 6313f3c66d1e407140f9140e368fda08e3f3f10e 0 1721288671554 2 connected 1adf90a107637a3e45fdb9bd19fc55b8c4b0a423 172.19.0.7:6379@16379 slave 4b82b9e5bbf9676a52eab80dd17eea77a938aa9d 0 1721288671050 1 connected 6313f3c66d1e407140f9140e368fda08e3f3f10e 172.19.0.3:6379@16379 master - 0 1721288671000 2 connected 5461-10922 4b82b9e5bbf9676a52eab80dd17eea77a938aa9d 172.19.0.6:6379@16379 myself,master - 0 1721288670000 1 connected 0-5460
Bash
볡사
ν‚€μŠ¬λ‘―μ— λΆ„μ‚°λ˜μ–΄ ν‚€κ°€ μ €μž₯되며, ν‚€μŠ¬λ‘―μ—λŠ” μ—¬λŸ¬ ν‚€μŠ¬λ‘―μ΄ μ‘΄μž¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Trouble Shooting

WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
# λ‘œμ»¬μ—μ„œ μ„€μ • sudo sysctl vm.overcommit_memory=1
Bash
볡사
μ»¨ν…Œμ΄λ„ˆμ—μ„œλ„ μ„€μ •ν•  수 μžˆλŠ” 방법이 μžˆμ§€λ§Œ, λ³΄μ•ˆμ μΈ 이유둜 ꢌμž₯ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  ν•©λ‹ˆλ‹€.

References::

5λΆ„ μ•ˆμ— κ΅¬μΆ•ν•˜λŠ” Redis-Cluster
Redis-Cluster νŠΉμ§•? masterλ₯Ό μ—¬λŸ¬κ°œ 두어 λΆ„μ‚° μ €μž₯이 κ°€λŠ₯ν•˜λ©°(Sharding), scale out 이 κ°€λŠ₯ν•˜λ‹€. μ„œλ²„λ₯Ό 늘릴수둝 μ €μž₯ν• μˆ˜ μžˆλŠ” 곡간이 λ¬΄ν•œλŒ€λ‘œ 컀진닀. master에 ν•˜λ‚˜ μ΄μƒμ˜ slave λ₯Ό λ‘˜ 수 μžˆλ‹€. master 1,2,3 이 μžˆλ‹€λ©΄ λ°μ΄ν„°λŠ” 3κ°œμ€‘μ— ν•˜λ‚˜μ— μ €μž₯되며, client κ°€ 데이터 읽기 μš”μ²­μ‹œ μ €μž₯된 곳이 μ•„λ‹Œ λ‹€λ₯Έ λ§ˆμŠ€ν„°μ— μš”μ²­ ν–ˆλ‹€λ©΄ μ €μž₯된 λ§ˆμŠ€ν„° 정보λ₯Ό μ•Œλ €μ£Όλ©°, ν΄λΌμ΄μ–ΈνŠΈλŠ” 전달받은 λ§ˆμŠ€ν„° 정보에 λ‹€μ‹œ μš”μ²­ν•΄μ„œ 데이터λ₯Ό 받아와야 ν•œλ‹€. But, ν•΄λ‹Ή 뢀뢄은 redis-cluster λ₯Ό μ§€μ›ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ λ‹€ ν•΄μ€€λ‹€. * μ°Έκ³  - scale up : 단일 μ„œλ²„μ˜ μŠ€νŽ™μ„ 올렀 μ„œλ²„ μ„±λŠ₯을 λ†’νžŒλ‹€. - scale out : μ„œλ²„λ₯Ό μΆ”κ°€ν•˜μ—¬ μ„œλ²„ ..