바메탈에 다중 클러스터 Pulsar 배포하기
바메탈에 다중 클러스터 Pulsar 배포하기
하나의 Pulsar 인스턴스 안에 여러 클러스터를 두고 지오레플리케이션으로 연결하면, 데이터센터나 리전 간에 데이터를 복제하며 장애에 대비할 수 있어요. 이 글에서는 바메탈에 다중 클러스터 Pulsar 인스턴스를 배포하는 전체 과정을 안내해 드릴게요. 기존 단일 클러스터 배포와 달리 각 클러스터의 로컬 메타데이터 저장소와 함께 인스턴스 전역의 configuration store를 구성하는 부분이 핵심이에요.
출처: 문서
본문
팁
- 대부분의 사용 사례(예: Pulsar 실험, 스타트업 또는 단일 팀에서의 사용)에서는 단일 클러스터 Pulsar 설치로 충분해요. 다중 클러스터 Pulsar 인스턴스를 실행해야 한다면 이 가이드를 보세요.
- 모든 내장 Pulsar IO 커넥터를 사용하려면 apache-pulsar-io-connectors 패키지를 다운로드해 각 브로커 노드의 pulsar 디렉터리 아래 connectors 디렉터리(또는 Pulsar Functions용으로 별도의 function-worker 클러스터를 실행한다면 각 function-worker 노드)에 설치해야 해요.
- 배포에서 계층형 저장소 기능을 사용하려면 apache-pulsar-offloaders 패키지를 다운로드해 각 브로커 노드의 Pulsar 디렉터리 아래 offloaders 디렉터리에 설치해야 해요. 이 기능 구성에 대한 자세한 내용은 계층형 저장소 쿡북을 참조하세요.
Pulsar 인스턴스는 여러 Pulsar 클러스터가 협력하여 구성돼요. 클러스터를 데이터센터나 지리적 리전에 분산하고 지오레플리케이션을 사용해 클러스터 간에 서로 복제할 수 있어요.
로컬에서 또는 Kubernetes에서 Pulsar를 실행하나요? 이 가이드는 비-Kubernetes 환경의 프로덕션에 Pulsar를 배포하는 방법을 보여줘요. 개발 목적으로 단일 머신에서 standalone Pulsar 클러스터를 실행하려면 로컬 클러스터 설정 가이드를 보세요. Kubernetes에서 Pulsar를 실행하려면 Kubernetes의 Pulsar 가이드를 보세요. 여기에는 Kubernetes, Google Kubernetes Engine, Amazon Web Services에서 Pulsar를 실행하는 섹션이 포함돼 있어요.
바메탈에 다중 클러스터 Pulsar 인스턴스를 배포하는 것은 다음 단계로 구성돼요.
시스템 요구 사항
현재 Pulsar는 64비트 macOS와 Linux에서 사용할 수 있어요. Windows에서 Pulsar를 실행하려면 Docker에서 Pulsar 실행을 보세요.
또한 적절한 64비트 JRE/JDK 버전을 설치해야 해요. Pulsar 런타임 Java 버전 권장을 참조하세요.
Pulsar 설치
Pulsar 실행을 시작하려면 다음 중 한 가지 방법으로 바이너리 tarball 릴리스를 다운로드해요:
- 아래 링크를 클릭하고 Apache 미러에서 릴리스를 다운로드: Pulsar 5.0.0-M2 바이너리 릴리스
- Pulsar 다운로드 페이지에서
- Pulsar 릴리스 페이지에서
- wget 사용:
wget 'https://www.apache.org/dyn/mirrors/mirrors.cgi?action=download&filename=pulsar/pulsar-5.0.0-M2/apache-pulsar-5.0.0-M2-bin.tar.gz' -O apache-pulsar-5.0.0-M2-bin.tar.gz
tarball을 다운로드한 후 압축을 풀고 결과 디렉터리로 cd해요:
tar xvfz apache-pulsar-5.0.0-M2-bin.tar.gz
cd apache-pulsar-5.0.0-M2
Pulsar 바이너리 패키지는 처음에 다음 디렉터리를 포함해요:
| 디렉터리 | 포함 내용 |
|---|---|
bin |
pulsar과 pulsar-admin 같은 Pulsar의 명령줄 도구 |
conf |
브로커 구성, ZooKeeper 구성 등을 포함한 Pulsar 구성 파일 |
examples |
예시 Pulsar Functions를 담은 Java JAR 파일 |
lib |
Pulsar가 사용하는 JAR 파일 |
licenses |
Pulsar 코드베이스의 다양한 구성 요소에 대한 .txt 형식의 라이선스 파일 |
Pulsar를 실행하기 시작하면 다음 디렉터리가 생성돼요:
| 디렉터리 | 포함 내용 |
|---|---|
data |
ZooKeeper와 BookKeeper가 사용하는 데이터 저장 디렉터리 |
instances |
Pulsar Functions를 위해 생성된 아티팩트 |
logs |
설치에서 생성되는 로그 |
1단계: 메타데이터 저장소 배포
새 클러스터에는 Oxia가 권장 메타데이터 저장소이며, 다중 클러스터 인스턴스에도 마찬가지예요. Oxia 문서를 따라 Oxia를 배포하고, 아래 단계에서 연결 문자열을 참조하는 곳마다 로컬 메타데이터 저장소와 configuration store 모두에 oxia://<host>:<port>/<namespace> URL을 사용해요. 이 단계의 나머지는 전통적인 ZooKeeper 설정을 설명해요.
ZooKeeper를 사용할 때 각 Pulsar 인스턴스는 두 개의 별도 ZooKeeper 쿼럼에 의존해요.
- 로컬 ZooKeeper는 클러스터 수준에서 운영되며 클러스터별 구성 관리와 조정을 제공해요. 각 Pulsar 클러스터에는 전용 ZooKeeper 클러스터가 필요해요.
- Configuration Store는 인스턴스 수준에서 운영되며 전체 시스템(따라서 클러스터 전반)의 구성 관리를 제공해요. 로컬 ZooKeeper가 사용하는 것과 같은 머신의 독립적인 클러스터나 같은 머신으로 configuration store 쿼럼을 제공할 수 있어요.
configuration store 쿼럼을 제공하기 위해 독립적인 머신 클러스터나 로컬 ZooKeeper가 사용하는 같은 머신을 사용할 수 있어요.
로컬 ZooKeeper 배포
ZooKeeper는 Pulsar의 다양한 필수 조정·구성 관련 작업을 관리해요.
Pulsar 인스턴스를 배포하려면 Pulsar 클러스터마다 로컬 ZooKeeper 클러스터 하나를 세워야 해요.
시작하려면 conf/zookeeper.conf 파일에 지정된 쿼럼 구성에 모든 ZooKeeper 서버를 추가해요. 클러스터의 각 노드에 대해 server.N 줄을 구성에 추가하는데, 여기서 N은 ZooKeeper 노드 번호예요. 다음은 3노드 클러스터의 예시예요:
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
각 호스트에서 각 노드의 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
Configuration store 배포
위 섹션에서 구성하고 시작한 ZooKeeper 클러스터는 단일 Pulsar 클러스터를 관리하는 데 사용할 수 있는 로컬 ZooKeeper 클러스터예요. 하지만 로컬 클러스터 외에도 완전한 Pulsar 인스턴스에는 인스턴스 수준의 구성·조정 작업을 처리하는 configuration store가 필요해요.
단일 클러스터 인스턴스를 배포한다면 configuration store용으로 별도 클러스터가 필요하지 않아요. 하지만 다중 클러스터 인스턴스를 배포한다면 구성 작업용으로 별도의 ZooKeeper 클러스터를 세워야 해요.
단일 클러스터 Pulsar 인스턴스
Pulsar 인스턴스가 클러스터 하나로만 구성되어 있다면, 로컬 ZooKeeper 쿼럼과 같은 머신에 configuration store를 배포하되 다른 TCP 포트에서 실행하면 돼요.
단일 클러스터 인스턴스에서 ZooKeeper configuration store를 배포하려면 같은 ZooKeeper 서버를 로컬 쿼럼에 추가해요. 로컬 ZooKeeper와 같은 방법으로 conf/global_zookeeper.conf의 구성 파일을 사용해야 하지만, 다른 포트(ZooKeeper 기본값은 2181)를 사용해야 해요. 다음은 3노드 ZooKeeper 클러스터에 포트 2184를 사용하는 예시예요:
clientPort=2184
server.1=zk1.us-west.example.com:2185:2186
server.2=zk2.us-west.example.com:2185:2186
server.3=zk3.us-west.example.com:2185:2186
이전과 마찬가지로 각 서버에 data/global-zookeeper/myid의 myid 파일을 만들어요.
다중 클러스터 Pulsar 인스턴스
서로 다른 지리적 리전에 분산된 클러스터를 가진 전역 Pulsar 인스턴스를 배포할 때, configuration store는 전체 리전에 걸친 장애와 분할을 견딜 수 있는 고가용성·강력한 일관성의 메타데이터 저장소 역할을 해요.
핵심은 ZK 쿼럼 멤버가 최소 3개 리전에 퍼져 있고, 다른 리전은 observer로 실행되도록 하는 거예요.
다시 말하지만 configuration store 서버의 예상 부하가 매우 낮으므로 로컬 ZooKeeper 쿼럼이 사용하는 같은 호스트를 공유할 수 있어요.
예를 들어 us-west, us-east, us-central, eu-central, ap-south 클러스터를 가진 Pulsar 인스턴스를 가정해 볼게요. 또한 각 클러스터에 다음과 같은 이름의 자체 로컬 ZK 서버가 있다고 가정해요:
zk[1-3].${CLUSTER}.example.com
이 시나리오에서 몇 개 클러스터에서 쿼럼 참가자를 선택하고 나머지는 모두 ZK observer로 두고 싶다면, 예를 들어 7개 서버 쿼럼을 형성하기 위해 us-west에서 3개, us-central에서 2개, us-east에서 2개를 선택할 수 있어요.
이 방법은 이 리전 중 하나에 도달할 수 없어도 configuration store에 쓰는 것이 가능하다는 것을 보장해요.
모든 서버의 ZK 구성은 다음과 같아요:
clientPort=2184
server.1=zk1.us-west.example.com:2185:2186
server.2=zk2.us-west.example.com:2185:2186
server.3=zk3.us-west.example.com:2185:2186
server.4=zk1.us-central.example.com:2185:2186
server.5=zk2.us-central.example.com:2185:2186
server.6=zk3.us-central.example.com:2185:2186:observer
server.7=zk1.us-east.example.com:2185:2186
server.8=zk2.us-east.example.com:2185:2186
server.9=zk3.us-east.example.com:2185:2186:observer
server.10=zk1.eu-central.example.com:2185:2186:observer
server.11=zk2.eu-central.example.com:2185:2186:observer
server.12=zk3.eu-central.example.com:2185:2186:observer
server.13=zk1.ap-south.example.com:2185:2186:observer
server.14=zk2.ap-south.example.com:2185:2186:observer
server.15=zk3.ap-south.example.com:2185:2186:observer
추가로 ZK observer는 다음 파라미터를 가져야 해요:
peerType=observer
서비스 시작
configuration store 구성이 준비되면 pulsar-daemon으로 서비스를 시작할 수 있어요.
bin/pulsar-daemon start configuration-store
2단계: 클러스터 메타데이터 초기화
인스턴스에 대한 클러스터별 메타데이터 저장소와 configuration store 쿼럼을 설정한 후, 인스턴스의 각 클러스터에 일부 메타데이터를 써야 해요. 이 메타데이터는 한 번만 쓰면 돼요.
pulsar CLI 도구의 initialize-cluster-metadata 명령으로 이 메타데이터를 초기화할 수 있어요. 다음은 예시예요:
bin/pulsar initialize-cluster-metadata \
--cluster us-west \
--metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181/my-chroot-path \
--configuration-metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181/my-chroot-path \
--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를 사용한다면
--metadata-store(그리고 다중 클러스터 인스턴스의 경우--configuration-metadata-store)를 자신의 Oxia URL로 설정하세요. 예:oxia://oxia-1.example.com:6648/broker.
위 예시에서 볼 수 있듯이 다음을 지정해야 해요:
- 클러스터의 이름
- 클러스터의 로컬 메타데이터 저장소 연결 문자열
- 전체 인스턴스의 configuration store 연결 문자열
- 클러스터의 웹 서비스 URL
- 클러스터의 브로커와 상호 작용할 수 있게 해주는 브로커 서비스 URL
TLS를 사용한다면 클러스터의 TLS 웹 서비스 URL뿐 아니라 클러스터 브로커의 TLS 브로커 서비스 URL도 지정해야 해요.
이 명령은 또한 public/default와 pulsar/system 네임스페이스를 생성하는데, 기본적으로 각각 32개와 64개 번들을 가져요 (--default-namespace-bundle-number와 --system-namespace-bundle-number). 크기 조정 방법은 네임스페이스 번들을 보세요.
인스턴스의 각 클러스터에 대해 initialize-cluster-metadata를 실행해야 해요.
3단계: BookKeeper 배포
BookKeeper는 Pulsar에 영구 메시지 저장소를 제공해요.
각 Pulsar 브로커에는 자체 bookie 클러스터가 필요해요. BookKeeper 클러스터는 Pulsar 클러스터와 메타데이터 저장소를 공유해요.
bookies 구성
conf/bookkeeper.conf 구성 파일을 사용해 BookKeeper bookies를 구성할 수 있어요. 각 bookie를 구성할 때 가장 중요한 측면은 그 metadataServiceUri가 BookKeeper 메타데이터 저장소를 가리키는지 확인하는 거예요. Oxia(권장)는 metadata-store:oxia://oxia-1.example.com:6648/bookkeeper, 또는 로컬 ZooKeeper 연결 문자열이에요.
bookies 시작
bookie는 두 가지 방식으로 시작할 수 있어요. 포그라운드 또는 백그라운드 데몬으로요.
bookie를 백그라운드에서 시작하려면 pulsar-daemon CLI 도구를 사용해요:
bin/pulsar-daemon start bookie
BookKeeper 셸의 bookiesanity 명령으로 bookie가 제대로 작동하는지 확인할 수 있어요:
bin/bookkeeper shell bookiesanity
이 명령은 로컬 bookie에 새 ledger를 만들고, 몇 개의 엔트리를 쓰고, 다시 읽은 다음 마지막으로 ledger를 삭제해요.
모든 bookie를 시작한 후에는 아무 bookie 노드에서 BookKeeper 셸의 simpletest 명령을 사용해 클러스터의 모든 bookie가 실행 중인지 확인할 수 있어요.
bin/bookkeeper shell simpletest --ensemble <num-bookies> --writeQuorum <num-bookies> --ackQuorum <num-bookies> --numEntries <num-entries>
bookie 호스트는 메시지 데이터를 디스크에 저장하는 역할을 담당해요. bookie가 최적의 성능을 제공하려면 bookie에 적합한 하드웨어 구성이 필수예요. 다음은 bookie 하드웨어 용량의 핵심 차원이에요.
- 디스크 I/O 용량 읽기/쓰기
- 저장 용량
bookies에 기록된 메시지 엔트리는 Pulsar 브로커에 확인을 반환하기 전에 항상 디스크에 동기화돼요. 낮은 쓰기 지연을 보장하기 위해 BookKeeper는 여러 디바이스를 사용하도록 설계됐어요:
- 내구성을 보장하는 저널(journal). 순차 쓰기의 경우 bookie 호스트에서 빠른 fsync 작업이 중요해요. 일반적으로 소형·고속 SSD면 충분하거나, RAID 컨트롤러와 배터리 백업 쓰기 캐시가 있는 HDD면 충분해요. 두 솔루션 모두 ~0.4ms의 fsync 지연에 도달할 수 있어요.
- ledger 저장 디바이스는 모든 소비자가 메시지를 확인할 때까지 데이터가 저장되는 곳이에요. 쓰기는 백그라운드에서 일어나므로 쓰기 I/O는 큰 우려가 아니에요. 읽기는 대부분 순차적으로 일어나고, 백로그는 소비자 드레이닝이 있을 때만 비워져요. 대량의 데이터를 저장하려면 일반적으로 RAID 컨트롤러가 있는 여러 HDD가 포함된 구성이 돼요.
4단계: 브로커 배포
메타데이터 저장소를 설정하고, 클러스터 메타데이터를 초기화하고, BookKeeper bookies를 가동하면 브로커를 배포할 수 있어요.
브로커 구성
conf/broker.conf 구성 파일을 사용해 브로커를 구성할 수 있어요.
브로커 구성의 가장 중요한 요소는 각 브로커가 로컬 메타데이터 저장소와 configuration store를 모두 인지하고 있는지 확인하는 거예요. metadataStoreUrl 파라미터가 로컬 메타데이터 저장소를 반영하고, configurationMetadataStoreUrl 파라미터가 configuration store를 반영하도록 설정했는지 확인하세요.
또한 clusterName 파라미터로 브로커가 속한 클러스터의 이름을 지정해야 해요. 추가로 클러스터 메타데이터 초기화 시 제공한 브로커와 웹 서비스 포트와 일치해야 해요 (특히 기본값이 아닌 다른 포트를 사용할 때).
Oxia(권장)를 사용하면 metadataStoreUrl은 클러스터 로컬 메타데이터 저장소, configurationMetadataStoreUrl은 인스턴스 전역 configuration store, bookkeeperMetadataServiceUri는 자체 네임스페이스를 사용해요:
metadataStoreUrl=oxia://oxia-1.example.com:6648/broker
configurationMetadataStoreUrl=oxia://oxia-config.example.com:6648/broker
bookkeeperMetadataServiceUri=metadata-store:oxia://oxia-1.example.com:6648/bookkeeper
다음은 ZooKeeper를 사용하는 예시 구성이에요:
# Local ZooKeeper servers
metadataStoreUrl=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
# Configuration store quorum connection string.
configurationMetadataStoreUrl=zk1.us-west.example.com:2184,zk2.us-west.example.com:2184,zk3.us-west.example.com:2184
clusterName=us-west
# Broker data port
brokerServicePort=6650
# Broker data port for TLS
brokerServicePortTls=6651
# Port to use to server HTTP request
webServicePort=8080
# Port to use to server HTTPS request
webServicePortTls=8443
브로커 하드웨어
Pulsar 브로커는 로컬 디스크를 사용하지 않으므로 특별한 하드웨어가 필요하지 않아요. 소프트웨어가 그것을 최대한 활용할 수 있도록 빠른 CPU와 10Gbps NIC를 선택하는 것이 좋아요.
브로커 서비스 시작
nohup과 함께 pulsar-daemon CLI 도구를 사용해 브로커를 백그라운드에서 시작할 수 있어요:
bin/pulsar-daemon start broker
pulsar broker로 브로커를 포그라운드에서도 시작할 수 있어요:
bin/pulsar broker
서비스 디스커버리
Pulsar 브로커에 연결하는 클라이언트는 단일 URL로 전체 Pulsar 인스턴스와 통신해야 해요.
자체 서비스 디스커버리 시스템을 사용할 수 있으며, 한 가지 요구 사항만 충족하면 돼요. 클라이언트가 Pulsar 클러스터의 엔드포인트로 HTTP 요청을 수행할 때(예: http://pulsar.us-west.example.com:8080), 클라이언트가 원하는 클러스터의 활성 브로커로 리다이렉트되어야 해요. DNS, HTTP 또는 IP 리다이렉트, 또는 다른 수단을 통해서요.
많은 스케줄링 시스템이 이미 서비스 디스커버리를 제공해요 Kubernetes 같은 대규모 배포 시스템에는 서비스 디스커버리 시스템이 내장돼 있어요. 그런 시스템에서 Pulsar를 실행한다면 자체 서비스 디스커버리 메커니즘을 제공할 필요가 없을 거예요.
관리 클라이언트와 검증
이 시점에서 Pulsar 인스턴스를 사용할 준비가 되어 있어요. 이제 각 클러스터의 관리 클라이언트 역할을 할 수 있는 클라이언트 머신을 구성할 수 있어요. 관리 클라이언트를 구성하려면 conf/client.conf 구성 파일을 사용할 수 있어요.
가장 중요한 것은 serviceUrl 파라미터를 클러스터의 올바른 서비스 URL로 설정하는 거예요:
serviceUrl=http://pulsar.us-west.example.com:8080/
새 테넌트 프로비저닝
Pulsar는 근본적으로 다중 테넌트 시스템으로 설계됐어요.
새 테넌트가 시스템을 사용하려면 새 테넌트를 만들어야 해요. pulsar-admin CLI 도구로 새 테넌트를 만들 수 있어요:
bin/pulsar-admin tenants create test-tenant \
--allowed-clusters us-west \
--admin-roles test-admin-role
이 명령에서 test-admin-role 역할로 식별되는 사용자는 test-tenant 테넌트의 구성을 관리할 수 있어요. test-tenant 테넌트는 us-west 클러스터만 사용할 수 있어요. 이제부터 이 테넌트는 자신의 리소스를 관리할 수 있어요.
테넌트를 만든 후에는 그 테넌트 안의 토픽에 대한 네임스페이스를 만들어야 해요.
첫 번째 단계는 네임스페이스를 만드는 거예요. 네임스페이스는 많은 토픽을 담을 수 있는 행정 단위예요. 일반적인 관행은 단일 테넌트의 각각 다른 사용 사례마다 네임스페이스를 만드는 거예요.
bin/pulsar-admin namespaces create test-tenant/ns1
테스트 프로듀서와 소비자
이제 메시지를 보내고 받을 준비가 모두 끝났어요. 시스템을 테스트하는 가장 빠른 방법은 pulsar-perf 클라이언트 도구를 사용하는 거예요.
방금 만든 네임스페이스의 토픽을 사용할 수 있어요. 토픽은 프로듀서나 소비자가 처음으로 사용하려 할 때 자동으로 생성돼요.
이 경우 토픽 이름은 다음과 같을 수 있어요:
persistent://test-tenant/ns1/my-topic
토픽에 구독을 만들고 메시지를 기다리는 소비자를 시작해요:
bin/pulsar-perf consume persistent://test-tenant/ns1/my-topic
고정 속도로 메시지를 게시하고 10초마다 stats를 보고하는 프로듀서를 시작해요:
bin/pulsar-perf produce persistent://test-tenant/ns1/my-topic
토픽 stats를 보고하려면:
bin/pulsar-admin topics stats persistent://test-tenant/ns1/my-topic
더 알아보기 (Learn more)
- 바메탈 배포 — 단일 클러스터 배포를 먼저 익혀요.
- 지오레플리케이션 관리 — 다중 클러스터 간 데이터 복제를 구성해요.
- Kubernetes 배포 — 관리형 환경에서 실행해요.
- 테넌트 관리 — 테넌트와 네임스페이스를 다뤄요.