[입 개발] 한 서버에 하나의 Redis를 띄우시나요? 아니면 여러 대를 띄우시나요?

해당 블로그는 KT Olleh UCloud Biz의 지원을 받고 있습니다.

여러분은 하나의 서버에 Redis 인스턴스를 하나만 실행하시나요? 아니면 CPU Core 수나 메모리 양에 따라서 여러 개의 Redis 인스턴스를 실행시키시나요?

아마도 일반적으로는 하나의 서버에 하나의 Redis 인스턴스를 실행하는 경우가 많을 것 같지만, 아마도 다 각자의 기준이 있거나 또는, 그냥 실행시키지 않을까 싶기도 합니다.

오늘은 바로 이 이야기에 대해서 해볼려고 합니다.

일단 먼저, 어떤 방식을 선택해야 한다라는 정답은 없습니다. 다 잘쓰면 되지요.(퍽퍽퍽, 이 따위 소릴 할려고 소중한 내 시간을 뺐느냐? 라는 주먹들이 보이시는군요.) 그런데, 일단 끝까지 헛소리를 들으시고 그 뒤에 절(퍽퍽퍽… 들을 가치도 없어보인다는 말씀들이 덜덜덜)

일단 두 가지 경우의 장단점을 간단히 따져보면,

하나의 서버에 Redis 인스턴스를 하나만 실행하는 경우는 관리가 싶습니다. 그리고 행여나 다른 이슈로 인해서 해당 Redis 인스턴스가 영향을 받을 경우도 덜합니다.

하나의 서버에 여러개의 Redis 인스턴스를 실행하는 것은, 일단, Redis가 싱글스레드이기 때문에, 그래도 성능이 더 잘 나올 수 있습니다. 그리고, 여러 대의 서버를 써야 한다면, 하나의 서버 여러개를 관리하나, 여러 대의 서버에서 여러 개의 인스턴스를 사용하나 비슷할 가능성이 높습니다.

그럼, 일단 너는 어떤걸 권장하냐? 라고 물어보신다면, 적절히 잘 관리하면 어떤 방법이든 상관없지만, 개인적으로는 하나의 서버에 여러 대의 Redis 인스턴스를 사용하는 것을 추천합니다.

자 일단 예를 들어보겠습니다. 다음과 같은 서버 사양이 있다고 합니다.(KT UCloud 에서 해당 서버 목록을 가져왔습니다.)

*2vCore, 4G memory
*4vCore, 8G memory
*8vCore, 16G memory

위와 같은 사양에서 만약 한 서버에 하나의 Redis 인스턴스를 실행한다면, 어느정도 메모리를 사용할 경우, 메모리를 많이 사용한다고 할 수 있을가요?

그냥 제 맘대로 생각했을때, 3G, 6G, 13~14G 정도 사용하면 거의 맥시멈으로 사용한다라고 생각하지 않을까요? 이게 그냥 일반적인 생각일 것입니다. 그런데 만약 우리가 마스터/슬레이브 형태로 Redis 를 사용한다면, 여기서 문제가 하나 생길 수 있습니다. 슬레이브 노드가 마스터에 연결될 때, 마스터가 죽을 수도(도를 강조) 있다는 것입니다.

“왜” 라는 질문이 나오는 것이 정상일 것입니다. 그리고 죽을 수 있는 이유는 RDB 때문입니다. 여기서 “아!!!” 하시는 분과 “엥???” 하시는 분이 계실껍니다. 그럼 RDB 꺼두면 되는거 아니예요? 라고 물어보시는 분도 생길껍니다. 그런데… RDB 설정을 켜두든, 꺼두든… 이 문제는 발생할 수 있습니다.

이유를 살펴보면, Redis의 마스터/슬레이브 연결시에는 RDB 설정 여부에 상관없이 무조건 RDB를 생성하게 됩니다. 그리고 이 RDB 파일을 seed로 전송하고 그 뒤의 차이를 버퍼에 저장한 후에 이를 보내서 sync를 맞추게 되는데, 이 때, write가 많은 서버라면 메모리를 많이 사용해서 서버가 죽을 수도 있습니다. 처음 서비스 시작시에 슬레이브를 설정하면, 당연히 메모리 사용량이 얼마 안되니, 큰 문제가 없지만, 서비스로 인해서 메모리가 거의 풀로 찬 상황에서 슬레이브가 붙는다면, 문제의 소지가 있는 것이죠.

이 때문에, Core 수나 메모리에 따라서 적절히 Redis 인스턴스를 여러 개 띄워주는게 유리합니다. 즉, N개의 인스턴스를 실행한다면 (Memory-(운영체제필요메모리))/(N+1) 정도의 규칙으로 적절히 나누면(물론 Core 수도 중요합니다.) 하나의 인스턴스가 순간적으로 메모리를 많이 사용하더라도, 안정적으로 넘어갈 수 있습니다.(물론 이 때도 관리를 잘 해야합니다. 관리를 잘못하면… 한대든 여러대든 똑같은 이슈가…)

즉, 위와 같은 문제를 해결하기 위해서 하나의 서버에서 하나의 인스턴스만 실행하면, 16G 메모리라면, 최악을 대비해서 7G 정도만 사용해야 하지만… 여러 개의 인스턴스를 실행한다면 4G*3 개 정도의 인스턴스를 운영할 수 있습니다. 어차피 여러 대 관리해야 하면, 관리 이슈도 비슷하게 들테니까요.

여담이지만, Redis 나 이런 서버종류를 단순히 8G 서버 4대를 32G 서버 한대로 변경할 수 있는 것은 아닙니다. 컨넥션 수의 관리 때문에, 무조건 일정 대수 이상은 있어야 할 경우도 충분히 있습니다. 즉, 어느 것이 답이라는게 아니라, 어떤 것을 쓰든, 내부 구조를 잘 알아야 한다는게 오늘의 이야기입니다.

13 thoughts on “[입 개발] 한 서버에 하나의 Redis를 띄우시나요? 아니면 여러 대를 띄우시나요?

    • 그건 아니구요 메모리 32GB 머신에 레디스를 사용하실 때 32GB 통자로 하나만 띄우는지 16GB짜리를 프로세스 2개로 띄우는가 입니다. 다 마스터라고 볼때용

  1. 안녕하세요. 운좋게 redis책을 발견해서 읽고 redis를 Benchmark를 하고 있습니다. servere하게 Test를 하고 싶어 Client를 R710서버를 사용하고 taskset으로 각 코어에 redis-server를 돌렸습니다. 또한 Network 1GB짜리 2개를 bond0로 본딩해서 총 2GB/s로 네트워크가 잡혀있습니다. 그런데 client에서 redis-benchmark를 1개를 돌리던 2개를 돌리던 네트워크를 120MB/s 밖에 사용을 하지 않습니다. 그래서 redis.conf에 maxclients와 maxmemory를 높혔는데도 120MB/s그대로 인데 어떻게 하면 네트워크를 2GB/s를 충분히 사용하면서 테스트할 수 있을까요?

    • 안녕하세요. 질문이 있는데요. 클라이언트 물리 머신은 몇대인가요? 실제 클라이언트 자체의 한계도 있기 때문에, 한두대 더 클라이언트를 가지고 테스트 해보시는 것도 좋을듯 합니다.

  2. 서버와 클라이언트 둘다 ulimit 명령어를 써서 다 unlimited를 했는데도 120MB/s 밖에 네트워크를 안쓰네요. 혹시 제가 모르는 config파일이나 설정이 있는지 알려주시면 감사하겠습니다.

  3. 안녕하세요 항상 좋은글 잘 보고 공부 잘하고 있습니다.
    포스트내용이랑 조금 다른 질문이 될지 모르겠는데요.
    최근에 34기가 메모리에서 96기가로 레디스 메모리를 늘리면서 발생한 문제입니다 (그 전에도 있었을거 같은데 데이터 양이 작았을때 발생한 것이라 별 이상하게 생각 안하고 넘어갔습니다)

    총 4대 서버 에서 마스트1 슬레이브3 구성입니다.(물리서버)
    메모리를 늘리기 위해서 슬레이브 3대를 한대씩 떨어 뜨려 메모리 추가후 재기동 하고 풀 리싱크를 기다려 다음 서버 떨어뜨려서 대응으로 해서 슬레브재기동에는 별 문제 없었습니다.

    문제는 마스터서버에 메모리를 추가 하기 위해서 다운 시켰을때 (나중에 레디스 문서를 보고 이해 했지만) 한 슬레이브가 마스터가 되고 다른 슬레이브가 마스터의 pid가 바뀐것을 인식하고 전 슬레이브가 풀 리싱크를 개시….
    동시에 (rdb 사이즈는 6.3기가 정도 입니다.rss 20기가정도) 풀 리싱크를 개시 해서 레디스 서버가 있는 세그멘트 100M에서 빨리 처리 못하고 슬레이브가 마스터에서 rdb를 다 받았을때는 벌써 버퍼를 넘어서는 양이라서 다시 풀 리싱크…가 무한루프가 발생 했습니다.

    일단. 담배 한대 피고
    3대의 슬레이브 서버중에서 2대를 떨어뜨리고 1대가 마스터랑 완전 싱크한것을 확인 한후 한대씩 추가 해서 집에는 돌아 갈수 있었습니다..

    여기서 질문이 있습니다.
    마스터를 다운 시켜야 될 경우 위와 같이 풀 리싱크를 발생 안시키고 처리하는 방법이 있을까요?
    네트워크가 100M..라는게 엄청난 리스크라는 것은 알고 있습니다만.

    • @minsoojun 뭐, 현재는 방법이… 따로는 없습니다. parial sync 도 사실 그런 목적이 아니라서 T.T
      그런데 슬레이브를 1대 이상 쓰시는데가 많지가 있어서, 아니면…

      뭐, 테스트를 목적이시면
      https://github.com/charsyam/redis.git 여기의 psync_with_newmaster 브랜치를 한번 써보시는것도 쿨럭…
      (안전성 보장이 안되는…) 같은 목적으로 제가 수정해둔 것인데…. 저희 회사에서는 슬레이브를 하나만 써서 제대로 테스트가 안되는…

      주 내용은 마스터가 내려갔을때, 다른 슬레이브가 마스터가 되면… -_- 그 차이를 보고 큰 차이가 안나면, 그 차이만 받는 겁니다.
      흑흑흑, 아직 실 테스트가 많이 되지는 않아서 흑흑흑

      • charsyam
        답변 감사합니다.

        1 master 3 slave구성 한 이유가 write heavy가 발생하는 서비스라서 master는 쓰기 전용 slave 는 읽기 전용으로 하기 위해서 였습니다 (콘트롤 하는 라이벌리는jedis를 랍퍼 해서 만들었구요)
        저희 비즈네스 요구상 많은 읽기 리퀘스트도 발생해서 (여러 서비스에서 공통적으로 사용하는) slave를 3대로 구성 했는데 이 부분이 발목을 잡는 형태가 되어 버렸네요 ㅠ.ㅠ

        이넘의 클러스터 기능은 언제 안정판이 나올런지 ㅎㅎ.;1년반전에 곧 클러스트 기능이 나온다고 봐서 최대 4gb로 생각했던 데이터 확장을 허가 해서 현재 20기가까지 되어 버렸네요 (rdb 6.3gb)

        알려주신 부분은 흐흐 틈 봐서 살짝넣어서 테스트 해보고 FB바로 하겠습니다.

        바쁘신중에 답변 너무 감사합니다.
        이 막막한redis 환경에서 오아시스를 만나것 갔습니다 (몇년전 블러그를 첨 봤을때처럼)
        외..영어로 적혀있는 문서는 꼭꼭 찍어주는게 없을끼요 ㅎㅎ:)

  4. 지금은 링크가 생각이 안나는데, Maximum으로 쓰기위해서 대충 “(Core갯수/2)-1″ 개의 Redis를 띄우는 것이 효율 적이라고 하는 메일링을 본적이 있는데요.

    Core/2는 Redis당 1Core, IO에 1Core 로 분배해주기 위해서이고, OS에 1Core 정도로 여분을 주는 것이 좋다고 하네요. 클러스터링은 그 외의 논제라고 할때에요.

  5. 지금은 링크가 생각이 안나는데, Maximum으로 쓰기위해서 대충 “(Core갯수/2)-1″ 개의 Redis를 띄우는 것이 효율 적이라고 하는 메일링을 본적이 있는데요.

    Core/2는 Redis 데몬당 1Core, IO에 1Core 로 분배해주기 위해서이고, OS에 1Core 정도로 여분을 주는 것이 좋다고 하네요. 클러스터링은 그 외의 논제라고 할때에요…

    • 음… 개인적인 생각으로는 Redis는 Core/2까지가 크게 필요가 없다고 생각합니다. IO를 쓰게 될 경우는 거의 OS인데 OS용 코어를 할당하고, 그 뒤에는 RDB나 AOF Rewrite를 할 때나… CPU를 더 쓸꺼라서… ㅎㅎㅎ

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s