[혀로그래머 charsyam은 구라쟁이 Q&A] 레디스 관련 Q&A

안녕하세요. 혀로그래머 구라쟁이 charsyam 입니다. 오늘은 제가 자주 서식하는 페북 커뮤니티에 질문을 누군가 올려주셔서 거기에 대한 답변을 간단하게 달아놓은 것을… 질문이 워낙 좋으셔서… 정리해 봤습니다.

먼저 질문은 다음과 같습니다.

  1. 인프라 구조에서 Scale-Out 구조를 가진 경우 각 데이터를 어떤 Node에 저장되고 있는지를 판별하고 있어야 하며 데이터 유실을 대비하여 데이터 블럭을 보통 분리하여 저장합니다. 레디스의 경우 한 노드가 죽었을때 휘발성인 캐쉬임을 대비하여 어떤 방식을 구현하는지요?
  2. 본문에 사용량이 많아지면 메모리 파편화가 일어난다고 하였는데(보통 디스크나 메모리의 경우 영속성이 있어야 성능이 잘나오는걸로 알고 있습니다.) 해당 파편화를 줄이는 알고리즘이나 파편화가 일어난 경우 해당 데이터를 재배치를 하는건가요?
  3. 서버 아키텍처는 캐쉬의 경우 여러 종류의 캐쉬를 두어 각 캐쉬별 역할을 구분하게 되어지는데 레디스도 그런 방식을 차용하고 있는건가요?
  4. 이슈를 대비하여 서버 대수만 늘려야한다면 아키 설계가 어려울듯 한데 아키 설계는 보통 어떻게?
  5. 레디스 서버 한대 다운시 처리는 어케 하는지요

여기에 대한 답변을 다음과 같이 정리했습니다.

  1. 인프라 구조에서 Scale-Out 구조를 가진 경우 각 데이터를 어떤 Node에 저장되고 있는지를 판별하고 있어야 하며 데이터 유실을 대비하여 데이터 블럭을 보통 분리하여 저장합니다. 레디스의 경우 한 노드가 죽었을때 휘발성인 캐쉬임을 대비하여 어떤 방식을 구현하는지요?
    1. 글에서 언급한 것 처럼 그냥 버리는 케이스가 있습니다. 각 노드들에 데이터들이 날아가도 실제 DB에서 처리할 수 있는 정도라면… 예를 들어 한대 죽었을 때 10% 정도 부하가 올라가는데, 이 정도는 원래 처리할 수 있다면, 무시해도 되겠죠.
    2. 캐시도 중요할 경우 Master/Slave 로 레디스 같은 경우 설정해 둘 수 있습니다. 멤캐시는 이게 안되서, 따로 리플리케이션을 구현하셔야 합니다.(Mysql Binlog를 이용하든지, 서버 로직에서 두 군데를 쓰든지…)
  2. 본문에 사용량이 많아지면 메모리 파편화가 일어난다고 하였는데(보통 디스크나 메모리의 경우 영속성이 있어야 성능이 잘나오는걸로 알고 있습니다.) 해당 파편화를 줄이는 알고리즘이나 파편화가 일어난 경우 해당 데이터를 재배치를 하는건가요?
    1. 레디스의 메모리 파편화는 다른 장비로 이전하는 수 밖에 없습니다. 보통 메모리 파편화가, 잦은 메모리 할당과 해제로 인해서 발생하므로, 장비 이전을 하면, 삽입만 대량으로 발생하니, 단편화 이슈가 조금 덜합니다. 보통 이런 경우 메모리를 2배로 늘린 장비로 이전합니다. 이전 과정은 간단하지만, 모니터링이 필요합니다.
    2. 말씀하신것 처럼 해당 데이터를 재배치 하는 것은 현재 레디스 상황에서는 쉽지는 않습니다. 재배치를 해봐도, 메모리 상황이 바로 좋아지는 것이 아니라, jemalloc에서 내부적으로 관리하는 매커니즘과 섞여서, 좀 외부에서 알기 어렵습니다.
  3. 서버 아키텍처는 캐쉬의 경우 여러 종류의 캐쉬를 두어 각 캐쉬별 역할을 구분하게 되어지는데 레디스도 그런 방식을 차용하고 있는건가요?
    1. 레디스가 내부적으로 그렇게 나누는 것은 아니고, 캐시를 사용하는 비지니스 로직에서 보통은 종류를 나눠서 사용하는 것이 제 경험상 메모리 사용량이나 파편화면에서 유리했습니다.(보통 그렇게 많이 쓰구요.)
    2. 통합 캐시(그냥 다 때려박는 형태)의 경우는 아이템별 메모리 사이즈의 차이가 커서 파편화를 더 가속화 시키는 측면이 있습니다.
  4. 이슈를 대비하여 서버 대수만 늘려야한다면 아키 설계가 어려울듯 한데 아키 설계는 보통 어떻게?
    1. 클라우드냐, 자체 IDC냐에 따라서 고려해야 할 것들이 좀 바뀝니다. 일단, 공통적으로 서비스의 Configuration이 Dynamic 할 수 있어야 합니다. 뭘 쓰는지는 크게 중요하지 않지만, 서비스를 내리고 올리는 형태가 아니라, 특정 보드에 설정을 바꾸면, 그게 전체 서버에 자동으로 반영되서, 서비스를 중단하지 않을 수 있어야 합니다. 서버의 추가나 제거도 마찬가지 입니다.
    2. 그런 아키텍처가 구성이 되면, 이제 IDC냐 클라우드냐에 따라서 고민할 것이 네트웍 밴드위스와 상면의 이슈가 있습니다. 개발자 입장에서는 네트웍 스위치의 밴드위스를 고려하지 않는 경우가 있는데, 이럴 경우, 큰 문제를 일으킬 수 있습니다. 상면 위치도 마찬가지입니다. 미리 잘 고민 안하면, 장비가 추가가 안되서, 해당 캐시만 다른 IDC에 넣어야 하는 경우도…(레이턴시가…)
  5. 레디스 서버 한대 다운시 처리는 어케 하는지요
    1. 레디스 서버 한대 다운시는… 여러 가지 방법이 있습니다. 자동 failover를 원하시면 sentinel 을 쓰든지 자체로 간단한 agent 를 만들어서 하는 방법이 있습니다. 이걸 vip, dynamic dns랑 잘 활요하면 클라이언트 입장에서는 크게 신경을 쓰지 않게 auto failover 를 제공할 수도 있습니다.