Rate-Limit 종류 및 구현 방법
· 약 8분
Redis Cluster 환경에서의 Topology 변화, 클라이언트 동작 방식, 그리고 Read 전략에 대한 핵심 내용을 정리합니다. 실무 및 면접에서 바로 활용 가능한 내용으로 구성하였습니다.
현대 분산 시스템에서 외부 API 호출이나 타 시스템 연동이 빈번해지면서, 장애 전파를 방지하기 위한 Circuit Breaker 패턴의 중요성이 점점 커지고 있다. 특히 여러 인스턴스가 동시에 운영되는 환경에서는 분산 상태 공유가 가능한 구조가 필수다. 본 포스팅에서는 Redis 기반 분산 Circuit Breaker 구현을 중심으로, Kotlin + Coroutine 환경에서 안전하게 사용하는 방식을 소개한다.
Here is docker-compose.yml file and redis.conf
We need to create conf files for each node with same port but different cluster-announce-port and redis-cli -h localhost -p 26380 -a secret.
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 3000
cluster-announce-ip [host IP]
cluster-announce-port 26379
cluster-announce-bus-port 17000
appendonly yes
requirepass secret
masterauth secret
version: "3.9"
services:
# for debugging to use ping nslookup and etc.
debug-busybox:
image: busybox
command: sleep 3600
networks:
- sample-app
redis-node-1:
image: redis:7.2
container_name: redis-node-1
volumes:
- ./redis-data/node1/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26379:6379"
- "17000:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-node-2:
image: redis:7.2
container_name: redis-node-2
volumes:
- ./redis-data/node2/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26380:6379"
- "17001:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-node-3:
image: redis:7.2
container_name: redis-node-3
volumes:
- ./redis-data/node3/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26381:6379"
- "17002:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-node-4:
image: redis:7.2
container_name: redis-node-4
volumes:
- ./redis-data/node4/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26382:6379"
- "17003:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-node-5:
image: redis:7.2
container_name: redis-node-5
volumes:
- ./redis-data/node5/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26383:6379"
- "17004:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-node-6:
image: redis:7.2
container_name: redis-node-6
volumes:
- ./redis-data/node6/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "26384:6379"
- "17005:16379"
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
redis-cluster-init:
image: redis:7.2
container_name: redis-cluster-init
depends_on:
- redis-node-1
- redis-node-2
- redis-node-3
- redis-node-4
- redis-node-5
- redis-node-6
entrypoint: [ "bash", "-c" ]
command:
- >
sleep 5 &&
echo yes | redis-cli -a secret --cluster create
host.docker.internal:26379
host.docker.internal:26380
host.docker.internal:26381
host.docker.internal:26382
host.docker.internal:26383
host.docker.internal:26384
--cluster-replicas 1
networks:
- sample-app
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
sample-app:
driver: bridge
Ok, it's time to run and moment of truth. Run following commands.
docker-compose -f docker-compose.yml up -d
If there is any error during containers are up and running, then you can run following command to connect one of redis node container.
redis-cli -h localhost -p 26380 -a secret