🏢 Uber 기술 스택 분석

15 min read
ubermicroservicesgojavanodejsreactkafkamysqlcassandrah3real-timemarketplacegrpcmobile

우버가 매일 2,500만 건의 라이드를 실시간으로 매칭하는 기술 스택 심층 분석 - Go, Java, Node.js로 구축한 글로벌 실시간 마켓플레이스

🏢 Uber 기술 스택 분석

전 세계 10,000개 도시에서 매초 수천 건의 실시간 매칭을 처리하는 Uber의 기술 스택을 심층 분석합니다.
"Move the world, build the future" - 실시간 마켓플레이스의 기술적 도전


📊 회사 개요

서비스 규모

  • 월간 활성 사용자: 1.3억 명
  • 드라이버 & 배달원: 500만 명+
  • 일일 트립: 2,500만 건
  • 도시: 전 세계 10,000개+
  • 서비스: Rides, Eats, Freight, Health

엔지니어링 조직

  • 엔지니어: 3,000명+
  • 기술 스택: 4,000+ 마이크로서비스
  • 코드베이스: 수천만 줄
  • 배포: 주당 4,000+ 배포

기술적 도전과제

  1. 실시간 매칭: 수요-공급 최적화
  2. 동적 가격: 서지 프라이싱 알고리즘
  3. 글로벌 확장: 다양한 규제와 시장
  4. 신뢰성: 24/7 가용성 필수

🏗️ 아키텍처 Overview

시스템 다이어그램

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Riders    │────►│   Gateway   │────►│  Dispatch   │
│    App      │     │   (Edge)    │     │   System    │
└─────────────┘     └─────────────┘     └─────────────┘
       │                    │                    │
       │              ┌─────▼─────┐       ┌─────▼─────┐
       │              │   DISCO   │       │   Supply   │
       │              │  Matching │       │  Service   │
       │              └───────────┘       └───────────┘
       │                    │                    │
┌─────────────┐       ┌─────▼─────┐       ┌─────▼─────┐
│   Drivers   │◄──────│   Kafka   │◄──────│  Pricing  │
│     App     │       │  Streams  │       │  Service  │
└─────────────┘       └───────────┘       └───────────┘

핵심 설계 원칙

  1. Domain-Oriented Architecture: 비즈니스 도메인별 분리
  2. Layered Architecture: 플랫폼, 제품, 프레젠테이션 레이어
  3. Event-Driven: 이벤트 기반 통신
  4. Location-First: H3 기반 지리공간 인덱싱
  5. Real-Time Priority: 저지연 최적화

기술 진화

  • 2009-2012: PHP 모놀리스
  • 2013-2015: Python/Node.js 마이크로서비스 전환
  • 2016-2018: Go 도입, Schemaless 개발
  • 2019-2021: gRPC 마이그레이션
  • 2022-현재: 플랫폼 통합 (Rides + Eats)

🧩 기술 스택 상세

Backend 기술

Go 서비스 예시

// 지리공간 매칭 서비스
package dispatch

import (
    "context"
    "github.com/uber/h3-go"
    "github.com/uber/ringpop-go"
)

type DispatchService struct {
    supplyIndex  *H3Index
    demandQueue  *PriorityQueue
    ringpop      *ringpop.Ringpop
    priceEngine  PricingClient
}

func (s *DispatchService) FindOptimalMatch(ctx context.Context, req *RideRequest) (*Match, error) {
    // H3 셀 기반 근처 드라이버 검색
    h3Cell := h3.GeoToH3(req.Pickup.Lat, req.Pickup.Lng, 9)
    nearbyDrivers := s.supplyIndex.GetDriversInRadius(h3Cell, 2000) // 2km

    // 동적 가격 계산
    surge, err := s.priceEngine.CalculateSurge(ctx, &SurgeRequest{
        H3Cell:       h3Cell,
        Timestamp:    time.Now(),
        SupplyCount:  len(nearbyDrivers),
        DemandCount:  s.demandQueue.GetDemandCount(h3Cell),
    })

    // 최적 매칭 알고리즘
    matches := []Match{}
    for _, driver := range nearbyDrivers {
        score := s.calculateMatchScore(req, driver, surge)
        if score > MinMatchThreshold {
            matches = append(matches, Match{
                Driver: driver,
                Rider:  req.RiderID,
                Score:  score,
                ETA:    driver.ETA,
                Fare:   s.calculateFare(req, surge),
            })
        }
    }

    // 최고 점수 매치 반환
    sort.Slice(matches, func(i, j int) bool {
        return matches[i].Score > matches[j].Score
    })

    if len(matches) > 0 {
        return &matches[0], nil
    }

    return nil, ErrNoMatchFound
}

주요 백엔드 기술:

  • 언어: Go (60%), Java (25%), Python (10%), Node.js (5%)
  • RPC: gRPC, TChannel (레거시)
  • API Gateway: Edge Gateway (자체 개발)
  • 서비스 메시: Envoy Proxy
  • 메시징: Apache Kafka, Celery

마이크로서비스 아키텍처

# 주요 도메인 서비스
services:
  # 핵심 비즈니스
  - name: dispatch-service
    language: go
    dependencies: [supply, demand, pricing]

  - name: pricing-service
    language: java
    dependencies: [ml-platform, surge-engine]

  - name: payment-service
    language: java
    dependencies: [risk, fraud-detection]

  # 플랫폼 서비스
  - name: user-platform
    language: java
    dependencies: [auth, profile, preferences]

  - name: geospatial-platform
    language: go
    dependencies: [h3-index, routing, maps]

  - name: ml-platform
    language: python
    dependencies: [feature-store, model-serving]

Frontend 기술

모바일 앱 아키텍처

// iOS 라이더 앱 아키텍처
class RideRequestViewController: UIViewController {
    private let locationManager = LocationManager()
    private let networkClient = UberAPIClient()
    private let mapView = MapboxMapView()

    func requestRide() {
        // 실시간 위치 추적
        locationManager.startUpdatingLocation { location in
            self.updatePickupLocation(location)
        }

        // 실시간 공급 상황 표시
        networkClient.streamNearbyDrivers { drivers in
            self.mapView.updateDriverPositions(drivers)
        }

        // 요금 추정
        networkClient.estimateFare(
            from: pickupLocation,
            to: destinationLocation
        ) { fare in
            self.showFareEstimate(fare)
        }
    }
}

플랫폼별 기술:

  • iOS: Swift, RIBs 아키텍처
  • Android: Kotlin, MVP/MVVM
  • Web: React, TypeScript, GraphQL
  • Driver App: React Native (일부), Native

RIBs 아키텍처

// Router-Interactor-Builder 패턴
protocol RideRequestRouting: ViewableRouting {
    func routeToLocationPicker()
    func routeToPaymentSelection()
    func routeToRideStatus()
}

class RideRequestInteractor: PresentableInteractor<RideRequestPresentable> {
    weak var router: RideRequestRouting?
    private let rideService: RideService

    func requestRide(pickup: Location, destination: Location) {
        rideService.createRideRequest(pickup: pickup, destination: destination)
            .subscribe(onNext: { [weak self] rideStatus in
                self?.router?.routeToRideStatus()
            })
            .disposed(by: disposeBag)
    }
}

Data & Infrastructure

데이터 아키텍처

-- Schemaless 데이터 모델 (MySQL 기반)
CREATE TABLE entities (
    entity_type VARCHAR(50),
    entity_id BINARY(16),
    attribute_name VARCHAR(100),
    attribute_value JSON,
    version BIGINT,
    updated_at TIMESTAMP,
    PRIMARY KEY (entity_type, entity_id, attribute_name, version)
);

-- 예시: 라이드 데이터
INSERT INTO entities VALUES
('ride', UUID_TO_BIN('...'), 'status', '{"value": "completed"}', 1, NOW()),
('ride', UUID_TO_BIN('...'), 'fare', '{"amount": 25.50, "currency": "USD"}', 1, NOW()),
('ride', UUID_TO_BIN('...'), 'route', '{"distance": 10.5, "duration": 900}', 1, NOW());

데이터 저장소:

  • Schemaless: MySQL 기반 NoSQL (자체 개발)
  • Docstore: 문서 저장소
  • Apache Cassandra: 시계열 데이터
  • HDFS: 데이터 레이크
  • Redis: 캐싱, 세션

H3 지리공간 시스템

// Uber의 H3 육각형 그리드 시스템
type H3Index struct {
    resolution int
    index      map[h3.H3Index]*Cell
}

type Cell struct {
    drivers    []*Driver
    demand     float64
    surge      float64
    lastUpdate time.Time
}

func (idx *H3Index) UpdateSupply(lat, lng float64, driverID string) {
    cell := h3.GeoToH3(lat, lng, idx.resolution)
    idx.mu.Lock()
    defer idx.mu.Unlock()

    if idx.index[cell] == nil {
        idx.index[cell] = &Cell{}
    }

    idx.index[cell].drivers = append(idx.index[cell].drivers, &Driver{
        ID:       driverID,
        Location: geo.NewPoint(lat, lng),
        Status:   "available",
    })
}

ML & 데이터 사이언스

Michelangelo ML 플랫폼

# 수요 예측 모델
from michelangelo import Model, Feature, Pipeline

class DemandForecastModel(Model):
    def __init__(self):
        self.features = [
            Feature("h3_cell", type="categorical"),
            Feature("hour_of_day", type="numeric"),
            Feature("day_of_week", type="categorical"),
            Feature("weather", type="categorical"),
            Feature("events_nearby", type="numeric"),
            Feature("historical_demand", type="time_series"),
        ]

    def train(self, training_data):
        # XGBoost 모델 학습
        self.model = XGBRegressor(
            n_estimators=1000,
            max_depth=8,
            learning_rate=0.01
        )

        X = self.prepare_features(training_data)
        y = training_data["demand_count"]

        self.model.fit(X, y)

    def predict(self, h3_cell, timestamp):
        features = self.extract_features(h3_cell, timestamp)
        return self.model.predict(features)[0]

ML 사용 사례:

  • 수요 예측: 15분 단위 예측
  • 동적 가격: 실시간 서지 계산
  • ETA 예측: 도착 시간 추정
  • 사기 탐지: 실시간 위험 평가
  • 경로 최적화: 최단 경로 계산

DevOps & Infrastructure

배포 파이프라인

# uDeploy 배포 설정
deployment:
  service: dispatch-service

  stages:
    - name: development
      clusters: [dev-us-west-2]
      canary_percentage: 0

    - name: staging
      clusters: [staging-us-west-2]
      canary_percentage: 10
      duration: 30m

    - name: production
      clusters: [prod-us-west-2, prod-eu-west-1, prod-ap-south-1]
      canary_percentage: 1
      increment: 10
      duration: 2h

  health_checks:
    - endpoint: /health
      interval: 10s
      threshold: 3

  rollback:
    automatic: true
    error_rate_threshold: 0.1
    latency_threshold_p99: 500ms

DevOps 도구:

  • uDeploy: 자체 배포 시스템
  • Phabricator: 코드 리뷰 (현재 GitHub 이전 중)
  • M3: 메트릭 시스템 (Prometheus 기반)
  • Jaeger: 분산 트레이싱
  • PagerDuty: 인시던트 관리

💡 핵심 기술 인사이트

1. DISCO (Dispatch Optimization)

# 실시간 매칭 최적화
class DISCOOptimizer:
    def optimize_batch(self, riders, drivers):
        # 이분 그래프 매칭 문제
        graph = BipartiteGraph()

        for rider in riders:
            for driver in drivers:
                if self.is_matchable(rider, driver):
                    weight = self.calculate_match_value(rider, driver)
                    graph.add_edge(rider.id, driver.id, weight)

        # Hungarian 알고리즘으로 최적 매칭
        matches = graph.maximum_weight_matching()

        return matches

    def calculate_match_value(self, rider, driver):
        # 다중 목표 최적화
        pickup_time = self.estimate_pickup_time(rider, driver)
        driver_utilization = self.get_driver_utilization(driver)
        rider_wait_time = self.get_rider_wait_time(rider)

        # 가중치 조합
        value = (
            - 0.4 * pickup_time
            - 0.3 * rider_wait_time
            + 0.3 * driver_utilization
        )

        return value

2. 서지 프라이싱

// 동적 가격 책정 엔진
type SurgePricingEngine struct {
    mlModel     MLModel
    constraints PricingConstraints
}

func (e *SurgePricingEngine) CalculateSurge(ctx context.Context, cell h3.H3Index) float64 {
    // 실시간 수요-공급 비율
    supply := e.getSupplyCount(cell)
    demand := e.getDemandCount(cell)
    ratio := float64(demand) / float64(supply)

    // ML 모델 예측
    features := e.extractFeatures(cell)
    predictedDemand := e.mlModel.Predict(features)

    // 서지 계산
    var surge float64
    if ratio > 1.5 {
        surge = min(
            1.0 + (ratio-1.5)*0.5,
            e.constraints.MaxSurge,
        )
    }

    // 규제 준수
    surge = e.applyLocalRegulations(cell, surge)

    return surge
}

3. 글로벌 확장 플랫폼

// 다중 지역 구성 관리
@Component
public class RegionalConfigService {
    private final Map<String, RegionalConfig> configs;

    @PostConstruct
    public void loadConfigs() {
        // 지역별 규제 및 기능 로드
        configs = Map.of(
            "US", new RegionalConfig()
                .withTipping(true)
                .withUpfrontPricing(true)
                .withSurgeMultiplier(3.0),

            "EU", new RegionalConfig()
                .withGDPRCompliance(true)
                .withFixedPricing(true)
                .withSurgeMultiplier(2.0),

            "IN", new RegionalConfig()
                .withCashPayments(true)
                .withAutoRickshaw(true)
                .withSurgeMultiplier(2.5)
        );
    }
}

📈 성과 & 지표

기술적 성과

  • 매칭 시간: 평균 15초 이내
  • 시스템 가용성: 99.99%
  • API 응답시간: P50 < 100ms, P99 < 500ms
  • 배포 빈도: 일일 1,000+ 배포
  • 서비스 수: 4,000+ 마이크로서비스

규모 지표

  • 일일 트립: 2,500만 건
  • 피크 시간 RPS: 500,000+
  • 데이터 처리: 일일 수 PB
  • ML 예측: 초당 수백만 건

🎓 Uber에서 배울 점

✅ 적용 가능한 패턴

  1. H3 지리공간 인덱싱: 효율적인 위치 기반 검색
  2. Schemaless 설계: 유연한 데이터 모델
  3. RIBs 아키텍처: 모바일 앱 구조화
  4. 배치 매칭: 효율성 극대화
  5. Circuit Breaker: 장애 격리

❌ 주의사항

  1. 복잡성 관리: 4000+ 서비스는 관리 어려움
  2. 기술 부채: 레거시 시스템 마이그레이션
  3. 조직 사일로: 팀 간 협업 어려움
  4. 비용: 대규모 인프라 운영비

📚 추천 리소스


🔮 미래 전망

현재 집중 분야

  1. 자율주행: ATG 기술 통합
  2. 멀티모달: 다양한 이동 수단 통합
  3. Uber Freight: B2B 물류 혁신
  4. 금융 서비스: Uber Money
  5. 슈퍼앱: 통합 플랫폼화

기술 투자 영역

  • 실시간 ML: 더 정교한 예측
  • 엣지 컴퓨팅: 저지연 처리
  • 블록체인: 공급망 추적
  • AR/VR: 향상된 사용자 경험

"우리는 단순히 차량을 호출하는 앱이 아닙니다. 우리는 도시의 OS를 만들고 있습니다."

  • Uber Engineering

마지막 업데이트: 2025-01-28

Found this helpful? Share it with others!
Tweet

🔗 Related Content

You might also be interested in these articles

🏢 company

🏢 Netflix 기술 스택 분석

넷플릭스가 전 세계 2.4억 사용자에게 스트리밍 서비스를 제공하는 기술 스택 심층 분석 - 마이크로서비스, AWS, Chaos Engineering의 교과서

9 min read
netflix, microservices +11
Read more
🏢 company

🏢 Airbnb 기술 스택 분석

에어비앤비가 전 세계 400만 개의 숙소를 연결하는 글로벌 마켓플레이스 기술 스택 심층 분석 - Ruby on Rails에서 Service-Oriented Architecture로의 진화

24 min read
airbnb, ruby +12
Read more
🏢 company

🏢 Stripe 기술 스택 분석

스트라이프가 전 세계 수백만 비즈니스의 결제를 처리하는 기술 스택 심층 분석 - Ruby, Go, Java로 구축한 금융 인프라의 미래

33 min read
stripe, ruby +11
Read more
🏗️ stack

🏢 Enterprise Microservices Stack

대규모 트래픽과 복잡한 비즈니스 로직을 위한 마이크로서비스 아키텍처 - Go, gRPC, Kubernetes로 구축하는 확장 가능한 시스템

14 min read
go, grpc +13
Read more
🏢 company

🏢 배달의민족 기술 스택 분석

배달의민족이 한국 배달 문화를 혁신하며 동남아로 확장한 기술 스택 심층 분석 - Java, Spring, Kotlin으로 구축한 O2O 플랫폼

51 min read
baemin, woowa +10
Read more
🏢 company

🏢 Canva 기술 스택 분석

캔바가 1억 명 이상의 사용자에게 쉽고 강력한 디자인 도구를 제공하는 기술 스택 심층 분석 - Java, TypeScript, AWS로 구축한 대규모 디자인 플랫폼

32 min read
canva, java +10
Read more

Found this helpful?

Help us improve this content by contributing on GitHub or sharing your feedback with the community.