카카오 "레디스, 잘못쓰면 망한다"

일반입력 :2013/11/19 17:51    수정: 2013/11/20 13:50

국민메신저 카카오톡 개발 업체인 카카오가 웹애플리케이션 서비스를 만드는 개발자들을 대상으로 오픈소스 기술 '레디스(Redis)' 활용 경험을 소개했다. 우수 활용사례가 아니라 절대 하면 안 되는 작업들을 열거하며 주의를 당부해 눈길을 끈다.

레디스는 인메모리에서 돌아가는 NoSQL 데이터베이스(DB)로 '멤캐시드'와 경쟁구도를 그려 왔다. 카카오뿐아니라 트위터, 페이스북, 인스타그램, 네이버 등 유명 인터넷 업체들이 사용자들의 대규모 메시지를 실시간으로 처리하기 위해 레디스를 사용 중인 것으로 알려졌다.

19일 서울 잠실 롯데호텔 '제10회 ACC' 현장에 '레디스 운영관리와 분산 설계'를 주제로 발표를 맡은 카카오 소프트웨어 엔지니어 강대명 씨는 자신을 '카카오 홈 개발자'라 소개하며 레디스가 좋은 기술이라는 건 (개발자들 사이에서) 다 아는 얘기라며 뭐가 좋다는 얘기 대신 최악의 사례가 될만한 사용법을 공유해 서비스 설계시 이를 피할 수 있도록 돕겠다고 운을 뗐다.

강 씨가 밝힌 레디스의 특징은 '싱글 쓰레드'라는 점이다. 싱글 쓰레드는 1번에 1개의 명령어만 실행할 수 있다. 한 서비스에서 요청된 명령어에 대한 작업이 끝나기 전까진 다른 서비스에서 요청하는 명령을 못 받아들인다. 이 특성 때문에 레디스로 웹서비스를 관리할 경우 절대 쓰면 안 되는 명령어들이 몇 가지 있다고 한다. 저장된 모든 키를 보여주는 명령어(keys)나 모든 데이터를 소거하는 명령어(flushall) 등이다.

강 씨는 모든 키를 보여주거나 플러싱하는 명령어는 테스트 환경이나 소량의 데이터를 관리하는 시스템에서 모니터링하는 용도로만 써야 한다며 실행 대상을 전수처리하기 때문에 점차 데이터를 쌓아가는 환경에서는 운영에 차질을 빚을 정도로 속도가 느려질 것이라고 경고했다.

이어 빠른 속도로 플러시라는 명령어를 지원하는 멤캐시드 때문에 사람들이 레디스에서도 이 명령어가 금방 처리될 거라 기대하기도 하는데 실제 작동하는 방식이 완전히 다르다며 이 명령어 수행 시간을 재 보면 멤캐시드는 항상 일정하게 1~2ms가 나오는데 레디스는 데이터 100만건 정도 기준으로 1초(1천ms)로 이미 훨씬 느리다, 이건 실패한 사용법이라고 지적했다.

그에 따르면 레디스는 인메모리DB라 빠른 속도가 강점이지만 큰 용량의 데이터를 담기엔 공간 제약이 크다. 그래서 실시간 처리는 인메모리에서, 보관은 디스크 기반 스토리지로 하는 구조가 성능과 효율을 함께 달성할 수 있다. 트위터, 인스타그램, 페이스북처럼 대규모 사용자 기반을 갖춘 인터넷 서비스 업체들도 이런 식으로 서비스를 설계했다는 설명이다.

강 씨는 용량 측면에서의 주의점도 짚었다. 레디스는 32비트 환경에선 최대 3GB 메모리만 사용 가능하고 64비트 시스템에서는 그런 제약이 없어 운영체제(OS)의 가상메모리(스왑)까지 쓴다. 하지만 이 경우 시스템의 메모리 한계를 인식하지 못해 더 많은 메모리를 요구하다가 문제를 일으킬 수 있어 관리자가 따로 설정을 더해줘야 한다.

강 씨는 또 레디스는 멤캐시드에서 지원 안 하는 명령어 '콜렉션'을 지원하지만 앞서 '플러시올'이나 '키즈'같이 싱글쓰레드 방식에서 쓰지 말아야 하는 기능에 해당한다며 콜렉션에 데이터 100만건을 넣으면 처리시간이 10초, 1천만건 넣으면 100초씩 걸리는 식으로 늘어나기 때문에 굳이 쓰려면 일단 데이터를 1만건 미만으로 관리해야 한다고 권고했다.

이어 레디스에서 디스크에 메모리 상태를 그대로 받아 저장하는(메모리스냅숏) RDB 기능이 레디스 서버 장애요인 99.9%를 차지한다며 원한다면 이 기능을 그냥 꺼 둘 수 있다고 말했다.

설명에 따르면 아마존 웹서비스 서버 기준으로 60GB짜리 메모리 서버 테스트시 RDB 작업에 10분 정도가 걸린다. 싱글쓰레드 문제를 겪지 않기 위해 'Fork()'라는 분기 기능을 쓸 수 있지만 이 경우 메모리를 2배로 잡아먹어, 용량부족에 따른 오류와 원인을 알수 없는 장애를 낼 수 있다. 이어지는 효과로, RDB 작업이 실패하면 '쓰기 거부' 상태가 돼 추가 장애를 낼 수 있다.

강 씨는 레디스 시스템을 적용한 국내 기업들이 RDB 사용으로 인해 실제 장애를 겪은 사례들을 언급하며 구체적인 장애 상황과 그 상태를 파악하려 할 때 주의해야 할 사항 등을 추가로 설명했다. RDB 설정을 해제하는 방법과, 서비스 정책 설정값을 통해 실패시 동작을 보정하는 요령도 제시했다.

현장에선 앞서 싱글쓰레드라는 특성 때문에 실무 환경에서 사용시 문제가 될 수 있는 또 다른 명령어 AOF와 그로 인한 문제 사례도 소개됐다. 메모리상의 정보를 디스크에 저장한다는 점은 RDB와 비슷하나, AOF는 레디스 프로토콜로 통신한 내용들을 명령어, 키, 이름 등 형식 그대로 저장한다는 점이 다르다. 다만 RDB 사용시 주의사항은 AOF에도 동일하게 적용된다.

강 씨는 이밖에도 복제(리플리케이션) 시스템을 구성해 가용성을 높이는 방법에 대한 주의사항으로 레디스의 '마스터'와 '슬레이브'라는 개념과 관리 요령을 숙지하라고 당부했다.

레디스 시스템에서 슬레이브는 이름처럼 마스터의 데이터 저장을 보조한다. 마스터가 죽었다가 되살아날 때 자신의 정보를 모두 없애고 그 데이터를 그대로 베낀다. 별도 조치 없이 아무 데이터가 없는 마스터를 시스템에 연결하면 슬레이브에 남은 데이터를 마스터에 되살릴 수 없다는 점이 포인트다. 이를 피하려면 복구할 데이터를 가진 시스템에 '슬레이브오브노원'이라는 명령어를 줘서 그걸 마스터로 승격시켜야 한다.

카카오가 이 모든 레디스 분산환경에 대한 운영관리 요령을 엔지니어 개인에게 수작업으로 하게 하진 않는다. 장애시 복구를 위한 리플리케이션 작업을 '레디스센티넬'이라는 기술로 자동화할 수 있다. 하지만 레디스센티넬도 레디스 시스템만큼이나 사용시 주의사항이 많았다.

강 씨는 레디스센티넬은 레디스 시스템에서 마스터가 죽었다고 판단시 다른 슬레이브를 마스터로 승격하고 사용자측에 마스터가 바뀌었다는 알림을 보내는 도구인데, 사실 미성숙한 기술인 것 같고 적당한 대안도 없다며 레디스가 살았는지 판단하는 몇가지 단계(네트워크 단절, 주관적 다운, 객관적 다운)를 거쳐 페일오버(장애시 정상시스템으로 전환)를 수행한다고 설명했다.

그는 이후 레디스센티넬을 사용해 레디스 환경에서 마스터와 슬레이브를 지정하는 방식, 우선순위 결정 원리, 실제 서비스 운영 환경에서 페일오버를 수행하기 위한 적정 설정값, 레디스 프로젝트에서 진행되고 있는 레디스센티넬 기술에 대한 개선 작업 현황, 하둡 인프라에서 레디스같은 역할을 하는 '주키퍼'와 함께 동작시 설정 요령 등을 차례로 언급했다.

강 씨는 이런 얘기들을 전하면 (개발자들이) '레디스를 아예 쓰지말라는거 아니냐' 하는데, 이걸 알면 모르는 것보다 더 잘 쓸 수 있게 된다고 거듭 말했다. 그는 세션 후반부에 레디스에 걸리는 부하를 분산시키고 가용성을 보완하는 기술로 트위터에서 만든 '티웸프록시'와 페이스북 메신저 시스템에 적용된 '샤딩' 시스템 구성 요령을 소개했다.

티웸프록시는 클라이언트에서 데이터가 들어오면 해싱값을 만들어 여러대의 레디스 서버에 나눠주는 역할이다. 서버당 1개의 커넥션을 만들기 때문에 속도가 빠르고 보안상 안전하며 부하를 줄일 수 있다. 레디스센티넬과 묶어 고가용성(HA) 구성도 가능하다. 레디스처럼 싱글스레드 기반이란 문제는 동일하게 나타난다. 또 키 세트가 여러 서버로 분산돼 레디스 서버 전체 데이터를 다루던 명령어 효과가 반감되는 단점도 있다.

한편 강 씨는 페이스북메신저에 구성돼 있다는 '셀 아키텍처'에 대해서도 언급했다. 전체 인프라가 각각 독립된 하드웨어(HW)로 구성되는 셀로 나뉘는 것으로 장애를 분산시킬 수 있다는 장점이 있다는 설명이었다.

관련기사

기본적으로 셀 안에 장애시 정상시스템으로 전환하는 설계구조도 필요하긴 하지만, 샤딩은 여러 데이터센터에 서비스를 나눠 운영하는 것이라 재해 발생에 따른 서비스 장애 범위를 줄일 수 있는 역할로 묘사됐다.

강 씨는 셀 아키텍처의 단점으로 독립적인 장비 인프라를 셀마다 풀세트로 갖춰야 하기 때문에 서비스 구성에 따른 비용 부담이 크다고 언급했다.