แฅแแฐ Twitter แฅแ Instagram แซแ แตแแแ แ แแแฌแฝแแฝ Architecture (แ แแแแญ) แแ แญแแตแแ? แจแฐแ แแแ แแฅแญ 1 แแแฎแ แฒแฐแญแต แแ แแแแฅ แ แแฃแฝแ? Trade-offs (แ แแฑแ แแ แแฑ แแฐแ) โ แแ แฒแแ แจแตแแแ แแแจแฅ แ แแฅแ?
แตแแ แตแ แฐแต: "Microservices แแแแ แแญแฅ แแ!" แฅแ แแฐแฅแข Amazonแฃ Netflixแฃ แฅแ Uber โ แแแ แ Monolith แแ แจแแแฉแต! แ แแตแแแ แแตแฅแตแฅแแตแ (Complexity) แ แณแตแแกแข แแแแชแซ แฝแแฉแ แแจแฑแฃ แแแตแแ แแฅแ แญแแฃแแข
| APPROACH | โ PROS (แฅแ แแฝ) | โ CONS (แแณแถแฝ) | USE WHEN (แแผ แฅแแ แแ?) |
|---|---|---|---|
| Monolith | แแแ แแแข แแดแจแแแแแต แแฃแ แแแข Debug แแแตแจแ แญแแปแแข | แฒแซแตแ (Scale แฒแซแฐแญแ) แญแจแฅแณแแข แ แแฑ แจแฐแ แแธ แแแ แญแแแแข | แแแแช แตแญแ แถแฝ (Startup)แข แจ 50 แดแจแแแฎแฝ แ แณแฝแข |
| Microservices | แฅแซแแณแแฑแ แแฅแป แแณแฐแ (Scale แแตแจแ) แญแปแแแข แจแฐแแซแจ แดแญแแแ แแ แแ แญแปแแแข | Network แแแแจแต (latency) แซแแฃแแข Debug แแแตแจแ แจแฃแต แแแข | แตแแแ แกแตแแฝ แฒแแฉแข แ แฃแ แฅแ แฐแ แแ แฒแแญแข |
| Modular Monolith | แจแแแฑแ แแญแฅ แแ แ แแแข แแฐแแต แแแจแแแ (แแแแ แ) แแแ แแแข | แ แแแ แ แแต แแญ แแ Deploy แจแแฐแจแแแข แซแแฐแ แแแ แ แแแจแจแจแญ แญแฝแแแข | แฅแซแฐแ แแ แตแญแ แถแฝแข แจ 10โ50 แดแจแแแฎแฝแข โ แแแแแญ แแญแก แแ! |
# Nginx Load Balancer โ Round Robin แ แฐแซแญ upstream backend { server app1.internal:3000; server app2.internal:3000; server app3.internal:3000; # แแแ แฅแซแแแฝ (Requests) แ แจแฐแซ 1โ2โ3โ1โ2โ3 แฅแซแ แญแจแแแแ! } server { listen 80; location / { proxy_pass http://backend; proxy_set_header X-Real-IP $remote_addr; # Health check โ แจแแฐ (แจแฐแ แแธ) แฐแญแจแญแ แจแตแซ แแญ แซแฐแญแแ proxy_connect_timeout 5s; proxy_read_timeout 30s; } } # Sticky Sessions โ แ แแต แฐแ แแ แแแแ แฐแแณแณแญ แฐแญแจแญ แแญ แฅแแฒแแญ: upstream backend_sticky { ip_hash; โ แจแฐแ แแแแ IP แแแป แซแฐแญแแ server app1.internal:3000; server app2.internal:3000; }
Caching แแแตแจแ แแแ แขแแตแแ แตแแ แแฐแ Cache invalidation แแแข แณแณ แฒแแจแญ แจแตแฎแแ Cache แฅแแดแต แฅแ แแผ แฅแแแแแ (update แฅแแตแญแแ)? "แ แฎแแแแฐแญ แณแญแแต แแแต แจแฃแต แแแฎแฝ แฅแป แ แแก Cache invalidation แฅแ แแแแฎแฝ แตแ แแแฃแตแข"
// โโ 1. Cache-Aside (Lazy Loading) โโ โ แ แฃแ แจแฐแแแฐแ async function getUser(id) { const cached = await redis.get(`user:${id}`); if (cached) return JSON.parse(cached); // Cache Hit! (แซแแแ แญแแแณแ) const user = await db.findUser(id); // Cache Miss (แซแแแแ แแฐ DB แญแแณแ) await redis.setEx(`user:${id}`, 3600, JSON.stringify(user)); return user; } // โโ 2. Write-Through โโ แแฐ DB แฅแ Cache แ แฐแแณแณแญ แแ แแแ async function updateUser(id, data) { await db.updateUser(id, data); await redis.setEx(`user:${id}`, 3600, JSON.stringify(data)); // DB แฅแ Cache แแแแ แฐแแณแณแญ แณแณ แญแแซแธแแ! } // โโ 3. Cache Invalidation โ แณแณ แฒแแจแญ แจแตแฎแแ Cache แแฅแแต async function deleteUser(id) { await db.deleteUser(id); await redis.del(`user:${id}`); // Invalidate (แ แฅแแ)! await redis.del(`users:list`); // แฐแซแซแฅแแต แซแแธแแแ Cache แซแ แแ! } // โโ 4. Cache Stampede Prevention โ แฅแ แฅแซแแแฝ แ แ แแต แแ Cache Miss แฒแซแฐแญแ async function getUserSafe(id) { const lockKey = `lock:user:${id}`; const lock = await redis.set(lockKey, 1, 'NX', 'EX', 10); if (!lock) { // แแ แฅแซแ (request) แณแณแแ แฅแซแแฃ แแ โ แตแแแ แตแแฝ แ แฅแ แฅแแฐแแ แญแแญแซแ await sleep(100); return getUser(id); } // แแแ แ แแซแแแ โ แตแแแ แจ DB แ แแฅแถ Cache แซแฐแญแแแ }
แแแแ แแแแ แจแแฅแแต แฅแแ แแต (Bottleneck) แจแแแแ: Database แแแข 100 แฐแญแจแญ แขแแซแฝแแ Database 1 แจแแ แแจแแแ แ แญแแญแ โ แตแแแ Indexingแฃ Query optimizationแฃ แฅแ Read replicas แแแญ แ แแฃแธแแข
-- โ Slow: Full table scan โ 1 แแแฎแแ แฎแ (rows) แซแ แแแแ แซแแฃแ SELECT * FROM posts WHERE user_id = 42; -- Execution: 850ms (แซแ index) -- โ แแแแชแซ Index แแ แฉ! CREATE INDEX idx_posts_user_id ON posts(user_id); -- แ แแ แซแ แฅแซแ: 2ms แฅแป! 425 แฅแฅแ แแฃแ แแ! -- Compound Index โ แแฅแ columns แ แ แแต แแ CREATE INDEX idx_posts_user_created ON posts(user_id, created_at DESC); -- "แจแ แคแแ posts โ แ แฒแถแนแ แแแแชแซ" โ แ แ แ แ แต แญแแแณแ! -- โ N+1 Query Problem โ แ แแแแ แญแ แแ แแ แจแแแณ! const users = await prisma.user.findMany(); for (const user of users) { const posts = await prisma.post.findMany({where:{authorId:user.id}}); // 100 users แขแแฉ = 101 queries แแฐ DB แญแแซแ! (N+1 แฝแแญ) } -- โ Fix: include แแ แแ (แ 1 query แฅแป แซแแแ!) const users = await prisma.user.findMany({ include: { posts: true } // JOIN แ แแตแจแ แ 1 query แญแแแฐแแ! }); -- Read Replica โ แ แฒแต แแจแ แแแแ แแฐ Primaryแฃ แแแแ แฅ แแฐ Replica const writePrisma = new PrismaClient({ datasourceUrl: PRIMARY_URL }); const readPrisma = new PrismaClient({ datasourceUrl: REPLICA_URL }); -- แแแแ แฅ โ replica (แจแแแ แฅ แ แ แแ 10x แซแณแตแแ!) -- แแแแ โ primary (Consistencyแ แแแ แ แ !)
แจแฐแ แแแแฝแ แแฅแญ แจแแฉ โ แแ แแญแแต Scale strategy แฅแแฐแแซแตแแแแฝแ แฐแแแจแฑ!
แจ Cache hit rate แจ DB แญแแต (load) แแญ แซแแแ แแแแแต แญแแแจแฑแข
แแ แแญแแต แ แแแฌแฝแ แแ? โ แแฅแฑ แจแแแฅแแแ Architecture แฅแแณแซแแแข