서비스 운영 중 발생한 Redis 관련 장애 Troubleshooting

김동욱·2024년 5월 9일
0

Troubleshooting

목록 보기
11/14
post-thumbnail

상황

실시간 서비스를 운영하는 상황에서 인증번호 번호 요청을 했지만 이메일을 확인해도 인증번호 관련 메일이 오지 않았다는 사용자의 제보를 받았다.

해결 방법

상황1

서버의 Redis 컨테이너 로그를 확인하던 중 아래의 에러를 발견했다.

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/celery/worker/worker.py", line 202, in start
    self.blueprint.start(self)
  File "/usr/local/lib/python3.9/site-packages/celery/bootsteps.py", line 116, in start
    step.start(parent)
  File "/usr/local/lib/python3.9/site-packages/celery/bootsteps.py", line 365, in start
    return self.obj.start()
  File "/usr/local/lib/python3.9/site-packages/celery/worker/consumer/consumer.py", line 340, in start
    blueprint.start(self)
  File "/usr/local/lib/python3.9/site-packages/celery/bootsteps.py", line 116, in start
    step.start(parent)
  File "/usr/local/lib/python3.9/site-packages/celery/worker/consumer/consumer.py", line 746, in start
    c.loop(*c.loop_args())
  File "/usr/local/lib/python3.9/site-packages/celery/worker/loops.py", line 97, in asynloop
    next(loop)
  File "/usr/local/lib/python3.9/site-packages/kombu/asynchronous/hub.py", line 373, in create_loop
    cb(*cbargs)
  File "/usr/local/lib/python3.9/site-packages/kombu/transport/redis.py", line 1344, in on_readable
    self.cycle.on_readable(fileno)
  File "/usr/local/lib/python3.9/site-packages/kombu/transport/redis.py", line 569, in on_readable
    chan.handlers[type]()
  File "/usr/local/lib/python3.9/site-packages/kombu/transport/redis.py", line 962, in _brpop_read
    dest__item = self.client.parse_response(self.client.connection,
  File "/usr/local/lib/python3.9/site-packages/redis/client.py", line 560, in parse_response
    response = connection.read_response()
  File "/usr/local/lib/python3.9/site-packages/redis/connection.py", line 536, in read_response
    raise response
redis.exceptions.ResponseError: UNBLOCKED force unblock from blocking operation, instance state changed (master -> replica?)

backend 컨테이너에서 실행 중인 Celery가 Redis 컨테이너와의 연결에서 발생한 문제로 인해 작동을 멈췄다. 에러 문구의 마지막에 인스턴스 상태 변경(마스터 -> 복제본)을 의심하는 문구가 있다. 따로 replication 설정은 하지 않았다. 아래의 명령어로 확인할 수 있다.

Celery와 Redis 간의 연결이 끊어졌을 때 재시도 하여 다시 연결할 수 있도록 설정을 추가했다. 설정 파일에 다음의 설정을 추가했다.

CELERY_BROKER_TRANSPORT_OPTIONS = {
    "max_retries": 5,
    "interval_start": 0,  # 첫 번째 재시도를 즉시 수행
    "interval_step": 0.2,  # 이후 각 재시도 간격을 200ms씩 증가
    "interval_max": 0.5,  # 재시도 간격이 0.5초를 넘지 않도록 설정
}

또한 기존에 Django와 Celery를 동일한 컨테이너에서 실행 시켰는데, 자원 관리, 장애 격리, 디버깅 편의성 등의 이유로 각각의 컨테이너로 분리했다.

결과1

약 5시간 후 서비스 접속이 안되어 ssh 접속을 시도했는데 접속이 안됐다. 사용량이 많지 않은 서비스라 cpu와는 무관하고 Redis와 관련된 메모리 문제라고 판단했다.

상황2

ec2 프리티어 인스턴스의 적은 용량의 메모리로 인해 비슷한 상황의 문제글을 많이 찾아볼 수 있었다. 적은 용량의 메모리 때문에 Redis 컨테이너가 종료됐고, Celery가 Redis와 연결을 지속적으로 재시도하는 과정에서 서버에 과부하가 발생한 것으로 추청됐다.

실제로 재실행된 서버에서 Redis 컨테이너의 로그를 살펴보니 다음과 같은 로그가 있었다.

1:C 10 May 2024 01:25:13.411 # 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.
1:C 10 May 2024 01:25:13.411 # WARNING Your system is configured to use the 'xen' clocksource which might lead to degraded performance. Check the result of the [slow-clocksource] system check: run 'redis-server --check-system' to check if the system's clocksource isn't degrading performance.

로그의 경고문을 살펴보면 Redis가 메모리를 overcommit하지 않도록 설정되어 있어, 메모리 부족 상황에서 문제가 발생할 수 있다고 한다. 이를 해결하려면 vm.overcommit_memory 설정을 변경해야 한다.

결과2

vm.overcommit_memory를 설정하여 메모리 오버커밋을 활성화했다. 다음의 명령어를 실행했다.

sudo sysctl vm.overcommit_memory=1

그리고 /etc/sysctl.conf 파일에 다음 줄을 추가하여 인스턴스 재부팅을 했다.

vm.overcommit_memory = 1
profile
안녕하세요! 질문과 피드백은 언제든지 환영입니다:)

0개의 댓글