κΈ°κ°: 2025λ 7μ 28μΌ ~ 9μ 26μΌ (9μ£Ό)
λͺ©ν: Kafka ν΅μ¬ κ°λ μ λ΄μ λ©μμ§ ν MVP ꡬν + λΆμ° μμ€ν μ€κ³ μλ μ΅λ
- 25λ 7μ 27μΌ μ€κ³ λ°ν μλ£
- 25λ 9μ 27μΌ νλ‘μ νΈ λ°ν μλ£(TODO)
κΈ°μ‘΄ μμ€ν μμ μλΉμ€ κ° μ§μ νΈμΆ λ°©μμ λ€μκ³Ό κ°μ νκ³λ₯Ό κ°μ§λ€:
- κ²°ν©λ: νλ‘λμμ 컨μλ¨Έ κ° κ°κ²°ν©μΌλ‘ μλΉμ€ λ³κ²½ μ μν₯λκ° νΌ
- νμ₯μ±: λμ©λ μ²λ¦¬ μ λμμ± ν보 μ΄λ €μ
- μ λ’°μ±: λ€νΈμν¬ μ΄μ λ°μ μ λ©μμ§ μ μ€ κ°λ₯
- 볡μλ ₯: μ₯μ μ μ 체 νλ¦ μ€λ¨ (μ: λκΈ° νΈμΆ μ€ν¨ μ ν)
| νλͺ© | λͺ©ν μμΉ | ν μ€νΈ 쑰건 |
|---|---|---|
| μ²λ¦¬λ (Throughput) | β₯ 5,000 msg/s (1KB λ©μμ§ κΈ°μ€) | λ¨μΌ λΈλ‘컀 + 2νν°μ (HTTP/JSON νκ³ κ³ λ €) |
| μ§μ°μκ° (Latency) | νκ· β€ 100ms, P95 β€ 200ms | E2E μΈ‘μ (ProducerβConsumer) |
| λ΄κ΅¬μ± | μΉμΈλ λ©μμ§ 100% 볡ꡬ 보μ₯ | WAL κΈ°λ° μμ 볡ꡬ ν μ€νΈ |
| μ₯μ 볡ꡬ μκ° | β€ 30μ΄ (μλ 볡ꡬ ν¬ν¨) | λΈλ‘컀 κ°μ μ’ λ£ ν 볡ꡬ μλλ¦¬μ€ |
| μμ 보μ₯ | νν°μ λ΄ 100% μμ 보μ₯ | λ©μμ§ μμ ν μ€νΈ |
- ν ν½/νν°μ ꡬ쑰: hash(key) % partitions λΌμ°ν
- λ©μμ§ λ°°μΉ λ° μ μ‘: λ€νΈμν¬ ν¨μ¨μ± ν₯μ (100κ° λλ 10ms λ¨μ)
- μ€νμ κΈ°λ° μλΉ λ° μ¬μ²λ¦¬: μ₯μ μ νΉμ μ§μ λΆν° μ¬μμ
- λ©μμ§ μμν (WAL): λΈλ‘컀 μ¬μμ νμλ λ°μ΄ν° μ μ§
- Consumer Group μ§μ: λ©μμ§ λ³λ ¬ μ²λ¦¬ λ° λ‘λ λ°Έλ°μ±
- Long Polling κΈ°λ° Pull: μ€μκ°μ±κ³Ό ν¨μ¨μ± κ· ν
- 리λ-νλ‘μ 볡μ : λ°μ΄ν° μ΄μ€ν (λ¨μ ꡬν)
- Heartbeat & νν°μ ν λΉ μ μ§: Consumer μμ‘΄ νμΈ
- κ³ μ±λ₯ μ²λ¦¬: 5K msg/s μ΄μ (HTTP/JSON μ μ½ κ³ λ €)
- νκ· μ§μ°μκ°: 100ms μ΄ν
- μ₯μ 볡ꡬ: μλλ¦¬μ€ κΈ°λ° λ³΅κ΅¬ λ§€λ΄μΌ
- ν μ€νΈ κΈ°λ° κ°λ°: TDD μ μ©
- νμ₯ κ°λ₯ μν€ν μ²: Phase 2μμ gRPC/TCP λ§μ΄κ·Έλ μ΄μ
- λ‘κ·Έ μμ§: μ ν리μΌμ΄μ λ‘κ·Έ β μ€μ μ μ₯μ μ λ¬
- μ΄λ²€νΈ μ²λ¦¬: μ£Όλ¬Έ μμ± μ΄λ²€νΈ β μ¬κ³ /κ²°μ μλΉμ€ μλ¦Ό
- λ°μ΄ν° νμ΄νλΌμΈ: μ€μκ° λ°μ΄ν° β λΆμ μμ€ν μ λ¬
flowchart TD
Producer["Producer(CLI or SDK)"] --> Broker1["Broker-1(Leader)"]
Broker1 --> WAL1[(WAL File)]
Broker1 --> Broker2["Broker-2(Follower)"]
Broker2 --> WAL2[(WAL File)]
Consumer1["Consumer-1(Group-A)"] --> Broker1
Consumer2["Consumer-2(Group-B)"] --> Broker1
Admin[Admin CLI] --> Broker1
| μ»΄ν¬λνΈ | μν | μ€λͺ |
|---|---|---|
| Producer | λ©μμ§ μ μ‘, νν°μ λ | key κΈ°λ° λΌμ°ν (hash(key) % N) |
| Broker | λ©μμ§ μμ /μ μ₯/μλΉ | WAL κΈ°λ° μμμ±, Consumer μμ² μλ΅ |
| Consumer | λ©μμ§ Pull, μ€νμ κ΄λ¦¬ | Long Polling, 컨μλ¨Έ κ·Έλ£Ή μ§μ |
| Coordinator (MVP λ¨μν) | Consumer Group λ° ν λΉ μν μ μ§ | μΈλ©λͺ¨λ¦¬ ꡬν, Heartbeatλ‘ λ¦¬λ°Έλ°μ± κ°μ§ |
| WAL | λ©μμ§ λ³΅κ΅¬μ© λ‘κ·Έ | offset, checksum ν¬ν¨ |
| Replication | 리λβνλ‘μ λΉλκΈ° 볡μ | 리λ κΈ°μ€ μ΅μ λ©μμ§ μ λ¬ |
| νλͺ© | MVP μ€κ³ κΈ°μ€ |
|---|---|
| Group Metadata | λΈλ‘컀 μΈλ©λͺ¨λ¦¬λ‘ κ΄λ¦¬ (etcd λ± μΈλΆ λꡬ μμ) |
| Consumer Registration | group_id, consumer_idλ‘ λ±λ‘ |
| Heartbeat API | μ£ΌκΈ°μ νΈμΆ (μ: 5μ΄) μμΌλ©΄ 리밸λ°μ± |
| Partition Assignment | Round-Robin λ°©μ λ¨μ ꡬν |
| Failover λμ | heartbeat λλ½ μ β νν°μ μ¬ν λΉ |
// λ©μμ§ κ΅¬μ‘°
type Message struct {
Topic string `json:"topic"`
Partition int32 `json:"partition"`
Offset int64 `json:"offset"`
Key string `json:"key,omitempty"`
Value string `json:"value"` // MVPμμλ stringμΌλ‘ λ¨μν
Timestamp int64 `json:"timestamp"`
Size int32 `json:"size"` // λ©μμ§ ν¬κΈ° (KB μ νμ©)
}
// WAL μνΈλ¦¬
type WALEntry struct {
Offset int64 `json:"offset"`
Message Message `json:"message"`
Checksum uint32 `json:"checksum"` // CRC32 체ν¬μ¬
}
// νν°μ
ꡬ쑰
type Partition struct {
ID int32 `json:"id"`
Messages []Message `json:"-"` // μΈλ©λͺ¨λ¦¬
OffsetIndex map[int64]int `json:"-"` // μ€νμ
β μΈλ±μ€
LastOffset int64 `json:"last_offset"`
WALPath string `json:"wal_path"`
MaxSize int64 `json:"max_size"` // νν°μ
μ΅λ ν¬κΈ° (MB)
mutex sync.RWMutex `json:"-"` // λμμ± μ μ΄
}| νλͺ© | gafka | Kafka |
|---|---|---|
| λ©μμ§ κ²½λ‘ | Producer β Broker (Leader) β WAL β Consumer | μ μ¬ |
| 볡μ λ°©μ | 리λ β νλ‘μ λΉλκΈ° | ISR κΈ°λ° λ³΅μ |
| Offset κ΄λ¦¬ | In-memory + μΌλΆ API μ§μ | Zookeeper or Kafka Internal |
| ν΅μ λ°©μ | HTTP + JSON | TCP + Binary Protocol |
| λ©μμ§ μ μ‘ λ°©μ | Batching μ§μ | Batching + Compression + Zero-Copy |
| μ₯μ 볡ꡬ | WAL κΈ°λ° μλ 볡ꡬ | μλ 리λ μ μΆ + ISR 볡μ |
- HTTP κΈ°λ° ν΅μ : MVP κ°λ° μλλ₯Ό μν μλλ μ νμ΄μ§λ§, μ±λ₯ νκ³ μ‘΄μ¬
- Coordinator λ¨μν: μΈλΆ μμ€ν (e.g., Zookeeper) μ κ±° β ꡬ쑰 λ¨μν
- WAL μ€κ³: λ¨μΌ νμΌ κΈ°λ° WALλ‘ μ΅μ μμμ± κ΅¬ν, ν₯ν μΈκ·Έλ¨ΌνΈ κ΄λ¦¬ νμ
| νλͺ© | κΈ°μ | μ΄μ |
|---|---|---|
| μΈμ΄ | Go 1.22 | λΉ λ₯Έ λμμ± μ²λ¦¬, κ°λ¨ν λ°°ν¬ |
| ν΅μ | HTTP + JSON | κ°λ° νΈμμ± μ°μ (μ±λ₯ μ μ½ μΈμ§) |
| μ μ₯ | In-memory + WAL νμΌ | μμμ±κ³Ό μ±λ₯ κ° κ· ν |
| CLI | Cobra | 컀맨λ λΌμΈ λꡬ κ°λ° |
| ν μ€νΈ | go test |
TDD κΈ°λ° κ°λ° |
| μ±λ₯ μΈ‘μ | wrk, custom tool | Throughput, P95 μΈ‘μ |
| λ‘κΉ | logrus | λ¨κ³λ³ λ‘κΉ μ²λ¦¬ |
| μ μ½ μμ | μν₯ | μν λ°©μ |
|---|---|---|
| HTTP/JSON μ€λ²ν€λ | JSON νμ±μΌλ‘ μΈν μ²λ¦¬λ μ ν (5K msg/s) | λ°°μΉμΌλ‘ μν, Phase 2μμ gRPC λ§μ΄κ·Έλ μ΄μ |
| μΈλ©λͺ¨λ¦¬ μ μ₯μ | νν°μ λΉ 1M λ©μμ§ μ ν | WAL κΈ°λ° μ¬μμ μ 볡ꡬ, ν₯ν μΈκ·Έλ¨ΌνΈ λΆν |
| μ ν νλͺ© | μ΅λκ° | μ΄μ |
|---|---|---|
| λ©μμ§ ν¬κΈ° | 1MB | HTTP μμ² ν¬κΈ° μ ν, λ©λͺ¨λ¦¬ μ¬μ©λ κ΄λ¦¬ |
| ν ν½λΉ νν°μ μ | 100κ° | Consumer Group κ΄λ¦¬ 볡μ‘λ μ ν |
| νν°μ λΉ λ©μμ§ μ | 1Mκ° | μΈλ©λͺ¨λ¦¬ μ μ₯ νκ³ |
| Consumer Group μ | μ ν μμ | κ° κ·Έλ£Ήμ λ 립μ μΌλ‘ κ΄λ¦¬ |
| Topicλͺ κΈΈμ΄ | 255μ | νμΌμμ€ν νΈνμ± |
| Consumer ID κΈΈμ΄ | 128μ | HTTP URL κΈΈμ΄ μ ν |
# 1. νλ‘μ νΈ ν΄λ‘ λ° λΉλ
git clone <repo> && cd gafka
make build
# 2. λΈλ‘컀 μμ (리λ)
./bin/broker --id=1 --port=9001 --data-dir=/tmp/gafka-1 --role=leader
# 3. λΈλ‘컀 μμ (νλ‘μ)
./bin/broker --id=2 --port=9002 --data-dir=/tmp/gafka-2 --role=follower --leader=localhost:9001
# 4. ν ν½ μμ±
./bin/admin create-topic --name=test-topic --partitions=2 --broker=localhost:9001
# 5. λ©μμ§ μ μ‘
./bin/producer --topic=test-topic --broker=localhost:9001 --message="Hello World" --key="user123"
# 6. λ©μμ§ μλΉ (Long Polling)
./bin/consumer --topic=test-topic --group=test-group --broker=localhost:9001 --timeout=30s# λ©μμ§ μ μ‘
curl -X POST http://localhost:9001/api/v1/produce \
-H "Content-Type: application/json" \
-d '{"topic":"test-topic","key":"user123","value":"Hello World"}'
# λ©μμ§ μλΉ (Consumer Group κΈ°λ° - λΈλ‘μ»€κ° offset κ΄λ¦¬)
curl "http://localhost:9001/api/v1/consume?topic=test-topic&count=10&consumer_id=consumer-1&group_id=test-group&timeout=30s"
# λ©μμ§ μλΉ (κ°λ³ Consumer - μ§μ offset μ§μ )
curl "http://localhost:9001/api/v1/consume?topic=test-topic&partition=0&offset=100&count=10&timeout=30s"
# Consumer Group μν νμΈ
curl "http://localhost:9001/api/v1/consumer-groups/test-group/status"
# Consumer Heartbeat
curl -X POST "http://localhost:9001/api/v1/consumer-groups/test-group/members/consumer-1/heartbeat"| ν μ€νΈ νλͺ© | λꡬ | λͺ©ν | κ²μ¦ λ°©λ² |
|---|---|---|---|
| μ²λ¦¬λ μΈ‘μ | wrk + Lua | β₯5K msg/s | 1KB λ©μμ§λ‘ 30μ΄ λΆν |
| μ§μ°μκ° μΈ‘μ | Go client | P95 β€ 200ms | produce β consume μΈ‘μ |
| μ₯μ 볡ꡬ | μλ | β€30μ΄ | λΈλ‘컀 kill ν 볡μ |
| λ°°μΉ ν¨κ³Ό | wrk | TPS λΉκ΅ | λ°°μΉ vs λ¨κ±΄ μ μ‘ λΉκ΅ |
-- scripts/produce.lua (wrkμ©)
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"
-- 1KB λ©μμ§λ‘ ν
μ€νΈ
local message_1kb = string.rep("a", 1024)
function request()
local body = string.format('{"topic":"test-topic","key":"test-%d","value":"%s"}',
math.random(1000), message_1kb)
return wrk.format(wrk.method, wrk.path, wrk.headers, body)
end
function response(status, headers, body)
if status ~= 200 and status ~= 201 then
print("Error: " .. status .. " " .. body)
end
end
function done(summary, latency, requests)
print("Throughput: " .. string.format("%.2f", summary.requests / (summary.duration / 1000000)) .. " requests/sec")
print("Average latency: " .. latency.mean / 1000 .. "ms")
endRed β Green β Refactor μ¬μ΄ν΄ λ°λ³΅
1. μ€ν¨νλ ν
μ€νΈ μμ±
2. ν
μ€νΈλ₯Ό ν΅κ³Όνλ μ΅μ μ½λ ꡬν
3. μ½λ κ°μ (리ν©ν λ§)
| μ£Όμ°¨ | TDD ν μ€νΈ λμ | μμ ν μ€νΈ μΌμ΄μ€ |
|---|---|---|
| 1-2μ£Όμ°¨ | λ©μμ§ κ΅¬μ‘°μ²΄, νν°μ λ‘μ§ | TestMessage_Serialize(), TestPartition_AddMessage() |
| 3-4μ£Όμ°¨ | νλ‘λμ/컨μλ¨Έ API | TestProducer_SendMessage(), TestConsumer_PullMessages() |
| 5-6μ£Όμ°¨ | WAL μμν, Consumer Group | TestWAL_WriteAndRecover(), TestConsumerGroup_Rebalancing() |
| 7-8μ£Όμ°¨ | ν΅ν© ν μ€νΈ, μ±λ₯ ν μ€νΈ | TestBroker_HandleHighLoad(), TestFailover_Recovery() |
| 9μ£Όμ°¨ | E2E ν μ€νΈ, λ¬Έμν | TestFullWorkflow_ProducerToBrokerToConsumer() |
| μ§λ¬Έ | λμ |
|---|---|
| μ Kafka ν΄λ‘ μ Goλ‘ λ§λλμ? | λμμ±, νμ΅ ν¨μ¨, κ°λ μ±μμ Goκ° μ ν© |
| μΈλΆ Zookeeper/etcd μ μ μΌλμ? | MVPμμ μ€νλ € 볡μ‘λ μ¦κ°. ν₯ν νμ₯ κ³ν μμ |
| λ©μμ§ μμλ μ΄λ»κ² 보μ₯λλμ? | νν°μ λ΄ offset λ¨μ μμ°¨ μ²λ¦¬, key κΈ°λ° νν°μ λ |
| λΈλ‘컀 μ₯μ μ 볡ꡬλ μ΄λ»κ² λλμ? | WAL νμΌ κΈ°λ° μλ 볡ꡬ + νλ‘μβ리λ μλ μΉκ²©. 리λ μ μΆ μλνλ Phase 2 |
| Pull λ°©μμ μ€μκ°μ±μ μ΄λ»κ² 보μ₯λλμ? | Long Polling μ¬μ©, μ΅λ 30μ΄ μ΄λ΄ μλ΅ λ³΄μ₯ |
| WAL μμ μ 볡ꡬλ μ΄λ»κ² λλμ? | CRC32 κΈ°λ° μμ κ²μ¦, 볡ꡬ μ€ν¨ μ fail-safe μ²λ¦¬ νμ |
| λ©μμ§ μ€λ³΅ λ°©μ§λ? | at-least-onceλ§ λ³΄μ₯. μ€λ³΅ λ°©μ§λ Consumerμμ μ²λ¦¬ νμ |
| Consumer Groupμμ λμμ± λ¬Έμ λ μ΄λ»κ² ν΄κ²°νλμ? | Heartbeat + νν°μ ν λΉμΌλ‘ ν νν°μ μ ν Consumerλ§ μλΉ. 409 Conflictλ‘ μ€λ³΅ λ°©μ§ |
| HTTP + JSON μ±λ₯ νκ³λ μ΄λ»κ² ν΄κ²°νλμ? | MVPμμλ κ°λ° νΈμμ± μ°μ . 5K msg/s λͺ©νλ‘ νμ€μ μ€μ . Phase 2μμ gRPCλ‘ λ§μ΄κ·Έλ μ΄μ |
| Zero-copy μ΅μ νλ HTTPμμ κ°λ₯νκ°μ? | HTTP μ€νμμλ λΆκ°λ₯. Phase 2μμ TCP κΈ°λ° μ»€μ€ν νλ‘ν μ½λ‘ μ νν΄μΌ ꡬν κ°λ₯ |
β μΆ©λΆν λ°μ κ°λ₯ν μ€κ³
- λͺ¨λ ν΅μ¬ μ»΄ν¬λνΈκ° λͺ¨λνλμ΄ μμ (
internal/broker,internal/consumerλ±) - ν μ€νΈ κΈ°λ° κ°λ° νλ‘μΈμ€ νμ¬ (TDD + wrk)
- λλ²κΉ κ³Ό νμ₯ λͺ¨λ κ³ λ €ν λλ ν 리 ꡬ쑰
νμ§λ§ μλμ κ°μ μμλ μμ€ν νμ₯μ μ€μ§μ μ₯μ λ¬Όλ‘ μμ© κ°λ₯
- ν΅μ κ³μΈ΅ νκ³
- HTTP + JSON β 5K msg/s μ ν
- TCP κΈ°λ° μ»€μ€ν νλ‘ν μ½ νμ (Zero-copy λ±)
- Coordinator μ§μμ± μμ
- νμ¬λ μΈλ©λͺ¨λ¦¬ κΈ°λ° (Consumer Group, Offset λ± λͺ¨λ νλ°μ±)
- 볡μ /μ₯μ 볡ꡬ μλν λΆμ‘±
- νλ‘μμ 리λ μ ν μλ
- ISR, 리λ μ μΆ μκ³ λ¦¬μ¦ λΆμ¬
- μΈκ·Έλ¨ΌνΈ λ° μΈλ±μ± κΈ°λ₯ λΆμ¬
- WALμ νλμ κΈ΄ λ‘κ·Έλ‘λ§ μ‘΄μ¬ β 볡ꡬ/μμΆ/GC μ΄λ ΅λ€
| μ£Όμ°¨ | ν΅μ¬ ꡬν μ¬ν | TDD λͺ©ν | κ²μ¦ κΈ°μ€ |
|---|---|---|---|
| 1μ£Όμ°¨ (7/28-8/3) |
νλ‘μ νΈ μ μ , λ©μμ§ κ΅¬μ‘°μ²΄ | Message, Partition λ¨μ ν μ€νΈ | ν μ€νΈ 컀λ²λ¦¬μ§ > 80% |
| 2μ£Όμ°¨ (8/4-8/10) |
νν°μ λ‘μ§, WAL κΈ°λ³Έ ꡬν | WAL μ½κΈ°/μ°κΈ° ν μ€νΈ | νμΌ μμν λμ νμΈ |
| 3μ£Όμ°¨ (8/11-8/17) |
HTTP API, νλ‘λμ ꡬν | HTTP νΈλ€λ¬ ν μ€νΈ | 1K msg/s μ²λ¦¬ νμΈ |
| 4μ£Όμ°¨ (8/18-8/24) |
컨μλ¨Έ, μ€νμ κ΄λ¦¬ | 컨μλ¨Έ κ·Έλ£Ή ν μ€νΈ | E2E λ©μμ§ νλ‘μ° λμ |
| 5μ£Όμ°¨ (8/25-8/31) |
λ°°μΉ, μ±λ₯ μ΅μ ν | λ°°μΉ λ‘μ§ ν μ€νΈ | 5K msg/s λͺ©ν λ¬μ± |
| 6μ£Όμ°¨ (9/1-9/7) |
Consumer Group, νν°μ ν λΉ | 리밸λ°μ± ν μ€νΈ | Consumer μΆκ°/μμ μ μλ μ¬ν λΉ |
| 7μ£Όμ°¨ (9/8-9/14) |
볡μ κΈ°λ₯, μ₯μ 볡ꡬ | 볡μ λκΈ°ν ν μ€νΈ | λ°μ΄ν° μΌκ΄μ± νμΈ, 30μ΄ λ΄ λ³΅κ΅¬ |
| 8μ£Όμ°¨ (9/15-9/21) |
μ±λ₯ ν μ€νΈ, λ²κ·Έ μμ | λΆν ν μ€νΈ μλν | λͺ¨λ μ±λ₯ λͺ©ν λ¬μ± |
| 9μ£Όμ°¨ (9/22-9/26) |
λ¬Έμν, λ°λͺ¨ μ€λΉ | ν΅ν© ν μ€νΈ μλ£ | README, API λ¬Έμ μμ± |
gafka/
βββ cmd/ # μ ν리μΌμ΄μ
μ§μ
μ
β βββ broker/
β β βββ main.go # λΈλ‘컀 μλ² μ€ν
β βββ producer/
β β βββ main.go # νλ‘λμ CLI
β βββ consumer/
β β βββ main.go # 컨μλ¨Έ CLI
β βββ admin/
β βββ main.go # κ΄λ¦¬ λꡬ CLI
βββ internal/ # λ΄λΆ ν¨ν€μ§ (μΈλΆ λ
ΈμΆ λΆκ°)
β βββ broker/ # λΈλ‘컀 μ½μ΄ λ‘μ§
β β βββ broker.go
β β βββ broker_test.go
β β βββ partition.go
β β βββ partition_test.go
β β βββ wal.go
β β βββ wal_test.go
β β βββ replication.go
β β βββ replication_test.go
β βββ producer/ # νλ‘λμ λ‘μ§
β β βββ producer.go
β β βββ producer_test.go
β β βββ batcher.go
β β βββ batcher_test.go
β β βββ partitioner.go
β βββ consumer/ # 컨μλ¨Έ λ‘μ§
β β βββ consumer.go
β β βββ consumer_test.go
β β βββ group.go
β β βββ group_test.go
β β βββ offset.go
β βββ api/ # HTTP API νΈλ€λ¬
β βββ handlers.go
β βββ handlers_test.go
β βββ middleware.go
β βββ routes.go
βββ pkg/ # μΈλΆ ν¨ν€μ§ (μ¬μ¬μ© κ°λ₯)
β βββ protocol/ # λ©μμ§ νλ‘ν μ½
β β βββ message.go
β β βββ message_test.go
β βββ client/ # Go ν΄λΌμ΄μΈνΈ SDK
β βββ client.go
β βββ client_test.go
βββ configs/ # μ€μ νμΌ
β βββ broker.yaml
β βββ examples/
βββ scripts/ # μ€ν¬λ¦½νΈ λ° λꡬ
β βββ produce.lua # wrk ν
μ€νΈ μ€ν¬λ¦½νΈ
β βββ setup.sh # νκ²½ μ€μ
β βββ benchmark.sh # μ±λ₯ ν
μ€νΈ
βββ docs/ # λ¬Έμ
β βββ api.md # API λ¬Έμ
β βββ architecture.md # μν€ν
μ² κ°μ΄λ
β βββ operations.md # μ΄μ κ°μ΄λ
βββ examples/ # μ¬μ© μμ
β βββ simple_producer/
β βββ simple_consumer/
βββ Makefile # λΉλ μ€ν¬λ¦½νΈ
βββ go.mod # Go λͺ¨λ μ μ
βββ go.sum # μμ‘΄μ± μ²΄ν¬μ¬
βββ README.md # νλ‘μ νΈ κ°μ
βββ .gitignore # Git 무μ νμΌ
- κΈ°λ³Έ νλ‘λμ/컨μλ¨Έ ꡬν
- λ¨μΌ λΈλ‘컀 WAL μ μ₯μ
- HTTP API κΈ°λ° ν΅μ
- HTTP β gRPC or TCP 컀μ€ν νλ‘ν μ½
- WAL μΈκ·Έλ¨ΌνΈ ꡬ쑰 λ° μΈλ±μ± μΆκ°
- λ©μμ§ μμΆ (gzip/snappy)
- Raft κΈ°λ° λ¦¬λ μ μΆ
- Offset λ° Metadata μμν (BoltDB/Badger λ± μ¬μ© κ°λ₯)
- λΈλ‘컀 ν΄λ¬μ€ν°λ§ + ZooKeeper or etcd μ°λ
- λ©μμ§ μ²λ¦¬λ: λ¨μΌ λΈλ‘컀 5K msg/s μ΄μ (1KB λ©μμ§, HTTP/JSON κΈ°μ€)
- λ©μμ§ μμ 보μ₯: νν°μ λ΄ 100% μμ μ μ§
- λ°μ΄ν° μμμ±: μΉμΈλ λ©μμ§ WAL κΈ°λ° 100% 볡ꡬ 보μ₯
- κΈ°λ³Έ 볡μ : 리λ-νλ‘μ κ° λΉλκΈ° 볡μ μ μ λμ
- Consumer Group: νν°μ λ³ λ¨μΌ Consumer 보μ₯
- ν μ€νΈ 컀λ²λ¦¬μ§: 80% μ΄μ μ μ§
- TDD μ€μ: λͺ¨λ κΈ°λ₯μ ν μ€νΈ λ¨Όμ μμ±
- μ½λ νμ§: Go lint κ·μΉ μ€μ
- API λ¬Έμ: OpenAPI μ€ν μμ±
- λ©μμ§ ν ν΅μ¬ κ°λ : ν ν½, νν°μ , μ€νμ μ΄ν΄
- λΆμ° μμ€ν κΈ°μ΄: 볡μ , μΌκ΄μ±, μ₯μ 볡ꡬ κ²½ν
- κ³ μ±λ₯ I/O: WAL, λ°°μΉ κΈ°λ² κ΅¬ν
- TDD μλ: ν μ€νΈ μ£Όλ κ°λ° μμ±