바메탈에 Pulsar 클러스터 배포하기
바메탈에 Pulsar 클러스터 배포하기
Docker나 클라우드 없이 직접 물리/가상 머신에 Pulsar 클러스터를 세우고 싶다면, 메타데이터 저장소부터 BookKeeper, 브로커까지 순서대로 배포해야 해요. 이 글에서는 바메탈에서 단일 클러스터를 배포하는 전체 과정을 안내해 드릴게요. ZooKeeper(또는 Oxia), BookKeeper bookie, Pulsar broker를 차례대로 구성하고 시작한 뒤 클라이언트로 연결을 확인하는 순서로 진행해요.
출처: 문서
본문
팁
- 대부분의 사용 사례(예: Pulsar 실험, 스타트업 또는 단일 팀에서의 사용)에서는 단일 클러스터 Pulsar 설치로 충분해요. 다중 클러스터 Pulsar 인스턴스를 실행해야 한다면 해당 가이드를 보세요.
- 모든 내장 Pulsar IO 커넥터를 사용하려면 apache-pulsar-io-connectors 패키지를 다운로드해 각 브로커 노드의 pulsar 디렉터리 아래 connectors 디렉터리(또는 Pulsar Functions용으로 별도의 function-worker 클러스터를 실행한다면 각 function-worker 노드)에 설치해야 해요.
- 배포에서 계층형 저장소(Tiered Storage) 기능을 사용하려면 apache-pulsar-offloaders 패키지를 다운로드해 각 브로커 노드의 Pulsar 디렉터리 아래 offloaders 디렉터리에 설치해야 해요. 이 기능 구성에 대한 자세한 내용은 계층형 저장소 쿡북을 참조하세요.
바메탈에 Pulsar 클러스터를 배포하는 것은 다음 단계로 구성돼요.
준비
요구 사항
현재 Pulsar는 64비트 macOS와 Linux에서 사용할 수 있어요. Windows에서 Pulsar를 실행하려면 Docker에서 Pulsar 실행을 보세요.
또한 적절한 64비트 JRE/JDK 버전을 설치해야 해요. Pulsar 런타임 Java 버전 권장을 참조하세요.
팁 기존 메타데이터 저장소(Oxia 또는 ZooKeeper) 클러스터를 재사용할 수 있어요.
바메탈에서 Pulsar를 실행하려면 다음 구성이 권장돼요:
- 최소 6대의 Linux 머신 또는 VM: 메타데이터 저장소 실행용 3대(Oxia 권장, 또는 ZooKeeper), Pulsar 브로커와 BookKeeper bookie 실행용 3대
- 모든 Pulsar 브로커 호스트를 아우르는 단일 DNS 이름(선택)
참고
- 브로커는 64비트 JVM에서만 지원돼요.
- 머신이 충분하지 않거나 클러스터 모드에서 Pulsar를 테스트하고 싶다면(그리고 나중에 클러스터를 확장하려면), ZooKeeper·bookie·broker가 모두 실행되는 노드 하나에 Pulsar를 완전히 배포할 수 있어요.
- DNS 서버가 없다면 서비스 URL에서 multi-host 형식을 대신 사용할 수 있어요.
- 클러스터의 각 머신에는 권장 Java 버전(예: Java 17)이 설치되어야 해요. 대상 Pulsar 버전에 맞춰 Pulsar 런타임 Java 버전 권장을 참조하세요.
다음은 기본 설정을 보여주는 다이어그램이에요.
이 다이어그램에서 연결하는 클라이언트는 단일 URL로 Pulsar 클러스터와 통신해야 해요. 이 경우 pulsar-cluster.acme.com이 모든 메시지 처리 브로커를 추상화해요. Pulsar 메시지 브로커는 BookKeeper bookie와 같은 머신에서 실행돼요. 브로커와 bookie는 다시 메타데이터 저장소에 의존해요.
하드웨어 고려 사항
Pulsar 클러스터를 배포할 때 용량 계획에서 다음 기본적인 더 나은 선택을 염두에 두세요.
ZooKeeper
ZooKeeper를 실행하는 머신에는 덜 강력한 머신이나 VM을 사용하는 것이 권장돼요. Pulsar는 기본 작업이 아니라 주기적인 조정·구성 관련 작업에만 ZooKeeper를 사용해요. 예를 들어 Amazon Web Services(AWS)에서 Pulsar를 실행한다면 t2.small 인스턴스로 충분할 가능성이 높아요.
Bookie와 Broker
bookie와 Pulsar 브로커를 실행하는 머신에는 더 강력한 머신이 필요해요. 예를 들어 AWS 배포에서는 i3.4xlarge 인스턴스가 적절할 수 있어요. 그 머신들에서 다음을 사용할 수 있어요:
- 빠른 CPU와 10Gbps NIC (Pulsar 브로커용)
- RAID 컨트롤러와 배터리 백업 쓰기 캐시가 있는 소형·고속 SSD 또는 HDD (BookKeeper bookie용)
하드웨어 권장 사항
Pulsar 인스턴스를 시작하려면 아래가 최소 및 권장 하드웨어 설정이에요.
클러스터는 3개의 브로커 노드, 3개의 bookie 노드, 3개의 ZooKeeper 노드로 구성돼요. 다음 권장 사항은 노드 하나에 대한 것이에요.
- 최소 하드웨어 설정 (250개 Pulsar 토픽)
| 구성 요소 | CPU | 메모리 | 저장소 | 처리량 |
|---|---|---|---|---|
| Broker | 0.2 | 256 MB | - | 쓰기 처리량: 3 MB/s, 읽기 처리량: 6 MB/s, 쓰기 속도: 350 entries/s, 읽기 속도: 650 entries/s |
| Bookie | 0.2 | 256 MB | 저널: 8 GB PD-SSD, Ledger: 16 GB PD-STANDARD | 쓰기 처리량: 2 MB/s, 읽기 처리량: 2 MB/s, 쓰기 속도: 200 entries/s, 읽기 속도: 200 entries/s |
| ZooKeeper | 0.05 | 256 MB | 로그: 8 GB PD-SSD, 데이터: 2 GB PD-STANDARD | - |
- 권장 하드웨어 설정 (1000개 Pulsar 토픽)
| 구성 요소 | CPU | 메모리 | 저장소 | 처리량 |
|---|---|---|---|---|
| Broker | 8 | 8 GB | - | 쓰기 처리량: 100 MB/s, 읽기 처리량: 200 MB/s, 쓰기 속도: 10,000 entries/s, 읽기 속도: 20,000 entries/s |
| Bookie | 4 | 8 GB | 저널: 256 GB PD-SSD, Ledger: 2 TB PD-STANDARD | 쓰기 처리량: 75 MB/s, 읽기 처리량: 75 MB/s, 쓰기 속도: 7,500 entries/s, 읽기 속도: 7,500 entries/s |
| ZooKeeper | 1 | 2 GB | 로그: 64 GB PD-SSD, 데이터: 256 GB PD-STANDARD | - |
Pulsar 바이너리 패키지 설치
클러스터의 각 머신(ZooKeeper와 BookKeeper를 실행하는 머신 포함)에 Pulsar 바이너리 패키지를 설치해야 해요.
바메탈에서 Pulsar 클러스터 배포를 시작하려면 다음 중 한 가지 방법으로 바이너리 tarball 릴리스를 다운로드해야 해요:
- 아래 링크를 직접 클릭해 자동으로 다운로드 트리거: Pulsar 5.0.0-M2 바이너리 릴리스
- Pulsar 다운로드 페이지에서
- GitHub의 Pulsar 릴리스 페이지에서
- wget 사용:
wget https://archive.apache.org/dist/pulsar/pulsar-5.0.0-M2/apache-pulsar-5.0.0-M2-bin.tar.gz
tarball을 다운로드한 후 압축을 풀고 결과 디렉터리로 cd해요:
tar xvzf apache-pulsar-5.0.0-M2-bin.tar.gz
cd apache-pulsar-5.0.0-M2
압축이 풀린 디렉터리는 다음 하위 디렉터리를 포함해요:
| 디렉터리 | 포함 내용 |
|---|---|
bin |
pulsar와 pulsar-admin 같은 Pulsar의 명령줄 도구 |
conf |
브로커 구성, ZooKeeper 구성 등을 포함한 Pulsar 구성 파일 |
data |
ZooKeeper와 BookKeeper가 사용하는 데이터 저장 디렉터리 |
lib |
Pulsar가 사용하는 JAR 파일 |
logs |
설치에서 생성되는 로그 |
conf 디렉터리에는 다양한 Pulsar 구성 요소의 구성 파일이 있어요. 아래는 주요 구성 범주의 간략한 개요예요:
- JVM 구성 (pulsar_env.sh / bkenv.sh): Broker, BookKeeper 및 기타 구성 요소에 대한 JVM 메모리 할당(PULSAR_MEM, BOOKIE_MEM), 가비지 컬렉션 옵션(PULSAR_GC, BOOKIE_GC), 추가 JVM 옵션(PULSAR_EXTRA_OPTS, BOOKIE_EXTRA_OPTS)을 제어해요.
- 브로커 구성 (broker.conf): 메타데이터 저장소 연결, 클러스터 이름, 포트, 메시지 보존 정책, 인증·권한 부여 설정을 포함한 Pulsar Broker의 핵심 런타임 파라미터예요.
- BookKeeper 구성 (bookkeeper.conf): 저널·ledger 디렉터리, ZooKeeper 연결, 컴팩션, 디스크 사용량 임계값을 포함한 BookKeeper Bookie의 저장 엔진 파라미터예요.
- Log4j 구성 (log4j2.yaml): 로그 수준, 출력 형식, 파일 롤링 전략, 로그 출력 디렉터리를 포함한 로깅 프레임워크 설정이에요.
- 동적 구성: 일부 Broker 구성 속성은 서비스를 재시작하지 않고 pulsar-admin CLI 도구나 Admin REST API로 런타임에 갱신할 수 있어요. 동적 구성은 메타데이터 저장소(ZooKeeper)에 저장되며 클러스터의 모든 브로커에 적용돼요.
사용 가능한 모든 구성 속성의 전체 목록은 Pulsar 구성 참조를 보세요.
내장 커넥터 설치 (선택)
built-in 커넥터를 사용하려면 다음 중 한 가지 방법으로 각 브로커 노드에 커넥터 tarball 릴리스를 다운로드해야 해요:
- 아래 링크를 클릭하고 Apache 미러에서 릴리스를 다운로드: Pulsar IO Connectors 5.0.0-M2 릴리스
- Pulsar 다운로드 페이지에서
- Pulsar 릴리스 페이지에서
- wget 사용:
wget https://archive.apache.org/dist/pulsar/pulsar-5.0.0-M2/connectors/{connector}-5.0.0-M2.nar
.nar 파일을 다운로드한 후 그 파일을 pulsar 디렉터리의 connectors 디렉터리에 복사해요.
예를 들어 커넥터 파일 pulsar-io-aerospike-5.0.0-M2.nar을 다운로드했다면:
mkdir connectors
mv pulsar-io-aerospike-5.0.0-M2.nar connectors
ls connectors
pulsar-io-aerospike-5.0.0-M2.nar
...
계층형 저장소 오프로더 설치 (선택)
계층형 저장소 오프로더를 사용하려면 다음 중 한 가지 방법으로 각 브로커 노드에 오프로더 tarball 릴리스를 다운로드해야 해요:
- 아래 링크를 클릭하고 Apache 미러에서 릴리스를 다운로드: Pulsar Tiered Storage Offloaders 5.0.0-M2 릴리스
- Pulsar 다운로드 페이지에서
- Pulsar 릴리스 페이지에서
- wget 사용:
wget https://archive.apache.org/dist/pulsar/pulsar-5.0.0-M2/apache-pulsar-offloaders-5.0.0-M2-bin.tar.gz
tarball을 다운로드한 후, Pulsar 디렉터리에서 오프로더 패키지의 압축을 풀고 오프로더를 Pulsar 디렉터리의 offloaders로 복사해요:
tar xvfz apache-pulsar-offloaders-5.0.0-M2-bin.tar.gz
# you can find a directory named `apache-pulsar-offloaders-5.0.0-M2` in the pulsar directory
# then copy the offloaders
mv apache-pulsar-offloaders-5.0.0-M2/offloaders offloaders
ls offloaders
tiered-storage-jcloud-5.0.0-M2.nar
계층형 저장소 기능 구성에 대한 자세한 내용은 계층형 저장소 쿡북을 참조해요.
1단계: 메타데이터 저장소 배포
새 클러스터에는 Oxia가 권장 메타데이터 저장소예요. Oxia 문서를 따라 Oxia 클러스터를 배포한 다음, 아래 단계에서 메타데이터 저장소 연결 문자열을 참조하는 곳마다(2단계와 브로커·bookie 구성에서) oxia://<host>:<port>/<namespace> URL을 사용해요. Oxia를 사용할 때는 이 단계의 나머지에 설명된 ZooKeeper 설정을 건너뛸 수 있어요.
이 단계의 나머지는 Pulsar 바이너리 패키지에 포함된 메타데이터 저장소인 ZooKeeper 배포를 설명해요.
참고 기존 ZooKeeper 클러스터가 있고 그것을 사용하고 싶다면 이 섹션을 건너뛸 수 있어요.
ZooKeeper는 Pulsar의 다양한 필수 조정·구성 관련 작업을 관리해요. Pulsar 클러스터를 배포하려면 먼저 ZooKeeper를 배포해야 해요. 3노드 ZooKeeper 클러스터가 권장 구성이에요. Pulsar는 ZooKeeper를 많이 사용하지 않으므로 경량 머신이나 VM이면 ZooKeeper 실행에 충분해요.
시작하려면 모든 ZooKeeper 서버를 위에서 만든 Pulsar 디렉터리의 conf/zookeeper.conf에 지정된 구성에 추가해요. 다음은 예시예요:
server.1=zk1.us-west.example.com:2888:3888
server.2=zk2.us-west.example.com:2888:3888
server.3=zk3.us-west.example.com:2888:3888
Pulsar를 배포할 머신이 하나뿐이라면 구성 파일에 서버 항목 하나만 추가하면 돼요.
머신이 NAT 뒤에 있다면 로컬 주소에 대해 server 항목으로 0.0.0.0을 사용해요. 노드가 자체 구성에 외부 IP를 사용하면, NAT 뒤에서는 linux 박스가 소유하지 않은 외부 IP에 리스너를 배치하려 하기 때문에 zookeeper 서비스가 시작되지 않아요. 0.0.0.0은 ALL ip에 리스너를 시작하므로 NAT 네트워크 트래픽이 도달할 수 있어요.
server.3의 구성 예시:
server.1=zk1.us-west.example.com:2888:3888
server.2=zk2.us-west.example.com:2888:3888
server.3=0.0.0.0:2888:3888
각 호스트에서 myid 파일에 노드의 ID를 지정해야 해요. myid 파일은 기본적으로 각 서버의 data/zookeeper 폴더에 있어요 (dataDir](/docs/5.0.x/reference-configuration/#zookeeper-dataDir) 파라미터로 파일 위치를 변경할 수 있어요).
myid와 관련한 자세한 정보는 ZooKeeper 문서의 다중 서버 설정 가이드를 보세요.
예를 들어 zk1.us-west.example.com 같은 ZooKeeper 서버에서 myid 값을 다음과 같이 설정할 수 있어요:
mkdir -p data/zookeeper
echo 1 > data/zookeeper/myid
zk2.us-west.example.com에서는 echo 2 > data/zookeeper/myid 명령이고, 그다음도 같은 식이에요.
zookeeper.conf 구성에 각 서버를 추가하고 적절한 myid 항목을 갖추면, pulsar-daemon CLI 도구로 모든 호스트에서 ZooKeeper를 시작할 수 있어요 (nohup으로 백그라운드에서):
bin/pulsar-daemon start zookeeper
bookie와 같은 노드에 ZooKeeper를 배포할 계획이라면, zookeeper.conf에서
metricsProvider.httpPort를 구성해 다른 stats 포트로 zookeeper를 시작해야 해요.
2단계: 클러스터 메타데이터 초기화
참고 새 클러스터를 프로비저닝할 때는 메타데이터 저장소(예: ZooKeeper)에 클러스터 메타데이터를 초기화해야 해요. 한 번만 초기화하면 돼요.
pulsar CLI 도구의 initialize-cluster-metadata 명령으로 이 메타데이터를 초기화할 수 있어요. 이 명령은 Pulsar 클러스터의 어느 머신에서든 실행할 수 있으므로, ZooKeeper, broker 또는 bookie 머신에서 메타데이터를 초기화할 수 있어요. 다음은 예시예요:
bin/pulsar initialize-cluster-metadata \
--cluster pulsar-cluster-1 \
--metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181 \
--configuration-metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181 \
--web-service-url http://pulsar.us-west.example.com:8080 \
--web-service-url-tls https://pulsar.us-west.example.com:8443 \
--broker-service-url pulsar://pulsar.us-west.example.com:6650 \
--broker-service-url-tls pulsar+ssl://pulsar.us-west.example.com:6651
팁 메타데이터 저장소로 Oxia를 사용한다면 연결 문자열을 자신의 Oxia URL로 설정하세요. 예:
--metadata-store oxia://oxia-1.example.com:6648/broker(--configuration-metadata-store는 선택이며 기본적으로 그 값을 따름).
위 예시에서 볼 수 있듯이 다음 구성을 지정해야 해요. *가 붙은 항목은 필수 플래그예요.
| 플래그 | 설명 |
|---|---|
--cluster* |
클러스터의 이름 |
--metadata-store* |
클러스터의 "로컬" 메타데이터 저장소 연결 문자열. 이 연결 문자열에는 ZooKeeper 클러스터의 한 머신만 포함하면 돼요. |
--configuration-metadata-store* |
전체 인스턴스의 구성 메타데이터 저장소 연결 문자열. --metadata-store 플래그와 마찬가지로 이 연결 문자열에는 ZooKeeper 클러스터의 한 머신만 포함하면 돼요. |
--web-service-url* |
클러스터의 웹 서비스 URL과 포트. 이 URL은 표준 DNS 이름이어야 해요. 기본 포트는 8080이에요 (다른 포트를 사용하지 않는 것이 좋아요). |
--web-service-url-tls |
TLS를 사용한다면 클러스터의 TLS 웹 서비스 URL도 지정해야 해요. 기본 포트는 8443이에요 (다른 포트를 사용하지 않는 것이 좋아요). |
--broker-service-url* |
클러스터의 브로커와 상호 작용할 수 있게 해주는 브로커 서비스 URL. 이 URL은 웹 서비스 URL과 같은 DNS 이름을 사용하지 말고 pulsar 스킴을 사용해야 해요. 기본 포트는 6650이에요 (다른 포트를 사용하지 않는 것이 좋아요). |
--broker-service-url-tls |
TLS를 사용한다면 클러스터의 TLS 웹 서비스 URL뿐 아니라 클러스터 브로커의 TLS 브로커 서비스 URL도 지정해야 해요. 기본 포트는 6651이에요 (다른 포트를 사용하지 않는 것이 좋아요). |
--default-namespace-bundle-number |
public/default 네임스페이스의 번들 수, 기본값 32. 번들은 나중에 분할할 수 있지만 병합할 수는 없어요. 네임스페이스 번들을 보세요. |
--system-namespace-bundle-number |
pulsar/system 네임스페이스의 번들 수, 기본값 64. 트랜잭션 코디네이터는 이 네임스페이스의 번들에 의해 브로커에 분산돼요. 기본값 16(--initial-num-transaction-coordinators)보다 더 많은 코디네이터를 실행한다면 이 값을 높이세요. 네임스페이스 번들을 보세요. |
참고 DNS 서버가 없다면 다음 설정으로 서비스 URL에서 multi-host 형식을 사용할 수 있어요:
--web-service-url http://host1:8080,host2:8080,host3:8080 \
--web-service-url-tls https://host1:8443,host2:8443,host3:8443 \
--broker-service-url pulsar://host1:6650,host2:6650,host3:6650 \
--broker-service-url-tls pulsar+ssl://host1:6651,host2:6651,host3:6651
기존 BookKeeper 클러스터를 사용하려면 다음과 같이 --existing-bk-metadata-service-uri 플래그를 추가할 수 있어요:
--existing-bk-metadata-service-uri "zk+null://zk1:2181;zk2:2181/ledgers" \
--web-service-url http://host1:8080,host2:8080,host3:8080 \
--web-service-url-tls https://host1:8443,host2:8443,host3:8443 \
--broker-service-url pulsar://host1:6650,host2:6650,host3:6650 \
--broker-service-url-tls pulsar+ssl://host1:6651,host2:6651,host3:6651
기존 BookKeeper 클러스터의 메타데이터 서비스 URI는 bin/bookkeeper shell whatisinstanceid 명령으로 얻을 수 있어요. 여러 메타데이터 서비스 URI가 세미콜론으로 구분되므로 값을 큰따옴표로 묶어야 해요.
3단계: BookKeeper 클러스터 배포
BookKeeper는 Pulsar의 모든 영구 데이터 저장을 처리해요. Pulsar를 사용하려면 BookKeeper bookie 클러스터를 배포해야 해요. 3-bookie BookKeeper 클러스터를 실행하도록 선택할 수 있어요.
BookKeeper 구성
BookKeeper 구성은 두 파일로 나뉘어 있어요:
conf/bookkeeper.conf: 메타데이터 저장소 연결, 저장 디렉터리, 컴팩션 설정, 디스크 사용량 임계값을 포함한 모든 BookKeeper 런타임 파라미터를 담아요.conf/bkenv.sh: 메모리 할당(BOOKIE_MEM), 가비지 컬렉션 옵션(BOOKIE_GC), 추가 JVM 플래그(BOOKIE_EXTRA_OPTS)를 포함한 Bookie 프로세스의 JVM 관련 파라미터를 담아요.
메타데이터 저장소 연결
conf/bookkeeper.conf 구성 파일을 사용해 BookKeeper bookies를 구성할 수 있어요. 여기서 bookies를 구성하는 가장 중요한 단계는 metadataServiceUri가 메타데이터 저장소의 URI로 설정되어 있는지 확인하는 거예요. Oxia(권장)를 사용하면 metadata-store: 드라이버를 사용해요:
metadataServiceUri=metadata-store:oxia://oxia-1.example.com:6648/bookkeeper
ZooKeeper를 사용하면 다음이 예시예요:
metadataServiceUri=zk://zk1.us-west.example.com:2181;zk2.us-west.example.com:2181;zk3.us-west.example.com:2181/ledgers
참고
metadataServiceUri에서 구분자로;를 사용해요.
ZooKeeper와 BookKeeper 관리에 대한 자세한 정보는 ZooKeeper 및 BookKeeper 관리를 보세요.
저장 디렉터리
프로덕션 환경에서는 저널과 ledger 저장에 전용 디스크를 구성해야 해요. 디스크를 분리하면 쓰기 성능이 크게 향상돼요.
# WAL (Write-Ahead Log) directory — use a dedicated SSD for low-latency writes
journalDirectory=/data/bookkeeper/journal
# Ledger storage directory — use a separate disk from the journal
ledgerDirectories=/data/bookkeeper/ledgers
- journalDirectory: 기본값 data/bookkeeper/journal. 저널은 ledger 저장에 적용되기 전에 모든 쓰기를 기록하는 write-ahead log예요. 저널 디렉터리에 전용 고속 SSD를 사용하는 것은 쓰기 지연에 중요해요.
- ledgerDirectories: 기본값 data/bookkeeper/ledgers. 실제 ledger 데이터가 저장되는 곳이에요. 저널 디렉터리와 분리하면 I/O 경합을 피하고 처리량을 높여요.
GC와 컴팩션
BookKeeper는 여러 ledger의 엔트리를 공유 Entry Log 파일에 써요 (기본 각 최대 1 GB, logSizeLimit으로 제어). ledger가 삭제되면(Pulsar 보존 정책이 만료 데이터를 정리한 후 등) 그 ledger를 포함한 Entry Log 파일에 미사용 공간이 생겨요. Bookie의 GC 스레드는 주기적으로 삭제된 ledger를 스캔하고, 남은 유효 엔트리를 새 파일로 다시 써 디스크 공간을 회수하는 컴팩션을 트리거해요.
BookKeeper는 두 수준의 컴팩션을 제공해요:
- 마이너 컴팩션: 유효 데이터 비율이 minorCompactionThreshold(기본 0.2, 즉 20%) 미만인 Entry Log 파일을 대상으로 해요. minorCompactionInterval(기본: 매시간)마다 실행돼요. 크게 조각화된 파일을 빠르게 회수하기 위해 설계됐어요.
- 메이저 컴팩션: 유효 데이터 비율이 majorCompactionThreshold(기본 0.5, 즉 50%) 미만인 Entry Log 파일을 대상으로 해요. majorCompactionInterval(기본: 매일)마다 실행돼요. 중간 정도 조각화된 더 넓은 범위의 파일을 다뤄요.
# GC scan interval (ms), default: 900000 (15 min)
gcWaitTime=900000
# Minor Compaction: threshold and interval
minorCompactionThreshold=0.2
minorCompactionInterval=3600
# Major Compaction: threshold and interval
majorCompactionThreshold=0.5
majorCompactionInterval=86400
참고
minorCompactionInterval과majorCompactionInterval은gcWaitTime보다 커야 해요. 그렇지 않으면 컴팩션이 실행되지 않아요.
디스크 사용량 임계값
BookKeeper는 디스크 사용량을 모니터링하고 디스크 고갈을 막기 위해 Bookie를 자동으로 읽기 전용 모드로 전환할 수 있어요.
# Bookie enters read-only mode when disk usage exceeds this threshold (default: 0.95)
diskUsageThreshold=0.95
# Warning threshold — Major Compaction is paused when disk usage exceeds this value (default: 0.90)
diskUsageWarnThreshold=0.90
# Low water mark — Bookie returns to read-write mode only after disk usage drops below this value
# Set it lower than diskUsageWarnThreshold to avoid frequent mode switching (recommended: 0.87)
diskUsageLwmThreshold=0.87
JVM 구성 (bkenv.sh)
conf/bkenv.sh 파일은 Bookie 프로세스의 JVM 파라미터를 제어해요:
-
BOOKIE_MEM: 기본값-Xms2g -Xmx2g -XX:MaxDirectMemorySize=2g. 저장 워크로드에 맞게 조정해요. 힙 메모리가 부족하면 빈번한 GC가 발생해 쓰기와 읽기 지연이 늘어나요. 특히 높은 처리량에서 GC 일시 중지는 쓰기 타임아웃을 유발할 수 있어요. 다이렉트 메모리는 주로 Netty ByteBuf 할당에 사용돼요. BookKeeper는 기본적으로PooledDirect메모리 할당자를 사용하며, 네트워크 I/O와 내부 데이터 처리를 위해 모든 ByteBuf를 다이렉트 메모리에서 할당해요.# Example: increase heap and direct memory for high-throughput workloadsBOOKIE_MEM="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=4g" -
BOOKIE_EXTRA_OPTS: Bookie 프로세스에 추가 JVM 플래그를 전달해요. 예시:# Enable heap dump on OOM (the default script only enables ExitOnOutOfMemoryError,# without a heap dump file you cannot diagnose the root cause)BOOKIE_EXTRA_OPTS="-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/bookie/heapdump.hprof"# Temporarily enable Netty leak detection for troubleshooting off-heap memory leaks# (default is disabled; set to advanced level when investigating)BOOKIE_EXTRA_OPTS="-Dio.netty.leakDetection.level=advanced"
conf/bookkeeper.conf와 conf/bkenv.sh를 모두 편집한 후, 사용 가능한 BookKeeper 구성 파라미터의 전체 목록은 여기에서 찾을 수 있어요. 다만 더 깊이 있는 가이드는 BookKeeper 문서를 참조하는 것이 더 나을 거예요.
BookKeeper 시작
conf/bookkeeper.conf와 conf/bkenv.sh에 원하는 구성을 적용한 상태에서 각 BookKeeper 호스트에 bookie를 시작할 수 있어요. 각 bookie를 nohup으로 백그라운드에서 시작하거나 포그라운드에서 시작할 수 있어요.
bookie를 백그라운드에서 시작하려면 pulsar-daemon CLI 도구를 사용해요:
bin/pulsar-daemon start bookie
bookie를 포그라운드에서 시작하려면:
bin/pulsar bookie
BookKeeper 셸에서 bookiesanity 명령을 실행해 bookie가 제대로 작동하는지 확인할 수 있어요:
bin/bookkeeper shell bookiesanity
이 명령은 로컬 bookie에 임시 BookKeeper ledger를 만들고, 몇 개의 엔트리를 쓰고, 다시 읽은 다음 마지막으로 ledger를 삭제해요.
모든 bookie를 시작한 후에는 아무 bookie 노드에서 BookKeeper 셸의 simpletest 명령을 사용해 클러스터의 모든 bookie가 실행 중인지 확인할 수 있어요.
bin/bookkeeper shell simpletest --ensemble <num-bookies> --writeQuorum <num-bookies> --ackQuorum <num-bookies> --numEntries <num-entries>
이 명령은 클러스터에 num-bookies 크기의 ledger를 만들고, 몇 개의 엔트리를 쓴 다음 마지막으로 ledger를 삭제해요.
4단계: Pulsar 브로커 배포
Pulsar 브로커는 Pulsar 클러스터에서 마지막으로 배포해야 할 것이에요. 브로커는 Pulsar 메시지를 처리하고 Pulsar의 관리 인터페이스를 제공해요. 이미 BookKeeper bookie를 실행 중인 머신마다 하나씩 3개의 브로커를 실행하는 것이 좋은 선택이에요.
브로커 구성
브로커 구성은 두 파일로 나뉘어 있어요:
conf/broker.conf: 메타데이터 저장소 연결, 클러스터 이름, 포트, 복제 설정, 기능 토글을 포함한 모든 Broker 런타임 파라미터를 담아요.conf/pulsar_env.sh: 메모리 할당(PULSAR_MEM), 가비지 컬렉션 옵션(PULSAR_GC), 추가 JVM 플래그(PULSAR_EXTRA_OPTS)를 포함한 Broker 프로세스의 JVM 관련 파라미터를 담아요.
메타데이터 저장소와 클러스터 설정
conf/broker.conf 구성 파일을 사용해 브로커를 구성할 수 있어요. 브로커 구성의 가장 중요한 요소는 각 브로커가 배포한 메타데이터 저장소를 인지하고 있는지 확인하는 거예요. metadataStoreUrl과 configurationMetadataStoreUrl 파라미터가 올바른지 확인하세요. 이 경우 클러스터가 1개이고 구성 저장소 설정이 없으므로 configurationMetadataStoreUrl은 같은 metadataStoreUrl을 가리켜요.
Oxia(권장)를 사용하면 단일 클러스터에서 configurationMetadataStoreUrl은 생략할 수 있지만, bookkeeperMetadataServiceUri는 필수이며 자체 네임스페이스를 사용해요:
metadataStoreUrl=oxia://oxia-1.example.com:6648/broker
bookkeeperMetadataServiceUri=metadata-store:oxia://oxia-1.example.com:6648/bookkeeper
ZooKeeper를 사용하면:
metadataStoreUrl=zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
configurationMetadataStoreUrl=zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
또한 클러스터 메타데이터 초기화 시 제공한 이름과 일치하는 클러스터 이름을 지정해야 해요:
clusterName=pulsar-cluster-1
추가로 클러스터 메타데이터 초기화 시 제공한 브로커와 웹 서비스 포트와 일치해야 해요 (특히 기본값이 아닌 다른 포트를 사용할 때):
brokerServicePort=6650
brokerServicePortTls=6651
webServicePort=8080
webServicePortTls=8443
Managed ledger 설정
이 파라미터들은 Broker가 메시지 저장을 위해 BookKeeper ledger를 만드는 방법을 제어해요. BookKeeper 프로토콜의 Ensemble / Write Quorum / Ack Quorum 모델에 매핑돼요:
# Ensemble size (E): number of bookies to use when creating a ledger (default: 2)
managedLedgerDefaultEnsembleSize=2
# Write quorum (Qw): number of copies to store for each entry (default: 2)
managedLedgerDefaultWriteQuorum=2
# Ack quorum (Qa): number of acks to wait before a write is considered complete (default: 2)
managedLedgerDefaultAckQuorum=2
불변식 E ≥ Qw ≥ Qa가 성립해야 해요. 그렇지 않으면 ledger 생성이 실패해요.
단일 노드 클러스터에 Pulsar를 배포한다면 세 값을 모두
1로 설정해야 해요.
JVM 구성 (pulsar_env.sh)
conf/pulsar_env.sh 파일은 Broker 프로세스의 JVM 파라미터를 제어해요:
-
PULSAR_MEM: 기본값-Xms2g -Xmx2g -XX:MaxDirectMemorySize=4g. 머신의 사용 가능한 메모리에 맞게 조정해요. 힙 메모리가 부족하면 빈번한 GC가 발생하고, GC 일시 중지가 메시지 게시·소비 지연을 늘려요. 심한 경우 Full GC가 Broker를 일시적으로 사용 불가하게 만들 수 있어요. 다이렉트 메모리는 Broker의 메시지 캐싱과 Netty I/O 작업에 중요해요.# Example: increase heap and direct memory for production workloadsPULSAR_MEM="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=8g" -
PULSAR_EXTRA_OPTS: Broker/Proxy/ZooKeeper 프로세스에 추가 JVM 플래그를 전달해요.PULSAR_EXTRA_OPTS는 명령줄에서 다른 JVM 옵션 뒤에 추가되므로,pulsar_env.sh또는bin/pulsar시작 스크립트에 정의된 기존 JVM 파라미터를 재정의하는 데에도 사용할 수 있어요 (뒤에 오는 플래그가 우선함). 예시:# Enable heap dump on OOM (the default script only enables ExitOnOutOfMemoryError,# without a heap dump file you cannot diagnose the root cause after the process exits)PULSAR_EXTRA_OPTS="-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/pulsar/heapdump.hprof"# Enable IPv6 support (the default script sets -Djava.net.preferIPv4Stack=true;# override this if your deployment uses IPv6 networking)PULSAR_EXTRA_OPTS="-Djava.net.preferIPv4Stack=false"# Tune Netty memory pool parameters (increase maxOrder and maxCachedBufferCapacity# if your messages are large, to avoid Netty bypassing the memory pool for allocation)PULSAR_EXTRA_OPTS="-Dio.netty.allocator.maxOrder=13 -Dio.netty.allocator.numDirectArenas=8 -Dio.netty.allocator.maxCachedBufferCapacity=1048576"
팁 튜닝 참고 자료로 Pulsar Helm Chart values.yaml의 기본 구성을 참조할 수도 있어요.
Pulsar Functions 활성화 (선택)
Pulsar Functions를 활성화하려면 아래 지침을 따르세요:
-
conf/broker.conf를 편집해functionsWorkerEnabled를true로 설정해 functions worker를 활성화해요.functionsWorkerEnabled=true -
conf/functions_worker.yml을 편집하고pulsarFunctionsCluster를 클러스터 메타데이터 초기화 시 제공한 클러스터 이름으로 설정해요.pulsarFunctionsCluster: pulsar-cluster-1
functions worker 배포에 대한 더 많은 옵션을 알고 싶다면 functions worker 배포 및 관리를 확인하세요.
브로커 시작
conf/broker.conf 파일에 원하는 다른 구성 변경을 제공할 수 있어요. 구성을 정하면 Pulsar 클러스터의 브로커를 시작할 수 있어요. ZooKeeper와 BookKeeper처럼 nohup으로 브로커를 포그라운드나 백그라운드에서 시작할 수 있어요.
pulsar broker 명령으로 브로커를 포그라운드에서 시작할 수 있어요:
bin/pulsar broker
pulsar-daemon CLI 도구로 브로커를 백그라운드에서 시작할 수 있어요:
bin/pulsar-daemon start broker
사용하려는 모든 브로커를 성공적으로 시작하면 Pulsar 클러스터를 사용할 준비가 끝나요!
실행 중인 클러스터에 연결
Pulsar 클러스터가 실행되고 나면 Pulsar 클라이언트로 연결할 수 있어야 해요. 그런 클라이언트 중 하나가 Pulsar 바이너리 패키지에 포함된 pulsar-client 도구예요. pulsar-client 도구는 Pulsar 토픽에 메시지를 게시하고 소비할 수 있어서 클러스터가 제대로 실행되는지 확인하는 간단한 방법을 제공해요.
pulsar-client 도구를 사용하려면 먼저 바이너리 패키지의 conf/client.conf에 있는 클라이언트 구성 파일을 수정해요. webServiceUrl과 brokerServiceUrl 값을 변경해, 기본값인 localhost를 브로커/bookie 호스트에 할당한 DNS 이름으로 대체해야 해요. 다음은 예시예요:
webServiceUrl=http://us-west.example.com:8080
brokerServiceurl=pulsar://us-west.example.com:6650
참고 DNS 서버가 없다면 다음과 같이 서비스 URL에서 multi-host를 지정할 수 있어요:
webServiceUrl=http://host1:8080,host2:8080,host3:8080
brokerServiceurl=pulsar://host1:6650,host2:6650,host3:6650
그게 끝나면 Pulsar 토픽에 메시지를 게시할 수 있어요:
bin/pulsar-client produce \
persistent://public/default/test \
-n 1 \
-m "Hello Pulsar"
이 명령은 Pulsar 토픽에 단일 메시지를 게시해요. 또한 다른 터미널에서 메시지를 게시하기 전에 다음과 같이 Pulsar 토픽을 구독할 수 있어요:
bin/pulsar-client consume \
persistent://public/default/test \
-n 100 \
-s "consumer-test" \
-t "Exclusive"
위 메시지를 토픽에 성공적으로 게시하면 표준 출력에서 그것을 볼 수 있어요:
----- got message -----
key:[null], properties:[], content:Hello Pulsar
Functions 실행
Pulsar Functions를 활성화했다면 지금 Pulsar Functions를 시험해 볼 수 있어요.
ExclamationFunction exclamation을 만들어요.
bin/pulsar-admin functions create \
--jar $PWD/examples/api-examples.jar \
--classname org.apache.pulsar.functions.api.examples.ExclamationFunction \
--inputs persistent://public/default/exclamation-input \
--output persistent://public/default/exclamation-output \
--tenant public \
--namespace default \
--name exclamation
함수를 트리거해서 예상대로 실행되는지 확인해요.
bin/pulsar-admin functions trigger --name exclamation --trigger-value "hello world"
다음 출력이 보여야 해요:
hello world!
더 알아보기 (Learn more)
- 바메탈 다중 클러스터 배포 — 여러 클러스터로 확장해요.
- Docker 배포 — 컨테이너로 편하게 시작해요.
- Terraform·Ansible AWS 배포 — 자동화 도구로 클라우드에 띄워요.
- 계층형 저장소 쿡북 — 오프로더를 구성해요.
- ZooKeeper·BookKeeper 관리 — 메타데이터 저장소 운영을 다뤄요.