최근 서버에서 redis 관련한 이슈가 몇번 나왔었다.
우리 서비스의 redis는 사내의 쿠브플로우 온프레미스 서버에 레플리카셋으로 올라가있는데(sentinel은 안 쓰는 상태),
개발 api 서버에서는 strict하게 master의 url만 사용했다. 이 때문에 인터넷이 끊기는 등 redis에 이상이 생겨서 기존 master가 slave로 전향해버리면 set이나 incr, expire 등의 명령어가 적용되지 않았다. 일반적으로 slave replica는 readonly 상태이므로 삽입이 불가능하기 때문이다.
때문에 프로덕션 환경 redis에 sentinel이 적용되었고, 개인 로컬 환경도 sentinel을 사용할 필요성이 생겼다.
local 환경은 대충 가볍게 써서 이런 정도만 나오게 되었다.
global:
redis:
password: "0073"
architecture: replication
auth:
enabled: true
sentinel: true
replica:
replicaCount: 3
containerPorts:
redis: 6379
sentinel:
enabled: true
automateClusterRecovery: true
...라고 했더니 이미지를 띄운 후 서버를 동작시키자 redis에 달아둔 이벤트 리스너에서 에러가 마구 떨어졌다.
문제는 connection 자체는 성공하면서도(왜냐하면 실질적인 master에 접근하는 로직이 listener에 안 달려있기 때문에) 런타임에서 redis를 참조하는 부분이 하나라도 생기면 이렇게 에러를 뱉는 것이었다.
[2022-09-19T14:24:29+09:00] error (RedisConnectionProvider) Redis got Error :: All sentinels are unreachable. Retrying from scratch after 300ms. Last error: ERR unknown command `sentinel`, with args beginning with: `get-master-addr-by-name`, `mymaster`,
[2022-09-19T14:24:29+09:00] error (RedisConnectionProvider) Redis got Error :: All sentinels are unreachable. Retrying from scratch after 600ms. Last error: ERR unknown command `sentinel`, with args beginning with: `get-master-addr-by-name`, `mymaster`,
[2022-09-19T14:24:29+09:00] error (RedisConnectionProvider) Redis got Error :: All sentinels are unreachable. Retrying from scratch after 900ms. Last error: ERR unknown command `sentinel`, with args beginning with: `get-master-addr-by-name`, `mymaster`,
[2022-09-19T14:24:30+09:00] error (RedisConnectionProvider) Redis got Error :: All sentinels are unreachable. Retrying from scratch after 1200ms. Last error: ERR unknown command `sentinel`, with args beginning with: `get-master-addr-by-name`, `mymaster`,
(허엉ㅠㅠ)
말인즉슨 sentinel에 접근할 수 없다는 건데, 의구심이 들어서 redis-cli로 접근해 info sentinel
명령을 내려봤다.
localhost:0>info sentinel
""
원래 info sentinel의 일반적인 응답은 여기에서 보듯이 리스팅이 되어야하는데 안 되고 있었다.
그래서 우선 로그를 살펴봤다.
> kubectl logs -f redis-node-0 sentinel
09:03:15.06 INFO ==> about to run the command: REDISCLI_AUTH=$REDIS_PASSWORD timeout 5 redis-cli -h redis.default.svc.cluster.local -p 26379 sentinel get-master-addr-by-name mymaster
Could not connect to Redis at redis.default.svc.cluster.local:26379: Connection refused
1:X 19 Sep 2022 09:03:15.071 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 19 Sep 2022 09:03:15.071 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 19 Sep 2022 09:03:15.071 # Configuration loaded
1:X 19 Sep 2022 09:03:15.071 * monotonic clock: POSIX clock_gettime
1:X 19 Sep 2022 09:03:15.072 * Running mode=sentinel, port=26379.
1:X 19 Sep 2022 09:03:15.072 # Sentinel ID is 2a09ba7abbb41ee71e79087310d75f9809c3c815
1:X 19 Sep 2022 09:03:15.072 # +monitor master mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379 quorum 2
1:X 19 Sep 2022 09:03:45.250 * +slave slave redis-node-1.redis-headless.default.svc.cluster.local:6379 redis-node-1.redis-headless.default.svc.cluster.local 6379 @ mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379
1:X 19 Sep 2022 09:03:46.239 * +sentinel sentinel 33535e4e17bf8f9f9ff9ce8f9ddf609e558ff4f2 redis-node-1.redis-headless.default.svc.cluster.local 26379 @ mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379
1:X 19 Sep 2022 09:04:35.515 * +slave slave redis-node-2.redis-headless.default.svc.cluster.local:6379 redis-node-2.redis-headless.default.svc.cluster.local 6379 @ mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379
1:X 19 Sep 2022 09:04:35.607 * +sentinel sentinel 9fe32540b27937ed9f341b0f610a0d8df405bb63 redis-node-2.redis-headless.default.svc.cluster.local 26379 @ mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379
Could not connect to Redis at redis.default.svc.cluster.local:26379: Connection refused
라는 문구가 나타났다.
2번은 어떨까?
> kubectl logs -f redis-node-2 sentinel
09:04:05.08 INFO ==> about to run the command: REDISCLI_AUTH=$REDIS_PASSWORD timeout 5 redis-cli -h redis.default.svc.cluster.local -p 26379 sentinel get-master-addr-by-name mymaster
redis-node-0.redis-headless.default.svc.cluster.local
6379
09:04:05.08 INFO ==> about to run the command: REDISCLI_AUTH=$REDIS_PASSWORD timeout 5 redis-cli -h redis.default.svc.cluster.local -p 26379 sentinel get-master-addr-by-name mymaster
09:04:05.08 INFO ==> printing REDIS_SENTINEL_INFO=(redis-node-0.redis-headless.default.svc.cluster.local,6379)
1:X 19 Sep 2022 09:04:05.108 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 19 Sep 2022 09:04:05.108 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 19 Sep 2022 09:04:05.108 # Configuration loaded
1:X 19 Sep 2022 09:04:05.108 * monotonic clock: POSIX clock_gettime
1:X 19 Sep 2022 09:04:05.108 * Running mode=sentinel, port=26379.
1:X 19 Sep 2022 09:04:05.109 # Sentinel ID is 9fe32540b27937ed9f341b0f610a0d8df405bb63
1:X 19 Sep 2022 09:04:05.109 # +monitor master mymaster redis-node-0.redis-headless.default.svc.cluster.local 6379 quorum 2
의외로 1번과 2번은 잘 연결이 되었다. 그러면 이제 자연스럽게 oO(그냥 0번을 재시작할까?) 라는 생각이 들 법 하다.
> kubectl get pod redis-node-0 -o yaml | kubectl replace --force -f-
pod "redis-node-0" deleted
그래서 삭제하고 다시 돌리는 방법을 쓰게 됐다.
저 명령어를 입력하면 파드가 삭제되고 자동으로 재실행된다.
kubectl logs -f redis-node-0 sentinel
09:14:24.12 INFO ==> about to run the command: REDISCLI_AUTH=$REDIS_PASSWORD timeout 5 redis-cli -h redis.default.svc.cluster.local -p 26379 sentinel get-master-addr-by-name mymaster
redis-node-2.redis-headless.default.svc.cluster.local
6379
09:14:24.12 INFO ==> about to run the command: REDISCLI_AUTH=$REDIS_PASSWORD timeout 5 redis-cli -h redis.default.svc.cluster.local -p 26379 sentinel get-master-addr-by-name mymaster
09:14:24.12 INFO ==> printing REDIS_SENTINEL_INFO=(redis-node-2.redis-headless.default.svc.cluster.local,6379)
1:X 19 Sep 2022 09:14:24.150 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 19 Sep 2022 09:14:24.150 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 19 Sep 2022 09:14:24.150 # Configuration loaded
1:X 19 Sep 2022 09:14:24.150 * monotonic clock: POSIX clock_gettime
1:X 19 Sep 2022 09:14:24.150 * Running mode=sentinel, port=26379.
1:X 19 Sep 2022 09:14:24.150 # Sentinel ID is 2a09ba7abbb41ee71e79087310d75f9809c3c815
1:X 19 Sep 2022 09:14:24.150 # +monitor master mymaster redis-node-2.redis-headless.default.svc.cluster.local 6379 quorum 2
1:X 19 Sep 2022 09:14:24.268 # +new-epoch 1
로그를 입력하니 잘 연결된 것처럼 보인다.
참고 자료
https://sup2is.github.io/2020/07/22/redis-replication-with-sentinel.html
https://fliedcat.tistory.com/186
'INFRA' 카테고리의 다른 글
gitlab runner 세팅 방법 (0) | 2024.09.27 |
---|---|
Kafka 프로듀서 데이터 가져오기 (0) | 2022.03.29 |