주요 컨텐츠로 이동
데이터 전략

Databricks Apps 확장을 위한 개발자 가이드

사용량이 늘어나도 앱을 빠르고 안정적으로 유지하는 방법

작성자: Bruno Tafur , Tushar Madan

  • Databricks Apps의 확장 규모 산정은 코드 작성 전에 시작됩니다. 앱의 응답 속도와 최대 사용량 기준 동시 사용자 수를 정한 다음, 무거운 작업은 적절한 서비스로 라우팅하세요. 앱 컴퓨팅은 UI를 제공하고 호출을 조율합니다.
  • 확장성 있는 코드는 서비스 대기 중에도 앱이 응답 가능한 상태를 유지하게 하고, 사용자별 캐싱을 활용하며, 상태 복구 가능성을 보장합니다. 소프트 상태는 다시 생성할 수 있으며, 하드 상태는 Lakebase 또는 Unity Catalog 테이블에 저장되므로 어떤 인스턴스에서든 세션을 복구할 수 있습니다.
  • 부하 테스트와 텔레메트리를 활용해 인스턴스 크기, 워커 수, 인스턴스 수를 결정하세요. Lakebase 연결을 예산에 맞춰 관리하고, 측정된 수요와 가용성 목표에 맞춰 컴퓨팅 리소스를 추가하세요.

축하합니다. Databricks Apps에서 앱을 구축했으며 조직 전체에서 사용자 수가 몇 명에서 수백 또는 수천 명으로 늘어났습니다. 사용자는 앱이 빠르게 응답하고 다운타임 없이 유지되기를 원합니다. 또한 상사는 여러 인스턴스 스택에 걸쳐 XLarge 컴퓨팅 비용을 지불해야 하는 것을 좋아하지 않을 수 있습니다.

빠르게 실행되고, 다운타임이 없으며, 증가하는 수요를 처리하는 앱을 어떻게 만들 수 있나요? 직관적인 답은 더 많은 컴퓨팅이지만, 이는 요청이 소요되는 시간과 앱이 확장되도록 구축되었는지(프레임워크, 비동기 코드 및 여러 인스턴스에서 실행되는 기능 등)를 파악한 후에야 플랫폼이 앱을 쉽게 수직 또는 수평 확장할 수 있도록 도와줍니다.

이 가이드에서는 디자인, 구축, 테스트 및 배포, 운영의 4단계에 걸쳐 Databricks Apps를 확장하는 방법을 살펴봅니다(그림 1). 

이 가이드의 초점은 주로 대규모에서의 애플리케이션 성능과 복원력에 있으며, 배포 자동화나 앱과 상호 작용할 수 있는 다른 Databricks 서비스의 성능 최적화 및 확장은 다루지 않습니다.

image1.png

그림 1: Databricks App 확장 4단계.

좋은 확장 결정은 코드가 작성되기 전에 시작됩니다. 앱에서 사용자가 필요로 하는 사항에 동의한 후 작업이 실행될 위치와 데이터가 상주할 위치를 결정하세요.

목표 설정부터 시작하기: 최대 사용자 수와 지연 시간

아키텍처를 선택하기 전에 앱이 처리해야 하는 부하와 우수한 사용자 경험이 어떤 모습인지 파악하는 것이 좋습니다. 두 가지 주요 목표에 동의하는 것을 권장합니다.

  • 성능: 주요 작업에 얼마나 빠르게 응답해야 합니까? 평균으로는 나타나지 않는 느린 경험을 포착하는 p95와 같은 백분위수를 기반으로 엔드투엔드 지연 시간 목표를 권장합니다. UI 렌더링을 포함하고 콜드 스타트는 별도로 처리하세요. 스트리밍 AI 응답의 경우 첫 번째 토큰까지의 시간(time to first token)도 중요합니다.
  • 확장성: 최고조 시 활성 사용자는 몇 명이며, 얼마나 자주 사용하고, 앱이 어느 정도의 성장을 지원해야 합니까? 월말과 같은 바쁜 시기는 앱이 지연 시간 및 오류율 목표 내에서 처리해야 하는 부하이기 때문에 이 추정치에 포함됩니다.

이와 함께 재시작 후에도 유지되어야 하는 작업이 무엇인지 결정하고 중요한 종속성이 이를 지원할 수 있는지 확인하세요. 이는 상태를 분할하는 방식과 실행하는 인스턴스 수를 결정합니다.

다음으로 대시보드 열기나 질문 제출과 같은 몇 가지 사용자 여정을 스케치합니다. 각 작업에 대해 호출하는 서비스, 대략적인 호출 횟수, 서로 의존하는 서비스, 완료되어야 하는 속도, 캐시된 데이터가 얼마나 오래될 수 있는지 기록합니다. 이러한 가정은 아키텍처와 첫 번째 테스트 목표를 형성합니다. 프로토콜이 실행되면 실제 호출을 측정하고 수정할 수 있습니다.

소매업체가 2,000명의 매장 관리자에게 Lakebase를 기반으로 재고를 확인할 수 있는 앱을 제공한다고 가정해 보겠습니다. 블랙 프라이데이의 가장 바쁜 시간 동안 그중 200명이 동시에 사용하고 있습니다. 각 관리자가 분당 평균 2회의 재고 조회를 수행하는 경우 이는 분당 400회의 조회입니다. 각 조회에서 Lakebase에 대해 3개의 SQL 문을 실행하는 경우, 해당 시간 동안 분당 1,200개 또는 평균 초당 20개의 문을 예상할 수 있습니다.

이는 동시성이 아닌 쿼리 비율을 추정합니다. 버스트와 성장을 테스트하고, 실제 사용량에 대해 유효성을 검사하며, 연결 예산을 별도로 책정하세요("Lakebase 연결 예산 책정" 참조).

디자인: 아키텍처 계획

앱 컴퓨팅은 앱 서빙용으로 유지하기

앱 컴퓨팅은 무거운 작업을 수행하기 위한 것이 아니라 UI를 서빙하고 호출을 조정하기 위한 것입니다. 각 종류의 작업을 이를 위해 구축된 서비스로 보내는 것을 권장합니다(그림 2). 장기 실행 호출의 경우 완료될 때까지 하나의 요청을 열어두는 대신 작업을 백그라운드에서 실행하고(예: 작업으로), UI가 상태를 폴링하거나 스트리밍된 업데이트를 받도록 하세요.

앱이 사용자가 작성하거나 에이전트가 생성한 코드와 같이 제어할 수 없는 코드를 실행해야 하는 경우 앱에서 실행하지 마세요. 사용자 지상 이미지를 시작할 수 있는 격리된 환경인 Databricks Sandbox에서 실행하여 CPU 및 메모리 사용량이 사용자를 서빙하는 인스턴스에 영향을 주지 않도록 하세요.

image4.png

그림 2: 각 종류의 작업이 실행되는 위치와 상태가 상주하는 위치.

규모 확장을 계획하고 프레임워크 선택하기

더 많은 사람들이 앱을 사용할 때 용량을 추가하는 방법에는 두 가지가 있습니다. 각 인스턴스에 더 많은 CPU와 메모리를 제공하는 더 큰 컴퓨팅 크기로 이동하여 수직 확장(scale up)하거나, 요청 부하를 분산하기 위해 인스턴스를 추가하여 수평 확장(scale out)하는 것입니다. 무거운 작업이 앱 외부에서 실행되는 경우 일반적으로 한 번에 처리할 수 있는 요청 수가 제한 요소가 됩니다.

예를 들어 블랙 프라이데이 사례에서 각 재고 조호는 가볍지만 200명의 매장 관리자의 조회가 버스트 형태로 한꺼번에 도착할 수 있습니다. 인스턴스가 많아지면 해당 요청이 분산되며, 앱이 추가 코어(일반적으로 더 많은 작업자 실행)를 사용할 수 있는 경우 더 큰 인스턴스가 도움이 됩니다. 메모리에 큰 참조 데이터셋이나 모델을 유지하는 앱은 다른 제한에 도달합니다. 더 큰 인스턴스는 필요한 메모리를 제공하지만, 각 인스턴스가 자체 복사본을 로드하기 때문에 인스턴스를 추가해도 도움이 되지 않습니다. Medium에서 시작하여 이 가이드의 뒷부분에 나오는 부하 테스트를 통해 필요한 항목을 확인할 수 있습니다.

프레임워크는 나중에 변경하기 더 어려우므로 지금 선택하는 것이 좋습니다. Databricks Apps는 Python 또는 Node.js로 구축된 앱을 실행하며 아래 프레임워크에 국한되지 않습니다. 대부분의 새 앱의 경우 databricks apps init 및 Databricks 에이전트 스킬이 기본적으로 사용하는 TypeScript SDK인 AppKit을 권장합니다. 캐싱, 텔레메트리, 재시도 로직, 오류 처리가 기본적으로 제공되므로 이 가이드의 여러 관행에 대한 시작점을 제공합니다. AppKit은 기본적으로 인스턴스당 하나의 Node.js 프로세스를 실행하므로 확장하는 가장 간단한 방법은 인스턴스를 추가하는 것입니다.

이미 앱이 있거나 백엔드에 Python이 필요한 경우:

  • API 백엔드(FastAPI, Flask 또는 Express)가 있는 JavaScript 프론트엔드: 브라우저에 UI 상태를 유지하고 작업자와 인스턴스 간에 서버측 상태를 복구할 수 있도록 만드세요. Python 백엔드는 Uvicorn 또는 Gunicorn을 사용하여 인스턴스당 여러 작업자를 실행할 수 있습니다. Node.js 백엔드는 기본적으로 인스턴스당 하나의 프로세스를 실행하므로 인스턴스를 추가하여 확장하세요.
  • Streamlit 또는 Gradio 프레임워크: Python에서 빠르게 구축된 데이터 및 AI 도구에 적합합니다. Streamlit은 단일 프로세스로 실행되며 둘 다 인스턴스 로컬 세션 처리에 의존하므로 재시작 및 확장 시 세션 연속성을 테스트하세요. 원활한 복구와 함께 인스턴스 간에 확장해야 하는 앱의 경우 이러한 프레임워크는 권장되지 않으므로 위의 접근 방식 중 하나를 선호하세요.

어떤 것을 선택하든 서버 메모리에 세션 상태를 유지하는 경우 규모를 확장하기 전에 세션이 다른 인스턴스로 이동할 때 어떤 일이 발생하는지 테스트하는 것이 좋습니다.

재시작 및 재조정 후에도 유지되는 애플리케이션 상태 계획

대부분의 Databricks Apps는 일부 상태를 메모리에 유지하며 잃어도 되는 부분을 알고 있는 한 괜찮습니다. 유용한 첫 번째 단계는 각 세션이 보유하는 것과 재시작 후에도 유지되어야 하는 것을 나열한 다음 소프트 상태와 하드 상태로 분할하는 것입니다.

항목소프트 상태하드 상태
항목속도나 컨텍스트를 위해 유지되는 임시 작업 데이터영구적으로 유지되는 진실의 원천(source of truth)
예시인메모리 컨텍스트, 캐시, 진행 중인 작업비즈니스 레코드, 체크포인트, 저장된 기본 설정
위치일반적으로 인스턴스 메모리 또는 로컬 디스크, 단일 인스턴스에 연결됨Lakebase 또는 Unity Catalog 테이블, 모든 인스턴스에서 사용 가능
손실 시가능한 경우 하드 상태에서 다시 구축됨복구 요구 사항 내에서 재시작 및 실패를 견뎌야 함

이 분할이 작동하는 방식은 앱 종류에 따라 다릅니다.

  • AI 에이전트: 루프가 실행되는 동안 대화 컨텍스트, 도구 출력 및 계획을 소프트 상태로 유지하고 의미 있는 단계마다 체크포인트를 저장합니다.
  • 워크플로우 앱: 진행 중인 상태를 UI에 스트리밍 또는 폴링하고 완료된 각 단계를 저장합니다.
  • 대시보드: 필터 값, 참조 목록 및 소규모 데이터셋을 메모리에 유지하고 사용자 기본 설정 및 저장된 필터를 하드 상태로 저장합니다.

image3.png

그림 3: 세션이 이동할 때 다른 인스턴스가 하드 상태에서 이를 다시 구축할 수 있습니다.

Databricks Apps는 최선 노력(best-effort) 원칙에 따라 각 사용자를 동일한 인스턴스에 유지하고(세션 선호도) 필요할 때 세션을 재조정하므로 앱이 로컬에 유지하는 사용자별 캐시는 일반적으로 계속 사용할 수 있습니다. 재시작, 실패 및 확장 변경으로 인해 세션이 이동할 수 있으므로 다른 인스턴스가 하드 상태에서 이를 다시 구축할 수 있어야 합니다(그림 3).

구축: 확장 가능하고 재시작 후에도 유지되는 코드 작성

목표와 아키텍처가 마련되면 다음 단계는 세션이 이동하거나 인스턴스가 중지될 때를 포함하여 부하를 견디는 코드를 작성하는 것입니다.

필요하기 전에 앱 계측하기

필요하기 전에 데이터가 미리 준비되어 있도록 처음부터 텔레메트리를 켜는 것을 권장합니다. 앱 텔레메트리는 OpenTelemetry를 통해 로그, 추적 및 메트릭을 Unity Catalog 테이블에 기록합니다. 앱에 대해 기능이 활성화되면 로그는 자동으로 도착하지만, 추적 및 메트릭에는 계측이 필요합니다.

시간이 소요되는 부분을 파악할 수 있도록 SQL, 데이터베이스, 모델 및 API 호출 주변에 커스텀 스팬을 생성해야 합니다. 또한 추적에 표시되도록 포착된 예외를 스팬에 기록하세요. 그런 다음 추적 및 요청 ID를 사용해 인스턴스 전반에 걸쳐 단일 사용자의 요청을 추적할 수 있습니다. 예를 들어 SQL 호출 주변의 스팬은 다음과 같습니다.

비동기 코드를 사용하고 불필요한 호출 줄이기

대부분의 앱은 SQL 쿼리, 모델 호출, 외부 API 등 다른 서비스를 기다리는 데 시간을 보냅니다. 차단 호출의 경우 각 대기 작업은 전체 호출 동안 실행 슬롯을 점유합니다. 몇 가지 느린 호출만으로도 해당 용량이 고갈될 수 있습니다. 이것이 I/O 중심 작업에서 비동기 핸들러가 중요한 이유입니다. 핸들러가 모델 및 데이터베이스 호출을 대기하는 동안, 해당 호출이 비차단식인 경우 하나의 작업자가 대기하면서 다른 요청을 계속 처리할 수 있습니다. 추적 및 시스템 메트릭을 통해 이 상황을 확인할 수 있습니다. 요청 시간의 대부분이 SQL, 모델 또는 API 스팬에서 소모되고 CPU 사용량은 낮은 상태에서 동시 사용자 수에 따라 지연 시간이 증가한다면, 요청이 차단 호출 뒤에서 대기하고 있을 가능성이 높습니다.

비동기를 사용하더라도 쿼리를 순차적으로 실행하면 하나의 요청이 여전히 느려질 수 있습니다. (예: asyncio.gather 또는 Promise.all를 사용하여) 독립적인 쿼리를 동시에 시작하면 요청이 가장 느린 쿼리와 비슷한 시간에 완료됩니다. 또한 하나의 요청이 웨어하우스나 데이터베이스에 부하를 과도하게 주지 않도록 병렬 실행 수를 제한하는 것이 좋습니다. 앱이 목록을 가져온 후 항목당 하나의 쿼리를 추가로 실행하는 N+1 쿼리를 실행하는 것보다 쿼리를 결합하는 것이 더 나은 경우가 많습니다. join 또는 IN 절을 사용하면 한두 번의 작업으로 동일한 결과를 얻을 수 있습니다.

기본적으로 사용자별 데이터 캐시

캐시는 앱 속도를 높이지만 데이터를 유출할 수도 있습니다. 앱 수준 캐시는 Unity Catalog 권한을 강제하지 않으므로 공유 캐시를 사용하면 한 사용자가 다른 사용자의 데이터를 볼 수 있습니다. 사용자의 검증된 신원, 쿼리 매개변수, 그리고 필요한 경우 세션별로 캐시 키의 범위를 지정하세요. 검증 없이 클라이언트가 보낸 신원을 키로 사용하지 마세요. 캐시된 데이터는 모든 사람에게 동일한 경우에만 공유하세요. 많은 사용자가 동시에 읽는 공유 항목의 경우, 모든 사용자가 한 번에 웨어하우스에 접속하지 않도록 하나의 요청이 만료된 항목을 갱신하는 동안 다른 요청들이 대기하도록 하세요. 예를 들어 AppKit의 캐시는 각 인스턴스 내에서 동시 캐시 미스를 중복 제거합니다.

앱 컨테이너 재시작 또는 세션 이동 시

소프트 상태 및 하드 상태 설계를 실제로 적용하는 것은 몇 가지 권장 사항으로 요약됩니다.

  • 재시작이나 배포 후에도 유지되어야 하는 모든 데이터를 영구 저장하세요. 메모리만 사용하는 것은 일회성 캐시에는 적합하지만, 사용자가 손실을 감수할 수 없는 작업에는 적합하지 않습니다.
  • 작업을 반복하고 싶지 않은 모든 지점에 체크포인트를 설정하고, 재시도가 안전하도록 단계를 멱등성 있게 만드세요.
  • 어떤 인스턴스든 하드 상태에서 세션을 재구축할 수 있도록 세션을 이탈 가능하게 만드세요(그림 3). 필요한 항목만 다시 로드하고 캐시하여 반복 읽기를 방지하세요.
  • 브라우저 앱은 세션 친화성을 자동으로 제공합니다. 상태 비저장 API 클라이언트의 경우 안정적인 X-Routing-Key 헤더를 전송하고 소프트 상태를 소유하는 대상을 기준으로 키를 지정하세요. 테넌트 ID보다는 대화 ID나 사용자 ID와 같이 부하를 분산하기에 충분히 구체적인 키를 선택하세요. 클라이언트가 헤더를 설정하므로 라우팅용으로만 사용하고 사용자가 누구인지 결정하는 데는 절대 사용하지 마세요.
  • 데이터베이스 연결 끊김 현상도 대비해야 합니다. 데이터베이스가 재시작되거나 장애 조치될 때 연결이 끊어집니다. 모든 인스턴스가 동시에 재연결되어 연결 폭주(connection storm)를 일으키지 않도록 제한된 백오프(backoff)와 지터(jitter)를 사용하여 재연결하세요. 쓰기 작업을 다시 시도하기 전에 데이터베이스를 확인하여 작업이 이미 완료되지 않았는지 확인하세요.
  • 시작 단계를 가볍게 유지하세요. 모든 재시작, 배포 및 새 인스턴스는 트래픽을 처리하기 전에 모델 또는 데이터셋 로드, 캐시 워밍, 풀 오픈에 대한 비용을 지불해야 합니다. 시작 시 대규모 설치 및 차단 외부 호출을 피하고, 무거운 리소스는 필요할 때만 로드하세요.

안전하게 종료

앱을 다시 배포할 때 Databricks는 SIGTERM을 보내고, 앱이 15초 이내에 종료되지 않으면 SIGKILL을 보냅니다. 이 시간 창은 최종 체크포인트를 위한 것입니다. 중요한 작업은 정상 운영 중에 이미 저장되어 있어야 합니다.

예를 들어 FastAPI를 사용하는 경우 Uvicorn은 수명 주기 정리를 실행하기 전에 열려 있는 요청을 완료합니다. save_in_progress_sessions()은 완료되지 않은 작업을 저장하는 사용자 지정 함수를 대신합니다.

여기서는 비동기 풀(예: psycopg의 AsyncConnectionPool)을 가정합니다. Apps-to-Lakebase 튜토리얼에서는 동기식 풀을 사용하며, await 없이 닫습니다.

오래 실행되는 요청이 체크포인트 시간을 소모하지 않도록 Uvicorn의 --timeout-graceful-shutdown을 15초 미만(예: 10초)으로 설정하고 자체 워크로드로 종료 테스트를 수행하세요. AppKit의 Lakebase 플러그인은 종료 시 풀을 닫으며, 모든 커스텀 체크포인팅 역시 동일한 시간 창 내에 완료되어야 합니다.

테스트 및 배포: 부하 테스트 및 피크에 맞는 규모 산정

image2.png

그림 4: 단계별 부하 테스트 중 시스템 메트릭: CPU 및 메모리가 한계 이하로 유지되는 동안 마지막 단계에서 지연 시간이 급증합니다.

출시 전에 부하 테스트를 수행하면 예상치를 실제에 더 가까운 의사결정으로 전환하는 데 도움이 됩니다. 인스턴스 크기, 인스턴스당 작업자 수, 인스턴스 수가 여기에 포함됩니다.

Databricks Apps 부하 테스트 방법

예상되는 피크 시점의 실제 사용자 여정을 사용하여 프로덕션 환경 전에 부하 테스트를 수행하는 것이 좋습니다. Locust와 같은 도구는 초당 요청 수, 지연 시간 백분위수 및 각 단계별 실패율을 보고하며, 테스트는 주요 작업에 대해 합의한 지연 시간 및 오류율 목표를 기준으로 통과 또는 실패가 결정됩니다. 테스트가 실행되는 동안 앱의 기본 제공 시스템 메트릭은 분당 요청 수, 지연 시간, 한계 대비 CPU 및 메모리 사용량을 보여주므로 앱이 어떤 한계에 먼저 도달하는지 확인할 수 있습니다(그림 4).

처리량이 증가하지 않거나 지연 시간 및 오류율이 목표치를 초과할 때까지 동시 사용자 수를 단계적으로 늘립니다. 더 큰 설정이 항상 더 빠른 것은 아니므로 여러 인스턴스 크기와 작업자 수를 시도해 보는 것이 좋습니다. 또한 테스트 환경에서 복구를 테스트하는 것을 권장합니다. 실행 중에 단순히 재배포하거나 인스턴스 수를 변경하는 것이 아니라 앱을 중지했다가 시작하여 사용자가 계속 진행할 수 있는지, 복구에 얼마나 걸리는지, 작업 손실이 발생하지 않는지 확인하세요. 에이전트 앱의 경우 부하 테스트 가이드를 참고하여 모의(mocked) LLM으로 한 번 테스트하여 앱 자체의 처리량을 측정하고, 실제 모델로 엔드투엔드 지연 시간을 측정해 보세요.

부하 생성기 자체가 병목 현상의 원인이 될 수 있습니다. CPU나 연결이 먼저 고갈될 수 있으며, 인증 오류나 속도 제한 응답이 속도 저하처럼 보일 수 있습니다. 중요한 것은 잠깐의 스파이크가 아니라 지연 시간 목표 내에서 성공적인 요청이 지속되는 것입니다.

또한 부하 테스트를 통해 앱 뒤의 서비스들이 원활하게 유지되는지 확인해야 합니다. 웨어하우스가 대기열에 들어가거나 모델 엔드포인트가 스로틀링을 유발하는 경우, 앱이 아니라 해당 서비스를 확장하세요.

인스턴스 크기 선택

Databricks Apps는 세 가지 크기를 제공합니다. Medium(기본값, 최대 2 vCPU 및 6 GB), Large(최대 4 vCPU, 12 GB), XLarge(최대 12 vCPU, 48 GB). 적절한 크기는 앱이 도달하는 첫 번째 한계에 따라 달라지므로 Medium으로 시작하여 부하 테스트를 통해 적절한 크기를 확인하세요.

부하 테스트 결과예상 원인권장 조치
낮은 앱 CPU 사용률로 인한 느린 요청앱이 백엔드 작업을 대기 중이거나 차단 호출이 워커를 점유하고 있습니다크기를 유지하세요. 쿼리, 웨어하우스, 커넥션 풀 또는 차단 호출을 먼저 수정하고, 프로세스별 CPU도 확인하세요. 코어 하나가 최대치로 사용되면 전체 CPU 사용률은 낮아 보일 수 있습니다
CPU가 한계에 근접하고 서버가 여러 워커를 실행하는 경우 (예: Uvicorn을 사용하는 FastAPI)앱이 더 많은 코어를 사용할 수 있습니다Large로 변경하세요
CPU가 한계에 근접하고 단일 프로세스 앱인 경우 (Streamlit 또는 기본 설정의 AppKit)프로파일링 결과 작업이 하나의 코어에 집중되어 있습니다인스턴스를 추가하세요. 크기를 키우는 것은 워커 스레드나 네이티브 라이브러리 등을 통해 앱이 추가 코어를 활용할 수 있는 경우에만 도움이 됩니다
메모리가 한계에 근접대규모 데이터셋이나 모델이 메모리에 적재되어 있음메모리 사양을 높이세요. Large는 Medium의 두 배이며, XLarge는 단일 인스턴스에서 48GB를 제공합니다
복구 테스트: 유일한 인스턴스가 재시작될 때 앱이 다운됨인수인계할 예비 인스턴스가 없음인스턴스 크기를 키우지 말고 인스턴스를 추가하세요

각 인스턴스에서 몇 개의 워커를 실행해야 하나요?

워커는 각 인스턴스 내의 서버 프로세스입니다. 이 모델을 지원하는 Python 서버의 경우 시작 시 개수를 설정하며(uvicorn --workers 2 등), 이는 인스턴스별로 적용됩니다.

단일 워커는 CPU를 유휴 상태로 둘 수 있지만, 워커가 너무 많으면 CPU와 메모리를 두고 경쟁하게 됩니다. 부하 테스트 가이드의 벤치마크에서는 Medium이 4개의 워커를 사용할 때보다 2개를 사용할 때 더 나은 성능을 보였으며, Large는 Medium 처리량의 약 2.2배를 제공했습니다. 문서화된 시작점(Medium의 경우 워커 2개, Large의 경우 워커 8개)은 가이드라인으로만 참고하세요. 벤치마크는 LLM을 모의(mock) 실험하여 CPU 집약적이었지만, 주로 모델 호출을 대기하는 실제 앱은 추가 워커로부터 더 많은 이점을 얻을 수 있습니다. 실제 모델을 사용한 자체 부하 테스트를 통해 개수를 결정하세요.

앱에서 몇 개의 인스턴스를 실행해야 하나요?

수평 확장을 사용하면 인스턴스 수를 직접 설정할 수 있습니다. 기본 제한은 앱당 5개의 인스턴스이며, 부하 테스트 결과 더 많은 인스턴스가 필요한 경우 Databricks 담당자를 통해 제한을 늘릴 수 있습니다. 예상되는 피크 트래픽과 성장에 맞춰 인스턴스 수를 산정하세요. 인스턴스 수가 변경되는 동안에도 앱은 계속해서 서비스를 제공하며, 컴퓨팅 비용은 인스턴스 수에 비례하여 증가합니다. 기존 앱을 변환하는 경우 먼저 복제본에서 테스트해 보세요.

고가용성을 위해 최소 두 개의 인스턴스를 권장하며, 하나의 인스턴스에 장애가 발생하더라도 피크 부하를 처리할 수 있는 충분한 용량을 확보하는 것이 좋습니다. 예를 들어 피크 시점에 인스턴스 2개가 필요한 경우 3개를 실행하세요. 추가 인스턴스는 인스턴스 장애로부터 보호해주지만, 앱 백엔드 서비스의 문제까지 해결해 주지는 않습니다.

### Lakebase 연결 예산 책정

OAuth를 사용하여 Lakebase에 연결하는 Databricks App의 경우, 데이터베이스의 표준(PgBouncer가 아닌) 연결 문자열에서 앱 측 커넥션 풀을 사용하여 시작하는 것을 권장합니다. Python용 Apps-to-Lakebase 튜토리얼에서 볼 수 있듯이, 이 방식은 연결을 재사용하고 새로운 연결을 열 때 최신 OAuth 자격 증명을 가져옵니다. 요청 제한 시간 전에 쿼리 자체를 위한 충분한 시간을 확보할 수 있도록 풀 타임아웃을 설정하세요.

이러한 연결이 누적되므로 인스턴스나 워커를 추가하기 전에 미리 예산을 책정해야 합니다. 워커당 하나의 풀이 있는 경우 최대 한도는 인스턴스 수 × 인스턴스당 워커 수 × 최대 풀 크기입니다. 예를 들어 인스턴스 5개, 워커 8개, 최대 풀 크기 10인 경우 최대 400개의 연결을 열 수 있습니다. 다른 클라이언트와 앱이 사용자를 대신하여 여는 연결을 추가한 후, 총합을 데이터베이스의 문서화된 제한과 비교하고 구버전과 신버전이 병행 실행되는 배포를 위한 여유 공간을 남겨두세요.

사용자 대행(OBO) 쿼리에는 ID 용량이 필요합니다. 즉, Lakebase를 자신으로 조회하는 각 사용자는 자신만의 Postgres 역할이 필요하며, Lakebase는 브랜치당 500개의 역할을 허용합니다. 사용자 기반이 큰 경우, 어떤 쿼리에 실제로 사용자별 액세스가 필요한지 일찍 결정하세요. 인스턴스를 추가해도 이 제한은 변경되지 않습니다. 그룹 수준 권한으로도 충분한 경우, Databricks 그룹에 대한 Postgres 역할을 통해 구성원이 자신의 OAuth 토큰으로 연결할 수 있으므로 하나의 역할로 전체 그룹을 커버할 수 있습니다.

중단 없는 배포 및 안전한 롤백

수평 확장된 앱의 경우 Databricks는 하나의 인스턴스를 먼저 업데이트하고 나머지는 성공 후에 업데이트하므로 앱이 계속 서비스를 제공합니다. 배포 후에는 앱이 정상 상태이고 세션이 복구되는지 여부를 확인하는 것이 좋습니다. 코드를 Git으로 관리하면 알려진 정상 태그나 커밋으로 다시 배포하여 쉽게 롤백할 수 있습니다. 롤백 중에는 구버전과 신버전이 함께 실행되므로 데이터베이스 및 체크포인트 형식을 양쪽 모두에서 읽을 수 있도록 유지하고, 롤백하지 않겠다고 확신하기 전에는 이전 버전에서 필요한 필드를 삭제하지 마세요.

운영: 데이터 기반 모니터링, 진단 및 문제 해결

출시 후에는 가장 느린 단계를 찾아 수정하고 다시 측정하는 과정이 반복됩니다. 이것이 프로덕션 환경에서 텔레메트리를 계속 켜두는 이유입니다. 수평 확장된 앱의 경우 로그 탭의 라이브 뷰는 한 번에 하나의 인스턴스만 보여주지만, 텔레메트리가 활성화된 경우 앱 텔레메트리 로그에서 모든 인스턴스를 볼 수 있습니다.

작동이 느려지면 요청을 처음부터 끝까지 추적하세요(그림 5).

image5.png

그림 5: 요청이 소요되는 시간과 주요 병목 현상.

증상부터 파악하기

다음은 가장 흔히 발생하는 증상과 그 원인입니다.

증상확인 위치예상 원인조치 방법
유휴 기간 또는 배포 후 첫 번째 요청이 느림인사이트 탭 시스템 메트릭 및 앱 텔레메트리의 추적콜드 스타트: 앱 시작 또는 유휴 상태에서 깨어나는 서비스앱 시작 시간과 유휴 시 Lakebase 또는 SQL 웨어하우스가 중지되는지 확인하고, 시작 과정을 가볍게 유지하세요
낮은 앱 CPU 사용률로 인한 느린 요청인사이트 탭 시스템 메트릭 및 앱 텔레메트리의 추적앱이 백엔드 작업을 대기 중이거나 차단 호출이 워커를 점유하고 있음

앱 컴퓨팅을 추가하기 전에 쿼리, 웨어하우스 또는 커넥션 풀 지연에 대한 추적을 확인하세요

단일 프로세스 앱의 경우, 전체 CPU 사용률이 낮더라도 하나의 코어는 최대치로 사용되고 있을 수 있음을 고려하세요

앱 CPU 또는 메모리가 한계에 근접인사이트 탭 시스템 메트릭앱 자체가 병목 현상이거나 메모리에 너무 많은 데이터를 유지하고 있음CPU 집약적인 작업을 프로파일링하고, 대용량 상태를 메모리에서 제거한 후 "인스턴스 크기 선택" 지침을 참고하세요
데이터베이스 연결 대기 중 시간 초과앱 로그 및 Lakebase 메트릭풀 경합, 긴 트랜잭션 또는 데이터베이스 연결 제한연결 사용량과 트랜잭션 지속 시간을 검사한 후 연결 예산 내에서 풀 또는 데이터베이스 용량을 조정하세요
배포 또는 재조정 중 사용자가 작업을 잃거나 오류 발생인사이트 탭 시스템 메트릭다시 빌드할 수 없는 소프트 상태 또는 15초 내에 완료되지 않는 종료중요한 작업에 체크포인트를 설정하고, 모든 인스턴스에서 세션을 다시 빌드할 수 있도록 만들며, 실제 요청과 스트림으로 종료 테스트를 수행하세요

상태 알림 설정

설정 과정의 일환으로 알림을 미리 계획하는 것을 권장합니다. 앱이 다운되었을 때 알림을 받을 사람을 결정하고, Apps API의 app_status.state 및 compute_status.state를 모니터링 도구에 연동하세요. 앱 상태만으로는 사용자가 정상적으로 작업할 수 있음을 증명할 수 없으므로, 대기 시간과 오류율을 포함한 대표적인 사용자 여정도 함께 확인하세요. 임계값을 설정할 때는 배포 중 발생하는 짧은 상태 변경을 고려하세요.

요약

Databricks Apps를 확장한다는 것은 앱 서버뿐만 아니라 전체 요청 경로의 크기를 조절하는 것을 의미합니다. 지연 시간 및 피크 부하 목표를 설정하고, 무거운 작업은 전용 서비스로 오프로드하며, 상태를 복구 가능한 상태로 유지하고, 부하 테스트와 텔레메트리를 통해 용량을 할당하세요. 즉흥적인 대응이 아닌 측정을 통해 필요성이 확인되었을 때 컴퓨팅을 추가하세요.

자세한 내용은 Databricks Apps 및 Lakebase를 사용하여 프로덕션준비가 완료된 데이터 및 AI 앱을 구축하는 방법을 읽어보세요. 자세한 내용은 설명서의 Databricks Apps 모범 사례 및 Databricks Apps 로깅 및 모니터링을 참고하세요. 내부 도구, AI 코파일럿, 에이전틱 워크플로 등 앱 유형별 아키텍처 패턴에 대해서는 Data + AI Summit 2026의 더 나은 앱 구축 및 수천 명의 사용자를 위한 상태 유지 앱: 수평 확장, 세션 어피니티 등 세션을 시청하세요.

자주 묻는 질문 (FAQ)

Databricks App은 어떻게 확장하나요?

설계, 빌드, 테스트 및 배포, 운영의 4단계로 확장하세요. 먼저 지연 시간 및 피크 부하 목표를 설정하고, 앱 컴퓨팅은 UI 서빙용으로 유지하며, 복구 가능한 상태로 비동기 코드를 작성하세요. 그 후 부하 테스트와 텔레메트리를 통해 더 큰 인스턴스로 수직 확장할지, 더 많은 인스턴스로 수평 확장할지 결정하세요.

Databricks App을 수직 확장(Scale up)해야 하나요, 아니면 수평 확장(Scale out)해야 하나요?

앱이 어떤 한계에 먼저 도달하느냐에 따라 다릅니다. 요청이 급증하거나 단일 프로세스 앱이 하나의 코어에 제한된 경우 인스턴스를 추가하여 수평 확장(Scale out)하세요. 앱에 더 많은 메모리가 필요하거나 추가 코어를 사용할 수 있는 여러 워커를 실행하는 경우 Large 또는 XLarge로 수직 확장(Scale up)하세요.

Databricks Apps에서 제공하는 인스턴스 크기는 무엇인가요?

Databricks Apps는 Medium(기본값, 최대 2 vCPU 및 6 GB), Large(최대 4 vCPU 및 12 GB), XLarge(최대 12 vCPU 및 48 GB)를 제공합니다. Medium으로 시작하고 부하 테스트를 통해 앱에 필요한 크기를 확인하세요.

앱이 재시작되거나 확장될 때 사용자 세션이 계속 작동하도록 하려면 어떻게 해야 하나요?

세션 상태를 다시 빌드할 수 있는 소프트 상태와 Lakebase 또는 Unity Catalog 테이블에 영구적으로 저장되는 하드 상태로 분리하세요. Databricks Apps는 최선을 다해 각 사용자를 동일한 인스턴스에 유지하지만, 재시작 및 확장으로 인해 세션이 이동할 수 있으므로 어떤 인스턴스든 하드 상태에서 세션을 다시 빌드할 수 있어야 합니다.

확장된 앱은 몇 개의 Lakebase 연결을 열 수 있나요?

워커당 하나의 풀을 사용할 때 상한선은 인스턴스 수 × 인스턴스당 워커 수 × 최대 풀 크기입니다. 예를 들어, 워커가 8개이고 풀 최대값이 10인 인스턴스 5개는 최대 400개의 연결을 열 수 있습니다. 이 총합을 데이터베이스의 문서화된 한계와 비교하고 배포를 위한 여유 공간을 남겨두세요.

앱 사용자를 몇 명에서 수천 명으로 늘릴 준비가 되셨나요? 설명서에서 Databricks Apps 모범 사례 및 Databricks Apps 수평 확장을 확인하세요.

"Databricks Apps 살펴보기" →

(이 글은 AI의 도움을 받아 번역되었습니다. 원문이 궁금하시다면 여기를 클릭해 주세요)

관련 태그:

모범 사례

최신 게시물을 이메일로 받아보세요

블로그를 구독하고 최신 게시물을 이메일로 받아보세요.