Concert Reservation Service
2024-10-05 — 2024-11-30
Concert seat reservation service resolving concurrency across seat locking, payments, and point charging under 10K concurrent requests — hybrid locking strategy (optimistic + Redisson distributed lock), 15x TPS improvement via Redis caching, Kafka event-driven architecture, K6 load test-driven optimization
System Architecture
Problem Solving
Risk of double-booking under 10K concurrent seat reservation requests
Compared pessimistic, optimistic, and distributed locks via K6; selected @Version optimistic lock optimal for single-row contention
50% reservation latency improvement (1,678ms → 835ms), zero double-bookings
Balance integrity corruption under concurrent point charging and payments
Analyzed infinite retry risk of optimistic lock; applied Redisson distributed lock (userWalletLock:{userId}) for per-user serialization
100% balance consistency under concurrent charge/payment scenarios
Concert/seat query TPS only 100, causing DB bottleneck at reservation open
Implemented layered caching strategy combining Redis cache with DB index optimization
TPS 100 → 1,500 (15x improvement), 94% DB query reduction
Payment/notification tightly coupled via synchronous calls after reservation
Kafka Transactional Outbox: outbox_event inserted within TX, scheduler publishes asynchronously
Eliminated coupling, prevented message loss, enabled independent scaling
Project Description
A project that resolved concurrency issues in high-traffic environments using multiple locking strategies (pessimistic, optimistic, and Redis distributed locks), selecting the optimal approach per scenario. Designed a hybrid strategy applying optimistic locks for seat reservation and Redisson-based distributed locks for point charging and payments. Optimized read performance through Redis caching and DB indexing, and reduced system coupling with Kafka-based event-driven architecture. Experienced the full cycle of identifying and resolving performance bottlenecks through K6 load testing.
Highlights
- 50% seat reservation response time improvement with optimistic locking (10K concurrent)
- Hybrid locking strategy: optimistic lock for seats, Redisson for payments
- 15x TPS improvement (100 → 1,500), 94% DB query reduction via Redis caching
- Kafka event-driven architecture eliminating inter-domain coupling
- Performance bottleneck identification and resolution via K6 load testing
Performance Metrics
| Performance Metrics | Before | After |
|---|---|---|
| Reservation latency | 1,678ms | 835ms (-50%) |
| Seat query TPS | 100 | 1,500 (15x) |
| DB query ratio | 100% | 6% (-94%) |
Tech Decisions
- ▶ @Version optimistic lock for seat reservation: higher throughput than pessimistic lock on single-row contention, validated with K6 10K VU
- ▶ Redisson distributed lock (userWalletLock:{userId}) for payments: avoids infinite retry loops of optimistic lock in balance-critical transactions
- ▶ Redis Sorted Set queue: score=Unix timestamp serves dual purpose (entry order + expiry), O(log N) vs DB-based queue
- ▶ Transactional Outbox pattern: outbox_event row inserted within payment TX → scheduler publishes to Kafka, preventing message loss
Lessons Learned
- • Understood fundamental differences in concurrency control by comparing pessimistic, optimistic, and distributed lock tradeoffs
- • Learned context-driven selection over single solutions through hybrid locking strategy design per scenario
- • Experienced layered caching strategy maximizing read performance by combining Redis caching with DB index optimization
- • Learned async communication design eliminating inter-domain coupling through Kafka-based event-driven architecture