10억 명 이상의 ChatGPT 사용자를 위한 온라인 스토리지의 빠른 확장
전례 없는 성장을 감당하기 위해 애플리케이션 스토리지 플랫폼 Habitat을 Python으로 확장한 방법.
작성: 기술 스태프 Jon Lee, Chaomin Yu, Ben Ries
로그인하거나 Codex 설정을 확인하거나 ChatGPT에서 새 대화를 시작하는 등 모든 OpenAI 제품은 빠르고 안정적인 데이터 액세스에 의존합니다. 제품이 응답하기 전에 이러한 작업 하나마다 여러 차례 별도의 데이터 조회가 필요할 수 있습니다. 이러한 요청이 느리면 제품도 느리게 느껴집니다. 이러한 요청이 실패하면 제품이 완전히 작동을 멈춥니다.
Habitat은 OpenAI 제품이 필요한 정보에 빠르고 안정적으로 접근할 수 있도록 구축한 온라인 스토리지 플랫폼입니다. 현재 Habitat은 거의 40개 리전에서 매주 10억 명 이상이 사용하는 제품을 지원하며 초당 7천만 건 이상의 요청을 처리합니다. Habitat은 DevDay 2023에서 GPTs를 지원하기 위해 처음 출시되었으며, 단일 데이터베이스에 연결된 간단한 Python 클라이언트 측 라이브러리로 시작했습니다. 오늘날에는 500페타바이트 이상의 데이터를 제공하는 복잡한 분산 시스템으로 발전했습니다.
그림 01 · Habitat이란?
온라인 스토리지 플랫폼
Habitat은 OpenAI 제품이 필요한 정보에 빠르고 안정적으로 접근할 수 있도록 구축한 온라인 스토리지 플랫폼입니다.
- 요청
- 응답
- 변경 사항(CDC)
이 정도 규모의 인프라를 구축하고 운영하는 일은 결코 쉽지 않지만, 그 자체가 특별히 어려운 일도 아닙니다. 우리 상황이 특별했던 이유는 성숙한 플랫폼을 구축하는 동시에 엄청난 사용자 증가와 제품 수요를 뒷받침하기 위해 전례 없는 속도로 확장해야 했기 때문입니다. 시스템 엔지니어는 흔히 10배의 규모에 대비해 구축하고, 다음 10배 확장을 준비하는 동안 몇 년간 버티기를 기대합니다. 하지만 OpenAI는 지난 3년 동안 매년 10배 넘게 성장했습니다. 그 결과 Habitat 구축과 운영은 전술적 결정과 순서 조정의 연속이었습니다. 각 구성 요소를 가장 낮은 수준까지 이해해 기존 스택의 성능을 최대한 끌어내는 한편, 스토리지와 컴퓨팅 용량 부족을 막아내며 기반 투자에 필요한 시간을 확보했습니다.
- 70M+
초당 요청 수
- 1B+
주간 이용자 수
- 500 PB+
데이터
OpenAI가 성장함에 따라 Habitat도 함께 성장해야 했습니다. 먼저 미션 크리티컬 제품 트래픽을 감당할 만큼 안정성을 높이고, 이어 전 세계 사용자에게 충분히 빠르게 응답하도록 했으며, 마침내 초대형 규모에서도 능숙하게 운영할 수 있게 되었습니다. 이 글은 온라인 스토리지를 확장한 방법을 다루는 2부작 시리즈의 첫 번째 글입니다. 이 글에서는 Habitat이 어떻게 발전했는지, 라이브러리에서 서비스로 전환한 이유, 서비스 스택에서는 흔치 않은 언어인 Python으로 작성된 서비스를 안정적인 스토리지 플랫폼 계층으로 확장한 방법을 공유합니다.
다음 글에서는 대규모 멀티테넌시의 안정성을 확보한 방법, 읽기 성능을 최적화하기 위한 계층적 전략, 전례 없는 수요를 안정적으로 처리하도록 Azure Cosmos DB와의 협력을 확대한 방법을 자세히 살펴봅니다.
Habitat은 제품 엔지니어가 데이터베이스 관리를 신경 쓸 필요가 없어야 한다는 단순한 아이디어에서 출발했습니다. Habitat은 DevDay 2023에서 GPTs를 지원하기 위해 ChatGPT의 메인 서버와 상호작용하는 소규모 Python 라이브러리로 처음 출시되었습니다. 내부적으로 데이터베이스 애플리케이션인 Azure Cosmos DB에 매핑되는 소수의 작업을 지원했습니다.
이 라이브러리의 역할은 제품 팀이 기반 기술의 세부 사항을 완전히 익히지 않아도 데이터를 간단히 저장하고 가져올 수 있게 하는 것이었습니다. Habitat은 관련 데이터의 유형, 데이터를 가져오거나 보낼 위치, 요청의 허용 여부 등을 판단하는 데 필요한 작업을 처리했습니다.
제품 엔지니어는 스키마 조회, 라우팅, 권한 부여, 암호화, 직렬화, 요청 셰이핑, 연결 풀링을 신경 쓸 필요가 없습니다. 데이터가 Azure Cosmos DB, 캐시 또는 다른 유형의 스토리지 중 어디에서 오는지도 고려할 필요가 없었습니다.
그림 02 · Habitat 서비스
간소화된 Habitat 요청 흐름
스토리지 로직을 독립형 서비스로 분리함으로써 배포, 관측 가능성, 플랫폼 개선을 위한 단일 제어 지점을 마련했습니다.
- 요청
- 응답
이 Python 라이브러리는 효과적으로 작동했습니다. 셀프서비스 Postgres와 Azure Cosmos DB 사용을 중앙에서 의도적으로 축소하지 않았는데도 Habitat은 OpenAI 제품 엔지니어 사이에서 빠르게 도입되었습니다.
제품 요구 사항이 발전하면 제품 개발자가 공유 라이브러리에 클라이언트 측 캐싱, 압축, 암호화 같은 기능 지원을 추가하기도 쉬웠습니다.
2025년 중반이 되자 클라이언트 측 구현으로서 Habitat은 한계에 도달했습니다. Habitat 계층이 복잡해지고 OpenAI의 서비스 수가 늘어나면서 이전 버전과 호환되는 프로토콜 변경이 불가능해졌습니다.
한 사례로, 가장 중요한 데이터 세트를 리전별로 분산된 Azure Cosmos DB 계정 집합으로 마이그레이션하여 단일 리전 장애의 영향 범위를 줄이고자 했습니다. 이를 변경하려면 기능 플래그로 비활성화된 추가 라우팅 로직을 클라이언트에 도입하고, 모든 클라이언트에 배포되었는지 확인한 뒤 기능 플래그를 활성화해야 했습니다.
수십 개 서비스의 배포를 조율하고 각 팀과 함께 출시하는 데 며칠이 걸렸습니다. 이를 활성화하기 전, 샤딩 로직이 정확한지 확인하기 위해 섀도잉을 도입해야 한다는 점을 깨달았습니다. 이를 배포하는 데 또 며칠이 걸렸습니다. 잘못된 부분을 발견해 버그를 수정하는 데는 어땠을까요? 또다시 며칠이 걸렸습니다. 마침내 플래그를 활성화할 준비가 되었지만, 한 팀이 관련 없는 이유로 서비스를 이전의 버그 있는 클라이언트로 롤백하면서 그토록 피하려 했던 장애가 발생했습니다.
클라이언트 라이브러리를 변경하려면 수십 개 서비스 간의 복잡한 조율이 필요했고, 이 프로세스는 갈수록 취약하고 비효율적이며 운영 장애가 발생하기 쉬워졌습니다. 향후 배포에서 이러한 운영상 팬아웃을 줄이기 위해 Habitat을 독립 서비스로 전환하기로 했습니다.
스토리지 로직을 독립형 서비스로 분리함으로써 배포, 관측 가능성, 플랫폼 개선을 위한 단일 제어 지점을 마련했습니다. 분산된 업데이트를 관리하는 대신 중앙에서 개선 사항을 구현하여 모든 OpenAI 제품에 즉시 혜택을 제공할 수 있었습니다.
중앙 집중식 서비스는 가장 강력한 데이터 보안 및 개인정보 보호 기본 요소를 제공하는 단일 관문 역할도 합니다. Habitat 서비스에서는 액세스 제어 정책을 중앙에서 적용하고, 감사 로그를 기록하며, Azure Cosmos DB 같은 기반 스토리지 리소스에 대한 접근을 제한할 수 있습니다. Habitat은 사용자 데이터를 보호하고 외부, 내부 및 에이전트 행위자의 무단 접근을 방지하는 데 핵심적인 역할을 합니다.
서비스가 필요하다는 점은 알고 있었지만, 서비스로 운영할 때 Python의 추가 오버헤드가 있더라도 당장은 Python에서 마이그레이션하고 싶지 않았습니다. 처리량이 높은 서비스에 Python을 사용하면 로컬 라이브러리 실행보다 네트워크 지연 시간이 늘고 CPU 및 메모리 확장 비용이 크게 증가했습니다. 게다가 규모가 100배 커지면 Python의 비효율성을 감당할 수 없으므로 결국 재작성해야 할 것이 거의 확실했습니다.
하지만 이는 전략적으로 기술 부채를 감수하는 결정이었습니다. 당시 최우선 목표는 비용이나 리소스 최적화가 아니라 제품 개발자의 장애 요소를 해소하고 플랫폼 안정성을 확보하는 것이었습니다. 단기적으로 Python 서비스의 성능상 절충을 받아들인 덕분에 더 시급한 과제를 우선 처리하고, 핵심 API를 확립하며, 견고한 인프라를 구축할 수 있었습니다.
또한 자체 코딩 모델이 빠르게 발전하면 향후 기술적 전환 과정이 간소해질 것이라는 계산도 있었습니다. Python에서 완전히 마이그레이션해야 할 때쯤이면 Codex와 GPT 덕분에 이를 실현할 수 있으리라 판단했습니다. 그 판단은 결국 옳은 것으로 드러났습니다.
Habitat을 Python 서비스로 운영하는 것은 성능 면에서 최선은 아니었지만 필요한 선택이었습니다. Python을 사용하면 빠르게 개발할 수 있지만, 그렇다고 주의 없이 눈에 띄게 긴 지연 시간을 감수할 수는 없었습니다. 평균적인 사용자 요청 하나가 수백 번의 데이터베이스 호출로 이어질 때 사용자가 체감하는 것은 가장 느린 호출입니다. 이 규모로 Python 서비스를 운영할 때의 핵심 과제는 이러한 꼬리 지연 시간을 관리하는 것이었습니다.
Asyncio는 Python이 I/O 중심 워크로드를 동시에 실행하도록 지원하지만, Python GIL을 우회하거나 CPU 병렬 처리를 제공하지는 않습니다. Habitat은 I/O 중심의 요청 프록시 외에도 라우팅, 압축, 암호화, 체크섬 계산, 다운스트림 상태 확인, 요청 섀도잉, 헤징 등 CPU 사용량이 많은 여러 작업과 백그라운드 작업을 처리합니다.
서비스에 CPU 사용량이 많은 워크로드와 백그라운드 작업이 이처럼 많으면 asyncio 스케줄링 지연이 요청의 꼬리 지연 시간을 쉽게 좌우할 수 있습니다. 초기 서비스 출시에 맞춰 튜닝하기 전, p99 이상의 지연 시간을 보인 요청의 트레이스를 살펴보니 다운스트림 스토리지는 빠르게 응답했지만 담당 코루틴이 응답을 파싱하도록 다시 스케줄링되기를 기다리는 동안 요청이 자주 멈췄습니다.
그림 03 · asyncio 지연 추적
동시성은 CPU 병렬 처리가 아닙니다
Python asyncio는 요청을 동시에 처리할 수 있지만, CPU 스레드에서는 한 번에 하나의 요청만 실행됩니다. CPU 작업량이 많으면 요청 지연 시간에 큰 영향을 줍니다.
적은 CPU 작업
짧은 Python 단계, I/O 대기 중첩많은 CPU 작업
긴 Python 단계로 준비된 응답이 계속 대기OpenAI의 Python 서비스에서는 메모리, CPU, 네트워크, 디스크 사용량에 관한 표준 사용률 및 포화도 메트릭뿐 아니라 asyncio 루프와 그 부하도 모니터링하고 그에 맞게 튜닝하는 것이 매우 중요합니다.
백그라운드 작업을 주기적으로 스케줄링하고 예상 실행 시간과 실제 실행 시간의 차이를 기록하여 이벤트 루프의 스케줄링 지연을 실시간으로 실측할 수 있습니다. 사용률이 높고 비용이 큰 작업이 많을 때는 프로세스당 동시 요청이 많지 않아도 수백 밀리초, 일부 극단적인 경우에는 수 초에 달하는 상당한 스케줄링 지터가 발생합니다.
이에 따라 각 프로세스가 소수의 동시 요청만 처리하도록 제한하는 대신 Python 워커 프로세스 수를 대폭 수평 확장합니다.
초기 서비스 출시 당시 라이브 서비스 CPU 프로파일링을 통해 asyncio 지연과 그에 따른 긴 꼬리 지연 시간의 한 가지 근본 원인을 발견했습니다. 바로 Statsig(기능 플래그를 관리하고 A/B 테스트 등을 실행하는 도구)를 통한 기능 플래그 구성의 주기적인 JSON 파싱이었습니다.
Statsig는 기본적으로 지터 없이 1분마다 갱신된 구성을 폴링하도록 설정되어 있었고, 구성에는 모든 서비스의 전체 프로덕션 규칙이 포함되어 있었습니다. 한편 CPU 사용률을 높이고 지연 시간을 줄이기 위해 포드당 최대 8개의 Python 프로세스를 실행하도록 아키텍처가 설계되어 있었습니다. 이 두 조건이 맞물리면서 매분 각 포드의 모든 워커가 처리 중인 요청을 잠시 멈추고 거대한 구성 파일을 파싱하는 데 CPU 사이클을 쓰는 순간이 발생했습니다.
CPU 프로파일링으로 근본 원인을 찾은 뒤 해결책은 간단했습니다. 더 작고 대상이 명확한 구성을 배포하고, 갱신 간격을 늘리며, 이러한 백그라운드 작업에 지터를 추가했습니다.
asyncio 지연을 낮게 유지하려면 서버 프로세스 전반에 요청 부하를 적절히 분산하는 것도 중요합니다. 연결 풀링 역시 튜닝하지 않으면 오히려 이를 방해할 수 있습니다.
클라이언트 측 연결 풀링에서는 동시 요청이 많은 단일 클라이언트 프로세스가 소수의 서버 연결만 설정하여 전체 부하를 몇몇 프로세스에만 보낼 수 있습니다. 부하 분산 방식을 조정하기 전에는 서비스 사용률의 편차가 컸으며, 일부 꼬리 프로세스는 평균보다 5~10배 많은 동시 요청을 처리했습니다.
서비스 일부에 과부하를 주던 클라이언트를 중지했는데도 요청이 급증한 뒤 일부 프로세스의 성능 저하가 오랫동안 계속된 우연한 사고를 통해 이 현상을 발견했습니다. 실제로 해당 프로세스는 다시 시작할 때까지 점점 더 많은 요청을 받으며 성능이 걷잡을 수 없이 악화되었습니다. 포드 하나에 과부하가 걸리면 어떤 동작으로 인해 과부하 포드에 더 많은 트래픽이 고정되었습니다. 이는 일부 팀원이 이전 업무를 통해 익숙하게 알고 있던 장애 유형인 준안정 장애(새 창에서 열기)였습니다.
연결 풀이 원인이라고 의심해 최대 연결 재사용 기간을 제한하는 방식으로 검증했습니다. 실제로 성능 저하가 제한되면서 조사 방향이 옳았음을 확인했습니다. 추가 조사 결과 Python의 aiohttp TCPConnector는 기본적으로 LIFO 방식으로 연결을 재사용하는 것으로 나타났습니다. 즉, 가장 최근에 반환된 연결이 다음 요청에 선택됩니다. 일반적으로 이는 합리적인 기본값입니다. 최근 연결을 재사용하면 트래픽 급증을 처리하기 위해 생성된 추가 연결이 유휴 시간 초과로 종료되어, 추가 연결 유지에 따른 오버헤드를 줄일 수 있습니다. 하지만 이 경우에는 준안정 장애를 일으켰습니다. 요청이 급증하는 동안 과부하로 느려진 서버의 요청은 연결을 풀에 더 늦게 반환했고, 이 때문에 후속 요청에서 더 자주 선택되어 이미 어려움을 겪는 포드에 점차 더 많은 트래픽이 집중되었습니다. 연결 풀이 FIFO 방식으로 재사용하도록 패치하자 이 피드백 루프가 끊어졌고 안정 상태의 요청 편차도 줄었습니다.
그림 04A · 클라이언트 측 연결 풀링
LIFO가 새 작업을 느린 프로세스로 다시 보냅니다
요청이 급증한 후에는 느린 서버의 연결이 풀에 가장 늦게 반환됩니다. LIFO는 같은 느린 서버에 작업이 더 집중되도록 만듭니다.
초기 요청 급증이 A, B 및 더 느린 프로세스 C에 도달합니다.
그림 04B · 클라이언트 측 연결 풀링
FIFO가 연결 재사용 피드백 루프를 차단합니다
FIFO는 요청 급증 후 활성 연결을 더 많이 유지하지만 모든 서버에 워크로드를 공정하게 분산합니다.
초기 요청 급증이 A, B 및 더 느린 프로세스 C에 도달합니다.
현재는 OpenAI 인프라 전반에서 연결 풀링과 서버 부하를 더 잘 인식하는 분산 전략을 제공하도록 주로 Istio와 Envoy에 의존하며, 이 문제를 근본적으로 방지합니다.
asyncio 지연을 낮추도록 튜닝하고 수많은 Python 프로세스를 운영할 때 나타나는 한 가지 부작용은 방대한 연결 수로 인해 다운스트림 종속 항목에 쉽게 과부하가 걸린다는 것입니다. 이를 ‘스탬피드 현상’이라고 합니다.
일상적인 배포도 천천히 진행되도록 튜닝하지 않으면 연결 순환으로 인해 상당한 CPU 변동을 일으킬 수 있습니다. 또는 연결 누수로 NAT 게이트웨이가 포화되어 네트워크가 중단될 수 있습니다. 다른 서비스에서도 드물지 않은 문제이지만, 프로세스가 한 자릿수 배 더 많으면 발생 임계점이 크게 낮아집니다. 순수 처리량만 기준으로 안정 상태에서 클라이언트가 처리해야 한다고 예상하지 못한 네트워크 관련 리소스가 포화되는 경우가 많습니다.
연결 팬인을 극대화하는 데도 Envoy를 사용합니다. Envoy를 사용해 Python의 HTTP/1 연결을 HTTP/2로 업그레이드하여 멀티플렉싱을 활용한 다음, 해당 연결을 풀링하고 연결 수명을 연장합니다. 또한 Envoy는 각 독립형 Python 프로세스에서 구현할 때보다 효과적인 속도 제한과 회로 차단기를 구현할 중앙 지점을 제공합니다.
그림 05 · 연결 팬인
같은 요청, 더 적은 연결
연결 풀링과 HTTP/2 연결 멀티플렉싱은 다운스트림의 연결 부하를 줄이는 데 도움이 됩니다.
Python을 이 정도 규모까지 확장할 수 있었던 한 가지 이유는 요청 비용을 예측 가능하게 유지하는 Habitat의 제한된 API였습니다. 클라이언트가 대규모 테이블 스캔이나 여러 테이블 간 조인으로 이어질 수 있는 임의의 SQL 쿼리를 작성하도록 허용하는 대신, Habitat은 단순한 NoSQL API를 제공합니다. 강력한 API를 제공하지 않는 것은 Habitat 설계에서 명시적으로 선택한 절충입니다.
단순하고 예측 가능하며 작업량이 일정한 요청에 최적화하는 것이 목표입니다. 경험상 이러한 시스템은 훨씬 쉽게 확장할 수 있고, 잘못 구현하거나 오용하기도 어렵습니다. 팬아웃을 예측할 수 없는 요청은 운영상 위험합니다. 격리와 부하 분산을 복잡하게 만들고, 서비스와 클라이언트 모두 확장으로 대응하기 어려운 급격한 지연 증가를 유발합니다.
Habitat과 Azure Cosmos DB로 이전하기 전에는 OpenAI 온라인 데이터의 대부분이 Postgres에 저장되어 있었습니다. 당시에는 모든 쿼리와 스키마 변경을 검토해 정상적으로 작동하고 인덱싱된 데이터에 접근하는지 확인한 후 프로덕션에 배포하기가 쉬웠습니다. 팀과 제품이 성장하면서 이는 빠르게 관리 불가능한 수준이 되었고, 핫 패스에 추가된 고비용 쿼리 하나가 데이터베이스를 중단시켜 장애를 일으키는 일이 잦았습니다.
문제의 핵심은 비용의 불균형입니다. 실행하기 어렵고 비용이 큰 SQL 쿼리도 저렴하고 쉽게 작성할 수 있습니다. Habitat에서는 이를 방지하고 비용이 큰 쿼리가 클라이언트 측에서 아주 명확히 드러나게 합니다. Habitat에 과부하를 줄 수 있는 무제한 쿼리는 없습니다. 복잡한 조인과 그래프 순회에는 제품 팀의 추가 작업이 필요하므로 전반적으로 더 효율적인 설계를 유도합니다.
Habitat은 TAO(새 창에서 열기)에서 영감을 받아 클라이언트가 정의한 객체 및 에지 유형을 중심으로 설계된 NoSQL API를 제공합니다. 클라이언트는 객체와 에지 및 그 관계를 미리 정의하지만 각 유형의 콘텐츠는 정의하지 않습니다. 그 결과 관계는 그래프와 유사하지만, Habitat 자체는 특정 객체의 직접 에지를 조회하는 것 외에 일반적인 그래프 순회 쿼리를 지원하지 않습니다.
각 객체와 해당 에지가 스토리지 수준 파티션에 함께 배치되도록 이 그래프를 분할하지만, 객체와 에지가 가리키는 원격 객체를 함께 배치하려고 데이터베이스 수준에서 별도로 조정하지는 않습니다. 그 결과 이 모델은 수평 확장을 위해 쉽게 분할할 수 있지만, 객체 사이를 한 번 이동할 때도 서로 다른 리전에 저장된 별개의 Azure Cosmos DB 계정 두 곳에서 데이터를 가져와야 할 수 있어 그래프 순회는 비효율적입니다.
더 복잡한 조회가 필요한 클라이언트에는 Rockset을 통해 접근할 수 있는 Habitat의 오프라인 보조 뷰를 제공합니다. 변경 데이터 캡처(CDC)를 사용해 온라인 스토리지의 변경 사항을 격리된 Rockset 인스턴스로 거의 실시간 스트리밍합니다. 각 클라이언트 팀은 복잡한 조회 요구에 맞춰 자체 Rockset 인스턴스를 확장할 책임이 있습니다.
이러한 Rockset 프로비저닝은 클라이언트에 추가 부담을 주지만, 현재로서는 적절한 절충이라고 판단합니다. 단순한 쿼리를 기본으로 삼되 복잡한 쿼리가 필요한 경우에는 대안을 제공하기 때문입니다. 이 설계는 읽기 중심의 분석 및 검색 워크로드로부터 온라인 스토리지를 격리합니다.
Python 재작성을 1년 미룬 덕분에 초고속 성장기에 더 시급하고 영향력 있는 과제에 집중할 수 있었습니다. 플랫폼이 성숙하고 성장이 계속 가속화되는 가운데, 코어 수 기준 OpenAI에서 두 번째로 큰 서비스이자 Envoy 규모 기준 네 번째로 큰 서비스가 되면서 마침내 Python을 벗어날 때가 되었습니다. 정점에서 Python은 초당 2천만 건이 넘는 요청을 처리하는 데 기여했습니다.
2026년 2분기에는 엔지니어 단 2명과 Codex, GPT‑5.5를 활용해 전체 서비스를 Rust로 재작성할 수 있었습니다. 새 Rust 서비스는 현재 프로덕션 요청의 95%를 처리하고 있으며, 앞으로 몇 주 안에 Python을 완전히 폐기할 예정입니다. 데이터에 따르면 Rust 서비스는 Python 버전보다 CPU 효율이 6배, 메모리 효율이 15배 높으며 평균 지연 시간과 꼬리 지연 시간도 크게 줄었습니다. 향후 블로그에서 더 많은 교훈을 공유할 예정입니다.
Python 서비스와 현재의 Rust 서비스는 Habitat의 한 측면에 불과합니다. 10억 명이 넘는 ChatGPT 사용자를 지원하기 위해 온라인 스토리지를 빠르게 확장한 방법을 설명하는 이 시리즈의 2부에서는 스토리지 계층과 Habitat이 500페타바이트 이상의 데이터 및 초당 7천만 건 이상의 요청을 처리하는 방법을 다룹니다.
프런티어 규모의 OLTP 시스템을 개발하고 싶고 이런 엔지니어링에 관심이 있다면 팀의 채용 공고를 확인해 보세요.


