현대 리눅스 배포판에서는 커널 매개변수가 잘 잡혀있지만 카프카 브로커의 특성에 맞게 설정을 튜닝한다면 성능을 더 끌어올릴 수 있다.

 

여기서는 가상 메모리와 네트워크 서브 시스템, 로그 세그먼트를 저장히기 위한 디스크 튜닝에 대해서 다룬다.

 

리눅스 커널 매개변수에 대한 자세한 사항을 보려면 리눅스 배포판의 문서를 참고하면 된다.

 

가상 메모리 설정:

  • 스와핑 (Swapping) 을 막는 것:
    • 처리량이 중요한 어플리케이션에서는 Swapping 을 막는 것이 도움을 줄 수 있다. 특히 카프카는 페이지 캐시에 있는 메모리를 많이 쓰기 때문에 스와핑을 할 경우 성능이 눈에 띄게 느려질 것이라서 이를 막도록 하는 것이 좋다.
    • 스와핑을 막는 방법은 스왑 영역을 아예 할당하지 않는 것도 있다. 이와 관련된 설정으로 vm.swappiness 이 있는데 0 에 가까울수록 스왑을 적극적으로 쓰지 않게 된다. 그러나 이 값은 0 으로 두는 것보다 1 로 두는 것이 더 낫다고 한다. 스왑 공간이 아예 없으면 운영체제에 의해 시스템은 강제 종료가 될 확률이 높아져서 안정성이 떨어지기 때문이다. 1 로 두게되면 스왑 공간을 남겨두면서도 최대한 물리 메모리를 쓰려고 하는 설정이라서 안정성과 성능을 모두 잡을 수 있다.

 

메모리 매핑 수 설정:

  • 메모리 매핑:
    • 파일의 메모리 매핑은 파일의 실제 데이터 내용을 메모리에 올려놓고 사용하기 위해서 필요하다.
    • 메모리 매핑은 디스크 I/O 작업을 최적화하여 파일 접근 속도를 향상시킬 수 있다. 파일 내용이 메모리에 직접 매핑되기 때문에, 파일 읽기/쓰기가 더 빨라질 수 있고, 필요한 파일의 부분만 메모리에 매핑함으로써 메모리 사용을 보다 효율적으로 사용할 수 있기 때문이다.
  • 카프카는 디스크 데이터를 페이지 캐시라는 커널 공간의 메모리에 올려놓고 사용하는데 이때 메모리 매핑이 사용된다. 카프카에서는 여러개의 디스크 데이터가 메모리에 올라와야 할 수 있는데, 하나의 프로세스당 디스크 데이터를 메모리에 올려놓을 수 있는 최대 개수는 vm.max_map_count 수에 따라서 결정된다. 그러므로 이 값을 증가 시켜야 할 수 있다. 이 값을 결정하는 변수로는 파티션의 수가 결정적일 것이고, 환경에 따라서 이 값은 400,000 ~ 600,000 정도로 설정할 수 있다.

 

파일 디스크립터 수 설정:

  • 브로커가 여러개의 파일을 관리하고, 여러개의 네트워크 연결을 맺는다면 파일 디스크립터의 수도 증가시켜줘야 할 수 있다.
  • 각 프로세스에서 파일 디스크립터의 수를 조절하려면 현재 쉘 세션에서 ulimit -Sn new_limit 을 통해서 늘려놓고 프로세스를 시작하면 된다.
  • 전체 프로세스에서 파일 디스크립터의 수를 늘리려면 /etc/sysctl.conf 파일을 편집해서 fs.file-max = new_limit 를 넣으면 된다.

 

파일 시스템 마운트 옵션 설정:

  • 파일 시스템 마운트의 개념:
    • 파일 시스템을 마운트한다는 것은 특정 저장 장치(예: 하드 드라이브, SSD, USB 드라이브)에 있는 파일 시스템을 운영 체제의 디렉토리 구조에 연결하는 것을 말한다.
    • 마운트 과정을 통해 사용자와 시스템은 해당 디스크의 파일과 디렉토리에 접근할 수 있게 된다. 즉 마운트되지 않은 저장 장치는 시스템에서 접근할 수 없다.
    • 마운트는 일반적으로 특정 "마운트 포인트"라고 하는 디렉토리에 연결된다. 예를 들어, 리눅스 시스템에서는 /mnt 또는 /media 디렉토리 하위에 새로운 저장 장치를 마운트할 수 있다. 마운트 포인트로부터 저장 장치 데이터에 접근할 수 있게 된다.
  • 파일 시스템 마운트 옵션으로 noatime 설정을 하는 것:
    • 파일 시스템에 있는 파일이나 디스크에 접근을 하게 되면 세 가지 타임 스탬프 값이 갱신될 수 있다.
      • 수정 시간(modification time, mtime), 변경 시간(change time, ctime), 그리고 접근 시간(access time, atime).
    • noatime 옵션을 사용하면, 파일 시스템은 파일이 읽힐 때 접근 시간(atime)을 갱신하지 않도록 할 수 있다. 이는 디스크 I/O를 줄여 성능을 향상시킬 수 있다.
      • 파일 수정을 하는 경우에나 수정 시간(modification time, mtime), 변경 시간(change time, ctime) 이 갱신되면서 Disk I/O 가 발생할 수 있다.
    • 현대 리눅스 시스템은 noatime 이 아닌 relatime 으로 설정되어 있는데 relatimeatime 을 모든 읽기 작업에서 업데이트하지 않고, 특정 조건에서만 업데이트한다. 기본적으로 atime 은 파일이 마지막으로 읽힌 이후 수정(mtime)이나 상태 변경(ctime)이 있었을 때, 또는 일정 시간(일반적으로 하루)이 지난 후에만 업데이트된다.
    • 그에 반해 noatime 옵션은 파일이 읽힐 때 접근 시간(atime)의 업데이트를 완전히 비활성화한다.
    • 카프카 브로커에서는 noatime 을 써도 문제 없다. 마지막 수정 이후의 접근 시간을 알 필요가 없기 때문임.

 

네트워크 설정:

  • 리눅스 커널은 기본적으로 대용량 데이터를 네트워크 통신하기에는 적합하게 설정되어 있지 않기 때문에 튜닝하는 것은 도움이 될 수 있다.
  • 소켓 송수신 버퍼 튜닝:
    • 이 버퍼는 TCP/UDP 와 같은 통신을 위해 사용하는 소켓의 버퍼를 말한다.
    • net.core.wmem_default 값과 net.core.rmem_default 값을 기본값이 아닌 128KB 정도로 설정하는 것이 좋다.
    • 송수신 버퍼의 최대 값은 net.core.wmem_maxnet.core.rmem_max 로 알 수 있는데 2MB 이다. 최대값이 항상 더 좋지는 않을 것이니 상황에 맞게 사용하자.
  • TCP 소켓 송수신 버퍼 튜닝:
    • TCP 소켓만 버퍼 튜닝을 하고 싶다면 net.ipv4.tcp_wmemnet.ipv4.tcp_rmem 을 설정하면 된다.이전에 소개한 net.core.rmem_default 는 TCP, UDP 모든 통신을 위해 사용하는 기본 소켓 버퍼 설정이다. 둘 다 같이 설정되어 있다면 net.ipv4.tcp_wmem 쪽이 우선적으로 적용된다.
    • 이 값은 그리고 (최소, 기본, 최대) 이렇게 3가지 값을 줘야한다. 최대 값으로는 net.core.wmem_maxnet.core.rmem_max 값을 넘을 수 없다.
  • TCP 윈도우 스케일링 기능 활성화:
    • TCP 헤더에서 윈도우 크기 필드가 16비트로 제한되어 있기 때문에 기존에 보낼 수 있는 최대 윈도우 사이즈는 65,535 바이트로 제한되어있다.
    • net.ipv4.tcp_window_scaling 을 통해서 이런 윈도우 사이즈 제한을 해제시킬 수 있다.
    • 윈도우 사이즈 최대 값은 65,535 × 2^14, 즉 약 1GB 될 수 있다. 여기서의 14 값은 스케일링 인자를 말하며 스케일링 인자의 최대 값이 14이다.
    • 현대의 리눅스 배포판은 기본적으로 net.ipv4.tcp_window_scaling 가 활성화 되어있다.
  • 브로커가 동시 받을 수 있는 연결의 수 증가:
    • net.ipv4.tcp_max_syn_backlog 설정을 통해 리눅스 시스템에서 TCP SYN 큐의 최대 크기를 결정할 수 있다.
    • 이 설정은 주로 서버가 동시에 처리할 수 있는 SYN(연결 요청) 수를 조절하는 데 사용된다.
    • 급증하는 트래픽으로 인해 연결의 수가 많아질 수 있는데 이에 대응하려면 net.ipv4.tcp_max_syn_backlog 수를 증가시키면 된다. 기본값은 1024인데 이것보다 늘려주자.

+ Recent posts