Apache Pulsar 3.x/4.x ์ต์ ๊ธฐ์ค ์ด๋ณด์ ์๋ฒฝ ๊ฐ์ด๋: Docker Standalone 1์ด ์ค์น, ๋ธ๋ก์ปค-BookKeeper ์ปดํจํธ/์คํ ๋ฆฌ์ง ๋ถ๋ฆฌ ์ํคํ
์ฒ, ๋ฉํฐ ํ
๋์ ํ ํฝ ๋ค์์คํ์ด์ค, 4๋ ๊ตฌ๋
๋ชจ๋(Exclusive/Failover/Shared/Key_Shared), ์ง์ฐ ๋ฉ์์ง(Delayed Delivery), Tiered Storage, Spring Boot ์ฐ๋ ๋ฐ pulsar-admin CLI ์นํธ์ํธ
## 1. ํ์ ์ฌ์ ์ค์น ์๊ฑด & ํ๊ฒฝ ๊ตฌ์ฑ (Prerequisites)
Apache Pulsar๋ ์ฐจ์ธ๋ ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ ๋ถ์ฐ ๋ฉ์์ง ๋ฐ ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ ํ๋ซํผ์
๋๋ค. ์ด๋ณด์๋ 1๋ถ ์์ ์์ ์ ๋ก์ปฌ PC์์ ์ฆ์ ์ค์ตํ ์ ์๋๋ก ๊ฐ์ฅ ๊ถ์ฅ๋๋ Docker Standalone ๊ตฌ๋๋ถํฐ ์์ํฉ๋๋ค.
### ๐ณ 1. Docker๋ก 1์ด ๋ง์ ์คํํ๊ธฐ (๊ฐ๋ ฅ ์ถ์ฒ)
Pulsar ๊ณต์ ์ฌ์ธ์ Standalone ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ๋ฉด ๋ธ๋ก์ปค, BookKeeper(์ ์ฅ์), ZooKeeper(๋ฉํ๋ฐ์ดํฐ)๊ฐ ๋จ์ผ ์ปจํ
์ด๋๋ก ์ฆ์ ๊ธฐ๋๋ฉ๋๋ค.
```bash
# Apache Pulsar Standalone ์ปจํ
์ด๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ
docker run -d --name pulsar-standalone \
-p 6650:6650 \
-p 8080:8080 \
apachepulsar/pulsar:3.3.0 \
bin/pulsar standalone
```
- **6650 ํฌํธ**: ๋ฐ์ด๋๋ฆฌ ํ๋กํ ์ฝ ํต์ ํฌํธ (Producer, Consumer ์ ํ๋ฆฌ์ผ์ด์
์ฐ๊ฒฐ)
- **8080 ํฌํธ**: REST Admin ๊ด๋ฆฌ์ API ๋ฐ ๋ฉํธ๋ฆญ ์กฐํ ํฌํธ
- **์ ์ ๊ธฐ๋ ํ์ธ**:
```bash
# REST API ํฌ์ค์ฒดํฌ โ "ok" ์๋ต ํ์ธ
curl http://localhost:8080/admin/v2/clusters
```
---
### ๐ป 2. ๋ก์ปฌ ๋ฐ์ด๋๋ฆฌ ์ง์ ์ค์น (Docker ๋ฏธ์ฌ์ฉ ์)
Pulsar๋ **Java 17 ๋๋ 21+** ๋ฐํ์ ํ๊ฒฝ์ด ์ฌ์ ์ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
```bash
# 1. ๊ณต์ ์์ถ ์์นด์ด๋ธ ๋ค์ด๋ก๋ ๋ฐ ์์ถ ํด์
wget https://archive.apache.org/dist/pulsar/pulsar-3.3.0/apache-pulsar-3.3.0-bin.tar.gz
tar -xzf apache-pulsar-3.3.0-bin.tar.gz
cd apache-pulsar-3.3.0
# 2. Standalone ๋ชจ๋๋ก ๋ก์ปฌ ์๋น์ค ์์
bin/pulsar standalone
```
---
### ๐ฆ 3. ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
์ค์ต์ ์ฌ์ฉํ ์ธ์ด์ ๊ณต์ Pulsar ๋๋ผ์ด๋ฒ๋ฅผ ์ค์นํฉ๋๋ค:
```bash
# Python ํด๋ผ์ด์ธํธ
pip install pulsar-client
# Node.js ํด๋ผ์ด์ธํธ
npm install pulsar-client
# Java / Spring Boot (Gradle build.gradle)
# implementation 'org.springframework.boot:spring-boot-starter-pulsar'
# ๋๋ implementation 'org.apache.pulsar:pulsar-client:3.3.0'
```
---
## 2. Apache Pulsar ํต์ฌ ๊ฐ๋
& ์ํคํ
์ฒ (Mental Model)
๊ธฐ์กด Kafka์์ ๊ฐ์ฅ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด๋ **์ปดํจํธ ๊ณ์ธต(Stateless Broker)**๊ณผ **์คํ ๋ฆฌ์ง ๊ณ์ธต(Stateful BookKeeper)**์ด ๋ฌผ๋ฆฌ์ ์ผ๋ก ์์ ํ ๋ถ๋ฆฌ๋์ด ์๋ค๋ ์ ์
๋๋ค.
```text
[Apache Pulsar ๊ณ์ธต ๋ถ๋ฆฌ ์ํคํ
์ฒ]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Serving / Compute Layer โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Pulsar Broker 1 โ โ Pulsar Broker 2 โ โ (Stateless: ์ํ ์์)
โ โ (๋ฉ์์ง ์์ & ๋ผ์ฐํ
)โ โ (ํธ๋ํฝ์ ๋ฐ๋ผ ์ค์ผ์ผ) โ โ
โ โโโโโโโโโโโโโฌโโโโโโโโโโโโ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ
โ Storage Layer (Apache BookKeeper) โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Bookie 1 (๋์คํฌ)โ โ Bookie 2 (๋์คํฌ)โ โ Bookie 3 โ โ (Stateful: ์ธ๊ทธ๋จผํธ ์ ์ฅ)
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### ๐ท๏ธ 1. ๋ฉํฐ ํ
๋์ ํ ํฝ ๊ณ์ธต ๊ตฌ์กฐ
Pulsar์ ๋ชจ๋ ํ ํฝ URL์ ์ฒด๊ณ์ ์ธ ๊ณ์ธตํ ํ์ค ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฆ
๋๋ค:
```text
{persistence}://{tenant}/{namespace}/{topic}
์: persistent://my-company/ecommerce/order-events
```
- **persistence**: `persistent`(BookKeeper ๋์คํฌ ์๊ตฌ ์ ์ฅ) ๋๋ `non-persistent`(์ธ๋ฉ๋ชจ๋ฆฌ ํ๋ฐ์ฑ ๊ณ ์ ์ ์ก).
- **tenant (ํ
๋ํธ)**: ๊ธฐ์
, ๋ถ์ ๋๋ ์กฐ์ง ๋จ์์ ๊ฒฉ๋ฆฌ ๊ณต๊ฐ (๋ณด์ ์ธ์ฆ ๋ฐ ๋ฆฌ์์ค ํ ๋น).
- **namespace (๋ค์์คํ์ด์ค)**: ์ค์ ๋จ์ (TTL, ๋ณด์กด ์ฃผ๊ธฐ, ๋ณต์ ์ ์ฑ
, ์ํธํ ์ค์ ).
- **topic (ํ ํฝ)**: ์ค์ ๋ฉ์์ง๊ฐ ์ ์ก๋๋ ์ฑ๋.
### ๐ Apache Kafka vs Apache Pulsar ๋น๊ต
| ๋น๊ต ํญ๋ชฉ | Apache Kafka | Apache Pulsar |
| :--- | :--- | :--- |
| **์ํคํ
์ฒ** | ์ปดํจํธ-์คํ ๋ฆฌ์ง ์ผ์ฒดํ (๋ชจ๋๋ฆฌ์ ๋ธ๋ก์ปค) | ์ปดํจํธ(Broker)์ ์คํ ๋ฆฌ์ง(BookKeeper) ์๋ฒฝ ๋ถ๋ฆฌ |
| **์ค์ผ์ผ์์ ํ์ฅ** | ๋ธ๋ก์ปค ์ถ๊ฐ ์ ํํฐ์
๋ฐ์ดํฐ ์ฌํ ๋น(Rebalance) ๊ณ ๋น์ฉ | ๋ธ๋ก์ปค๋ ์ฆ์ ์ถ๊ฐ ๊ฐ๋ฅ, ๋ฐ์ดํฐ ์ด๋ ์์ |
| **๋ฉ์์ง ๋ชจ๋ธ** | ์ค์ง ์์ฐจ ๋ก๊ทธ(Log) ๊ธฐ๋ฐ ์คํธ๋ฆฌ๋ฐ | **์คํธ๋ฆฌ๋ฐ(Kafkaํ) + ํ์(RabbitMQํ)** ๋์ ์ง์ |
| **๋ฐ์ดํฐ ๋ณด๊ด ๋น์ฉ** | ๊ณ ๊ฐ์ SSD ๋ธ๋ก์ปค ๋์คํฌ์ ์ฅ๊ธฐ ๋ณด๊ด | **Tiered Storage**: ์ค๋๋ ๋ฐ์ดํฐ AWS S3๋ก ์๋ ์ด์ |
| **์ง์ฐ ์ ์ก** | ์ง์ํ์ง ์์ (๋ณ๋ ํ ํฝ/์ค์ผ์ค๋ฌ ํ์) | **๋ค์ดํฐ๋ธ ์ง์** (`deliverAfter`, `deliverAt`) |
---
## 3. 4๋ ๊ตฌ๋
๋ชจ๋ (Subscription Types) ์๋ฒฝ ์ดํด
Pulsar๋ ํ๋์ ํ ํฝ์ ๋ํด ์ฌ๋ฌ ์ ํ๋ฆฌ์ผ์ด์
์ด ๊ฐ์์ ๋น์ฆ๋์ค ์๊ตฌ์ ๋ง์ถ์ด ๊ตฌ๋
๋ฐฉ์์ ์ ํํ ์ ์์ต๋๋ค.
```text
[4๋ ๊ตฌ๋
๋ชจ๋ ๋น๊ต ๋ค์ด์ด๊ทธ๋จ]
1. Exclusive : [Topic] โโโบ [Consumer A] (๋จ 1๊ฐ๋ง ํ์ฉ, ์ ๋ ์์ ๋ณด์ฅ)
2. Failover : [Topic] โโโบ [Consumer A(Active)] โโ[์ฅ์ ์]โโโบ [Consumer B(Standby)]
3. Shared : [Topic] โโโบ [Consumer A] (๋ผ์ด๋ ๋ก๋น ์์
ํ์ ๋ถ๋ฐฐ)
โโโบ [Consumer B]
4. Key_Shared : [Topic] โโโบ [Consumer A] (Key 1, Key 3 ์ ๋ด)
โโโบ [Consumer B] (Key 2, Key 4 ์ ๋ด)
```
| ๊ตฌ๋
๋ชจ๋ | ๋์ ๋ฐฉ์ | ์ฃผ์ ์ค๋ฌด ํ์ฉ์ฒ |
| :--- | :--- | :--- |
| **Exclusive (๋จ๋
)** | ํ๋์ ํ์ **์ค์ง 1๊ฐ์ ์ปจ์๋จธ๋ง ์ฐ๊ฒฐ ํ์ฉ**. ๋ค๋ฅธ ์ปจ์๋จธ ์ ์ ์ ์๋ฌ ๋ฐ์ | ๋จ์ผ ํํฐ์
์๊ฒฉํ ์์ ๋ณด์ฅ ์์คํ
|
| **Failover (์ฅ์ ์กฐ์น)** | ์ฌ๋ฌ ์ปจ์๋จธ๊ฐ ๋๊ธฐํ๋ค๊ฐ ์ฃผ ์ปจ์๋จธ๊ฐ ๋ค์ด๋๋ฉด **์๋น ์ปจ์๋จธ๊ฐ ์๋ ์น๊ณ** | ๋ง์คํฐ-์ฌ๋ ์ด๋ธ ๊ณ ๊ฐ์ฉ์ฑ ํ์ดํ๋ผ์ธ |
| **Shared (๊ณต์ - ํ ๋ชจ๋)** | ๋ฉ์์ง๋ฅผ ๋ผ์ด๋ ๋ก๋น ๋ฐฉ์์ผ๋ก ์ฌ๋ฌ ์ปจ์๋จธ์๊ฒ **์์
ํ์ฒ๋ผ ๊ณตํ ๋ถ๋ฐฐ** | RabbitMQ ๊ฐ์ ๋๊ท๋ชจ ๋ณ๋ ฌ ๋ฐฑ์๋ ์์
์์ปค |
| **Key_Shared (ํค ๊ธฐ๋ฐ ๊ณต์ )** | ๋ฉ์์ง์ **๋์ผ ํค(Partition Key)๋ ํญ์ ๋์ผํ ์ปจ์๋จธ์๊ฒ๋ง ์ ๋ฌ** | ์ ์ ๋ณ ์์๋ ๋ณด์ฅํ๋ฉด์ ์ ์ฒด ์์ปค๋ ๋ฌดํ ์ํ ํ์ฅ |
---
## 4. [์ด๋ณด์ 1๋จ๊ณ] ํฌ๋ก์๋: ๊ฐ์ฅ ๋จ์ํ ๋ฉ์์ง ์ก์์ (Python)
Pulsar ํด๋ผ์ด์ธํธ๋ฅผ ์์ฑํ๊ณ ํ ํฝ์ ๋ฉ์์ง๋ฅผ ๋ฐํ ๋ฐ ์์ ํ๋ ๊ธฐ๋ณธ ์์ ์
๋๋ค.
### ๐ค ์์ฐ์: `producer.py`
```python
import pulsar
# 1. Pulsar ๋ธ๋ก์ปค ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ (๊ธฐ๋ณธ ๋ฐ์ด๋๋ฆฌ ํฌํธ: 6650)
client = pulsar.Client('pulsar://localhost:6650')
# 2. ์์ฐ์(Producer) ์์ฑ
producer = client.create_producer('persistent://public/default/hello-pulsar')
# 3. ๋ฉ์์ง ๋ฐํ (๋ฌธ์์ด ๋ฐ์ดํธ ์ ์ก)
message_content = "๋ฐ๊ฐ์ต๋๋ค! Apache Pulsar ์ฒซ ์ด๋ฒคํธ์
๋๋ค."
msg_id = producer.send(message_content.encode('utf-8'))
print(f" [V] ๋ฉ์์ง ๋ฐํ ์ฑ๊ณต! Message ID: {msg_id}")
# 4. ๋ฆฌ์์ค ์ ๋ฆฌ
producer.close()
client.close()
```
### ๐ฅ ์๋น์: `consumer.py`
```python
import pulsar
client = pulsar.Client('pulsar://localhost:6650')
# ์๋น์(Consumer) ์์ฑ (๊ตฌ๋
๋ชจ๋: Shared ๋ชจ๋)
consumer = client.subscribe(
topic='persistent://public/default/hello-pulsar',
subscription_name='my-shared-sub',
consumer_type=pulsar.ConsumerType.Shared
)
print(" [*] ๋ฉ์์ง ์์ ๋๊ธฐ ์ค... (์ข
๋ฃ: CTRL+C)")
while True:
try:
# ๋ฉ์์ง ๋๊ธฐ ๋ฐ ์์
msg = consumer.receive()
print(f" [OK] ์์ ๋ ๋ด์ฉ: {msg.data().decode('utf-8')} (ID: {msg.message_id()})")
# ๐ ์ค์: ๋ธ๋ก์ปค์ ์ ์ ์์ ํ์ธ(ACK) ํต๋ณด
consumer.acknowledge(msg)
except Exception as e:
print("์์ ์ค๋ฅ:", e)
break
consumer.close()
client.close()
```
---
## 5. [์ด๋ณด์ 2๋จ๊ณ] ํค ๊ธฐ๋ฐ ๋ฉ์์ง & Key_Shared ๋ณ๋ ฌ ํ์ฅ
์ฃผ๋ฌธ ๋ฒํธ๋ ์ ์ ID๋ฅผ ํค(`partition_key`)๋ก ์ค์ ํ์ฌ, ์ฌ์ฉ์๋ณ ์ด๋ฒคํธ ์์๋ฅผ ์ฒ ์ ํ ์งํค๋ฉด์๋ ์์ญ ๋์ ์๋ฒ๊ฐ ๋ณ๋ ฌ ์ฒ๋ฆฌํ๋๋ก ๋ง๋๋ ํจํด์
๋๋ค.
```python
import pulsar
client = pulsar.Client('pulsar://localhost:6650')
producer = client.create_producer('persistent://public/default/orders-topic')
# ์ ์ ID๋ฅผ partition_key๋ก ๋ถ์ฌํ์ฌ ๋ฐํ
orders = [
{"user_id": "user_A", "order": "์ฃผ๋ฌธ ์์ฑ"},
{"user_id": "user_B", "order": "์ํ ๊ฒฐ์ "},
{"user_id": "user_A", "order": "๋ฐฐ์ก์ง ์
๋ ฅ"}, # user_A๋ ์ ์ฃผ๋ฌธ ์์ฑ๊ณผ ๋์ผ ์ปจ์๋จธ๋ก ๊ฐ
]
for item in orders:
producer.send(
item["order"].encode('utf-8'),
partition_key=item["user_id"] # ๐ ํค ์ง์
)
print(f" [๋ฐํ ์๋ฃ] ํค: {item['user_id']} | ๋ฐ์ดํฐ: {item['order']}")
producer.close()
client.close()
```
---
## 6. [์ด๋ณด์ 3๋จ๊ณ] ์ง์ฐ ๋ฉ์์ง ์ ์ก (Delayed / Scheduled Messaging)
๋ณต์กํ ์ธ๋ถ ์ค์ผ์ค๋ฌ๋ Cron ์์ด, "์ง๊ธ๋ถํฐ 10๋ถ ๋ค์ ์ฒ๋ฆฌํด์ค"๋ผ๋ ์์
์ ๋ธ๋ก์ปค ์์ค์์ ๋ค์ดํฐ๋ธ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
```python
import pulsar
import time
client = pulsar.Client('pulsar://localhost:6650')
producer = client.create_producer('persistent://public/default/delayed-tasks')
# ๐ 10์ด ํ์ ์๋น์์๊ฒ ๋ฐฐ๋ฌ๋๋๋ก ์ค์ (deliver_after)
producer.send(
b'Order #5524: 10์ด ๋ฏธ๊ฒฐ์ ์๋ ์ทจ์ ์์
',
deliver_after=10 # ์ด ๋จ์ ์ง์ฐ ์ง์ (deliver_at์ ํ์์คํฌํ)
)
print(" [V] ์ง์ฐ ๋ฉ์์ง๊ฐ ๋ฑ๋ก๋์์ต๋๋ค. 10์ด ํ์ ์ปจ์๋จธ์๊ฒ ๋ํ๋ฉ๋๋ค.")
producer.close()
client.close()
```
---
## 7. ๊ณ์ธตํ๋ ์คํ ๋ฆฌ์ง (Tiered Storage) ์๋ ์คํ๋ก๋
๋ธ๋ก์ปค ๋ก์ปฌ SSD ์ฉ๋์ด ์ฐจ์ค๋ฅด๋ฉด ์ค๋๋ ๋ฉ์์ง ์ธ๊ทธ๋จผํธ๋ฅผ **AWS S3, Google Cloud Storage, Azure Blob, MinIO** ๋ฑ ์ ๋ ดํ ๊ฐ์ฒด ์คํ ๋ฆฌ์ง๋ก ๋ฌด์ค๋จ ์๋ ์ด์ ํฉ๋๋ค.
- ์๋น์๋ ๋ฉ์์ง๊ฐ S3์ ์๋ ๋ก์ปฌ ๋์คํฌ์ ์๋ **๋์ผํ ์คํ์
API๋ก ํฌ๋ช
ํ๊ฒ ์กฐํ(Transparent Read)**ํ ์ ์์ต๋๋ค.
```bash
# ๋ค์์คํ์ด์ค์ 10GB ์ด๊ณผ ์ ๋๋ 2์๊ฐ ์ด๊ณผ ์ S3๋ก ์๋ ์คํ๋ก๋ ์ ์ฑ
์ค์
bin/pulsar-admin namespaces set-offload-threshold \
--size-threshold 10G \
public/default
```
---
## 8. ์ค๋ฌด ๋ฐฑ์๋ ์ฐ๋: Spring Boot (Spring for Apache Pulsar)
์ต์ Spring Boot 3.2+ ํ๊ฒฝ์์ ๊ณต์ ์ง์ํ๋ Spring for Apache Pulsar ์ฐ๋ ํ์ค์
๋๋ค.
### ๐ `application.yml`
```yaml
spring:
pulsar:
client:
service-url: pulsar://localhost:6650
producer:
topic-name: persistent://public/default/spring-topic
consumer:
subscription-name: spring-sub
subscription-type: shared # exclusive, failover, shared, key_shared
```
### โ Spring ์๋น์ค & ๋ฆฌ์ค๋ ์ฝ๋
```java
@Service
public class OrderEventService {
@Autowired
private PulsarTemplate<String> pulsarTemplate;
// 1. ๋ฉ์์ง ๋ฐํ
public void publishOrder(String orderId) {
pulsarTemplate.send("persistent://public/default/spring-topic", orderId);
}
// 2. ๋ฉ์์ง ์์ ๋ฆฌ์ค๋
@PulsarListener(
topics = "persistent://public/default/spring-topic",
subscriptionName = "order-processing-sub",
subscriptionType = SubscriptionType.Shared
)
public void handleOrder(String orderId) {
System.out.println("Spring Pulsar ์์ ์ฒ๋ฆฌ: " + orderId);
}
}
```
---
## 9. Pulsar CLI ํต์ฌ ๊ด๋ฆฌ ๋ช
๋ น์ด ์นํธ์ํธ (`pulsar-admin`)
Pulsar ๋ธ๋ก์ปค ์ปจํ
์ด๋ ๋ด๋ถ ๋๋ ์ค์น ๋๋ ํ ๋ฆฌ์์ ์คํํ๋ ํ์ ๊ด๋ฆฌ ๋ช
๋ น์ด์
๋๋ค:
```bash
# 1. ํด๋ฌ์คํฐ ๋ฐ ํ
๋ํธ ๊ด๋ฆฌ
bin/pulsar-admin clusters list
bin/pulsar-admin tenants create my-tenant
bin/pulsar-admin tenants list
# 2. ๋ค์์คํ์ด์ค ์์ฑ ๋ฐ ์ ์ฑ
์ค์
bin/pulsar-admin namespaces create my-tenant/my-namespace
bin/pulsar-admin namespaces set-retention my-tenant/my-namespace --size 50G --time 7d
# 3. ํ ํฝ ๊ด๋ฆฌ ๋ฐ ์ค์๊ฐ ํต๊ณ ์กฐํ
bin/pulsar-admin topics list my-tenant/my-namespace
bin/pulsar-admin topics stats persistent://my-tenant/my-namespace/my-topic
# 4. ํ ํฝ ํํฐ์
์์ฑ (๋๊ท๋ชจ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ฉ)
bin/pulsar-admin topics create-partitioned-topic persistent://my-tenant/my-namespace/logs --partitions 4
# 5. ์๋ธ์คํฌ๋ฆฝ์
๋ฉ์์ง ๊ฐ์ ์คํ์
์ด๊ธฐํ (๋๊ฐ๊ธฐ)
bin/pulsar-admin topics reset-cursor persistent://my-tenant/my-namespace/my-topic \
--subscription my-sub --time 1h
```
---
## 10. ์ค๋ฌด ์ฃผ์์ฌํญ & ํ๋ก๋์
์ฒดํฌ๋ฆฌ์คํธ
| ์ ๊ฒ ํญ๋ชฉ | ๊ถ์ฅ ์ฌํญ | ์ด์ |
| :--- | :--- | :--- |
| **๊ตฌ๋
๋ชจ๋ ์ ํฉ์ฑ ๊ฒํ ** | ์์๊ฐ ํ์ํ๋ฉด `Exclusive` ๋๋ `Key_Shared`, ๋ณ๋ ฌ ํ์์ `Shared` ์ ํ | ์๋ชป๋ ๊ตฌ๋
๋ชจ๋ ์ ํ ์ ๋ฉ์์ง ์ฒ๋ฆฌ ์์ ๋ค์ํด ๋ฐ์ |
| **์๋ ACK ๋๋ฝ ๊ธ์ง** | ๋ฉ์์ง ์์ ํ ์ฒ๋ฆฌ ์ฑ๊ณต ์ ๋ฐ๋์ `consumer.acknowledge(msg)` ํธ์ถ | ๋ฏธ์น์ธ ๋ฉ์์ง๊ฐ ๋์ ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ฐ ๋ฐฑ๋ก๊ทธ ๊ธ์ฆ |
| **BookKeeper ๋์คํฌ ๋ชจ๋ํฐ๋ง** | Bookie ๋์คํฌ ์ฌ์ฉ๋ฅ ์ด 85%๋ฅผ ๋์ง ์๋๋ก ๊ด๋ฆฌ | ๋์คํฌ ์๊ณ์น ์ด๊ณผ ์ ๋ธ๋ก์ปค ์ ์ฒด๊ฐ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ฐจ๋จ๋จ |
| **Tiered Storage ํ์ฑํ** | 1์ฃผ์ผ ์ด์ ์ฅ๊ธฐ ๋ณด๊ด์ด ํ์ํ ๋ก๊ทธ/์ด๋ฒคํธ๋ S3 ์คํ๋ก๋ฉ ์ ์ฉ | ๊ณ ๋น์ฉ NVMe/SSD ํด๋ฌ์คํฐ ์คํ ๋ฆฌ์ง ๋น์ฉ์ 80% ์ด์ ์ ๊ฐ |
| **ํ ํฝ ๋ค์ด๋ฐ ํ์คํ** | `persistent://{tenant}/{namespace}/{topic}` ์ฒด๊ณ๋ฅผ ์๊ฒฉํ ์ค์ | ๋ฉํฐ ํ
๋ํธ ๊ถํ ์ ์ด ๋ฐ ๋ค์์คํ์ด์ค๋ณ TTL/Quota ์ ์ฉ์ ๊ธฐ๋ณธ |
์๊ฒฌ ๋ฐ ์ง๋ฌธ
0์์ง ๋ฑ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋๊ธ์ ๋จ๊ฒจ๋ณด์ธ์!
๋๊ธ ์์
๋๊ธ ์ญ์