처리량
bsr의 처리량 최적화에 관한 몇 가지 하드웨어 고려 사항과 튜닝 항목들에 대해 살펴보겠습니다.
하드웨어
bsr의 처리능력은 시스템 내의 하위 I/O 서브시스템(디스크, 컨트롤러, 그리고 캐시)과 네트워크 대역폭의 영향을 받습니다.
I/O 서브 시스템
I/O 서브시스템의 처리 능력은 병렬로 구성된 디스크의 수에 의해 결정됩니다. 최근의 SCSI 나 SAS 디스크는 일반적으로 하나의 디스크에 약 40MB/s의 쓰기 스트리밍을 할 수 있습니다. 스트라이프(striped) 구성일 경우에는 디스크를 분산해서 병렬로 I/O 를 기록하므로 처리 속도도 디스크 개수만큼 배수로 증가할 수 있습니다. 가령, 40MB/s 디스크를 RAID-0 또는 RAID-1+0 구성으로 3개를 사용할 경우는 120MB/s, 5개일 경우에는 200MB/s의 처리 속도를 기대할 수 있습니다.
일반적으로 미러링(RAID-1) 방식은 처리 속도 향상에 거의 영향을 주지 않습니다. RAID-5 방식은 처리 속도를 향상시켜 주지만 스트라이핑에 비해서는 다소 느린 편입니다.
네트워크
네트워크 처리량은 일반적으로 트래픽의 양과 네트워크 인프라(routing/switching) 장비에 의해 결정됩니다. 하지만 일반적으로 bsr을 위한 복제 링크는 전용선을 사용하기 때문에 이런 환경 조건들과는 크게 관련이 없습니다. 따라서 네트워크 처리량은 higher-throughput 전송대역(10 Gigabit Ethernet처럼)으로 전환하거나, 본딩 네트워크 드라이버 같은 복수의 링크를 통해서 향상시킬 수 있습니다.
처리속도 추정
위 에서 설명한 바와 같이 처리 속도를 추정하기 위해 I/O 서브시스템과 네트워크 대역폭에 대해 고려하여 추정합니다.
이론적으로는 두 요소의 각각의 최대값 중에서 최소값을 최대 처리 속도로 추정할 수 있으며, 이 값에 오버헤드를 약 3% 정도로 가정해서 추산합니다.
200MB/s 처리 능력이 있는 I/O 서브시스템에서 기가 비트 이더넷이 연결된 클러스터 노드를 가정해 봅시다. 기가 비트 이더넷의 TCP 연결은 110MB/s 처리 속도를 제공한다고 가정하고, 네트워크의 병목현상을 감안해 3% 정도를 낮춰서 대략 107MB/s의 최대 처리 속도를 기대할 수 있습니다.
또한, I/O 서브시스템에서 100MB/s의 처리 능력이 제공된다고 했을 때 이곳에서의 병목현상까지 감안하여 bsr의 최대 처리 속도는 전체 97MB/s까지 기대할 수 있습니다.
처리량 최적화 튜닝
bsr의 성능에 영향을 줄 수 있는 몇 가지 구성 옵션 들 중 몇 가지 권장할 만한 사항들을 소개합니다. 하지만 성능은 하드웨어에 크게 좌우되기 때문에 여기서 설명한 옵션들을 조정한 효과는 시스템마다 다를 수 있습니다. 따라서 이러한 권장사항들이 모든 성능 병목을 해결해주는 절대적인 요소는 아닙니다.
req-buf-size
Primary 노드의 I/O request 버퍼 큐(req-buf)의 최대 크기를 지정합니다. 이 버퍼는 로컬 디스크로 I/O 가 발생되면 해당 I/O 를 1차적으로 큐잉하기 위한 장소로서 TCP 송신버퍼로 I/O Request 가 넘겨지기 이전 시점에 1차 버퍼링을 위한 용도로 사용됩니다.
복제가 원할한 보통의 경우에는 req-buf 가 혼잡상황(full)에 놓일 일이 거의 없지만 어떤 요인으로 인해 시스템의 부하가 커질 경우 복제 처리가 지연 될 수 있고 req-buf가 full 이 될 가능성이 있습니다.(이 정도의 복제 지연과 부하에 놓인 상태라면 ack 지연으로 인한 복제연결 단절이 발생할 수도 있습니다.) 이러한 상황에 대비하기 위해 req-buf 를 여유있게 설정할 필요가 있습니다. 기본값은 리소스 당 100MB 입니다.
max-buffers
max-buffers는 타깃의 디스크에 데이터를 쓰기 위해 할당된 peer request 버퍼의 최대 수로 secondary 노드의 쓰기 성능에 영향을 줍니다. 기본값은 16000이고 약 8000 정도면 대부분의 하드웨어 RAID 컨트롤러에서 좋은 성능을 냅니다.
max-buffers 값은 최소한 max-epoch-size 값보다 크거나 같아야 합니다.
resource <resource> { net { max-buffers 8000; max-epoch-size 8000; ... } ... }
al-extents
bsr 을 사용하는 응용 프로그램이 쓰기 위주이고 작은 크기의 쓰기가 자주 발생하는 환경이라면 메타디스크의 액티비티 로그(AL) 크기를 여유 있게 구성하는 것이 좋습니다. 그렇지 않으면 메타데이터 업데이트가 자주 발생하여 쓰기 성능이 저하될 수 있습니다. 다음은 AL 크기를 65001 로 확장하는 예 입니다.
>bsradm create-md --al-stripe-size-kB 288 r0 ... >bsradm dump-md r0 ... al-stripe-size-4k 72; ...
al-extents 와 congestion-extents 를 지정합니다.
resource <resource> { disk { al-extents 65001; ... } net { congestion-extents 58501; # 90% of the al-extents } }
sndbuf-size
송신버퍼는 버퍼링을 통해 전송량 최적화를 구현합니다. TCP/IP 전송은 ACK 기반의 프로토콜이기 때문에 세그먼트가 분할되어 전송될 수록 프로토콜 오버헤드가 커집니다. 따라서 네트워크 전송 관점에서는 데이터를 보낼 때 되도록 한번에 많이 모아서 보내는게 유리합니다. 송신버퍼는 바로 이 부분을 구현하고 있기 때문에 자연스럽게 최적화를 달성할 수 있습니다. 특히 작은 단위의 데이터가 지속 전송되는 상황에서 데이터를 송신버퍼 큐에 일정 정도 모아두고 보냄으로써 전송량을 크게 향상시킬 수 있습니다. 다음과 같은 상황일 경우 sndbuf-size 를 통한 최적화를 고려해야 합니다.
복제 대상 파일들이 작은 단위 파일들로 많이 분할되어 있어서 복제 I/O 자체가 4KB ~ 8KB 수준의 작은 단위의 I/O로 발생되는 경우
작은 검사 단위로 온라인 정합성 검사를 수행할 경우
지연시간
bsr의 지연시간(latency) 최적화에 대해 다룹니다. 지연시간을 최소화하기 위해 하드웨어 측면에서 검토하고 몇 가지 설정 옵션을 살펴보겠습니다.
하드웨어
bsr의 수행 시간은 기본 I/O 서브시스템(디스크, 컨트롤러 그리고 캐시)의 수행 시간 및 네트워크의 처리시간에 영향을 받습니다.
I/O 서브 시스템
I/O 서브시스템의 수행 시간은 주로 디스크의 회전속도(RPM)에 의해 정해집니다. 따라서 RPM이 더 빠른 디스크를 사용하는 것이 수행 시간을 개선할 수 있는 올바른 접근 방법입니다.
마찬가지로 배터리 장착 쓰기 캐시(battery-backed write cache-BBWC)를 사용하는 경우도 쓰기시간을 줄일 수 있습니다. 최근 대부분의 스토리지 장비에서는 이런 캐시가 장착되어 있고 읽기 쓰기 캐시 비율을 관리자가 설정할 수 있습니다. 쓰기 I/O의 성능을 높이려면 읽기 캐시를 없애고 쓰기 캐시에 모두 사용할 것을 권장합니다.
네트워크
네트워크 수행 시간은 본질적으로 패킷이 호스트에서 호스트까지 왕복하는 데 걸리는 시간(RTT)을 의미합니다. 여기에 영향을 줄 수 있는 요소들은 몇 가지가 있지만 전용선 환경에서는 이러한 요소에 거의 영향을 받지 않으므로 복제 회선은 직접(back-to-back) 연결된 네트워크를 사용하는 것이 좋습니다. 이처럼 일정한 병목이 유지되는 환경에서 기가비트 이더넷을 사용한다면 지연시간은 일반적으로 100~ 200 microseconds (μs) 패킷 RTT 정도가 될 것입니다.
지연시간 추정
처리량과 연계된 지연시간을 추정할 때, 몇 가지 고려해야 할 중요한 제약 사항이 있습니다.
지연시간은 RAW I/O 서브 시스템 성능과 가용한 네트워크 병목시간의 범주 내에 있습니다.
이 두 시간의 합이 이론상으로는 bsr에 영향을 주는 최소의 지연시간이 됩니다. 그리고 여기에 1% 보다 작은 값을 조금 더 추가시킵니다. 예를 들어 로컬 디스크의 지연시간이 3ms이며 네트워크 지연이 0.2ms인 경우, 예상되는 bsr의 지연시간은 3.2ms입니다. 그냥 로컬 디스크에 쓰는 것보다 지연시간이 약 7% 증가하게 됩니다. 지연시간은 CPU 캐시 미스, 컨텍스트 스위칭(Context Switching)등의 몇 가지 다른 요소들에 의해서도 영향을 받습니다.
지연시간 최적화 튜닝
지연시간 측면의 튜닝을 고려해볼 만한 요소는 네트워크 프로토콜이나 전송 계층에서 부가적으로 제공하는 특수한 기능들 입니다. 이러한 기능들은 네트워크 전반의 성능을 높이기 위해 써드파티 벤더나 OS 구성요소 등에 의해 제공되는 기능이지만 지연시간 측면에서는 성능에 안 좋은 영향을 줄 수도 있습니다. 예를 들어, TCP 에서 제공하는 Delayed ACK Time, MTU 크기, NIC 계층에서 제공하는 점보패킷, LSO(Large Send Offload) 등의 기능들이 있는데 이 기능들은 보통 시스템에서 기본 활성화 되어 있어서 복제 데이터가 송신되거나 수신되는 계층에서 직간접적으로 연관됩니다.
만약 복제 성능이 예기치 않게 낮게 나온다면 다른 문제로 해결하지 못할 경우 이 기능들을 비활성화 해볼 필요가 있습니다.
Disable TCP Delayed ACK
특히 Windows 에서 TCP의 기본 속성인 지연 응답(Delayed ACK)은 전송 최적화에는 도움이 되지만 지연시간에는 나쁜 영향을 주기 때문에 수동으로 비활성화해 주어야 합니다. bsr 이 최초 설치될 때에는 이것을 설치과정 중에 자동 스크립트로 수행해 주지만 이후 랜카드 교체가 있을 경우에는 다시 이 작업을 수동으로 직접 수행해 주어야 합니다.
다음은 네트워크 인터페이스에서 이 옵션을 비활성화하는 명령이며 리소스 단위로 제어할 수 있습니다.
bsrcon /nodelayedack <resource> |
이 명령은 윈도우즈 전용명령이며 윈도우즈 레지스트리에 TCP 옵션값을 설정하고 네트워크 인터페이스에 해당 내용을 적용합니다. 이 옵션이 잘 적용되어 있는지 확인하려면 아래 경로의 레지스트리 내용을 확인하면 됩니다.
HKLM\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\{인터페이스 GUID}\
TcpAckFrequency(REG_DWORD) = 1
리눅스의 Delayed Ack 비활성화는 bsr 엔진의 코드 수준에서 구현합니다.
accelbuf-size
bsr 은 로컬 I/O 를 빠르게 완료 처리하기 위해 로컬 I/O 와 송신버퍼 사이의 위상에서 2중 버퍼링을 구현하고 이것을 가속버퍼라고 합니다.
가속버퍼는 로컬 I/O의 지연을 최적화할 목적으로 구현되었으며 특히 4KB 이하의 작은 단위의 I/O 에 대한 지연을 최적화 합니다.
resource <resource> { options { ... accelbuf-size 10M; } ... }