주요 컨텐츠로 이동

Databricks에서 Databricks를 사용하여 데이터베이스 신뢰성 확장

Databricks on Databricks: Scaling Database Reliability

Published: September 12, 2025

데이터 엔지니어링1분 이내 소요

작성자: Xiaotong Jiang

Summary

반응형에서 사전형으로: 우리의 사건 소방에서 개발 루프에서 데이터베이스 효율성에 대한 이른 시기의 신호를 주는 Continuous Integration 기반의 점수 매기기 메커니즘으로의 여정을 따라가세요.

  • 데이터베이스 사용 스코어카드: 소유자에게 쿼리, 스키마, 데이터 및 트래픽의 360도 뷰를 제공하는 통합된 인터페이스를 확인하세요 - 수천 개의 데이터베이스를 걸쳐 베스트 프랙티스를 강제합니다.
  • Databricks에서의 Databricks: 우리가 Databricks 내부에서 Delta 테이블, DLT 파이프라인, 그리고 AI/BI 대시보드를 이용하여, 모든 OLTP 쿼리를 대규모로 측정하고 분석하는 방법을 살펴보세요.

요약: Databricks 엔지니어들은 Databricks 제품과 같은 빅 데이터 분석 도구를 활용하여, 반응적 모니터링에서 데이터베이스 베스트 프랙티스를 추진하는 능동적인 점수화 메커니즘으로 이동했습니다. 이것은 고객에게 영향을 끼치기 전에 문제가 있는 쿼리와 스키마 정의를 식별하고 해결하여 데이터베이스의 사용 효율성을 크게 향상시켰습니다. 예를 들어, 하나의 데이터베이스는 평가 기능 덕분에 최적화된 데이터베이스 효율성으로 4배의 트래픽 증가를 처리하면서도 더 적은 리소스(CPU, 메모리, 디스크)를 소비했습니다.

Databricks에서는 우리의 제품들이 수천 개의 데이터베이스를 여러 클라우드, 지역 및 데이터베이스 엔진에서 지원하며, 사용자 계정 메타데이터, 작업 스케줄링, 데이터 거버넌스 같은 다양한 사용 사례를 지원합니다. 이 데이터베이스들은 안정적인 트랜잭션(예: 사용자 권한에 대한 원자성 업데이트)과 빠른 조회(예: Genie 대화 검색)를 가능하게 합니다. 그러나 이런 규모와 다양성, 고객 워크로드가 효율적으로 관리되는 공유 인프라의 다중 테넌트 아키텍처는 중요한 신뢰성 문제를 일으킵니다. 비효율적인 쿼리나 최적화되지 않은 스키마는 지연 시간 급증을 일으키거나 락 경쟁을 일으켜 많은 사용자에게 영향을 미칩니다.

이 블로그 게시글에서는 Databricks에서의 엔지니어링 팀이 데이터 기반 마인드셋을 어떻게 받아들여 데이터베이스의 신뢰성을 달성하기 위해 접근 방법을 변화시키는 방법에 대해 심도있게 탐구하고 있습니다. 우리는 이전에 사용했던 전통적인 반응형 모니터링 방법과 그 한계점부터 설명하겠습니다. 다음으로는, 질의 로그가 Delta Tables로 수집되어 사건 동안 데이터베이스 사용에 대한 인사이트를 얻기 위해 유연한 집계를 할 수 있게 하는 클라이언트 측 쿼리 추적을 도입하는 방법에 대해 논의하겠습니다. 그곳에서 우리는 문제를 사전에 잡아내기 위해 우리의 지속적인 통합(CI) 파이프라인에 내장된 쿼리 점수자에 대해 더 자세히 살펴볼 것입니다. CI에 의해 식별된 쿼리 패턴은 JSON으로 출고되어 노트북에서 처리되며, 스파크 작업은 모든 것을 조인하여 대규모로 측정치를 계산합니다(당장 이 측정치는 수천 개의 데이터베이스와 수만 개의 쿼리를 포괄합니다). 마지막으로, 우리는 이 모든 부분이 어떻게 우리의 AI/BI 대시보드에서의 통일된 데이터베이스 사용 점수표로 모인지 설명하겠습니다. 이 점수표는 팀을 가장 좋은 방법으로 이끕니다. 주제는 반응적인 소방에서 사전 조치로 이동하는 것입니다. 우리의 여정은 우리 자신의 플랫폼의 신뢰성을 향상시키는 것뿐만 아니라 다른 팀이 분석 도구를 사용하여 자신의 시스템을 모니터링하고 최적화하기 위한 유사한 "점수표" 파이프라인을 구현하는 방법을 보여줍니다. 우리는 인프라와의 원활한 통합을 위해 Databricks를 선택했지만, 이 전략은 어떤 견고한 분석 플랫폼에도 적응 가능합니다.

원래의 반응적 접근법 - 서버 측 지표

초기에는 우리의 데이터베이스 이슈에 대한 접근법은 대부분 반응적이었습니다. 데이터베이스 사고가 발생하면 주로 사용하던 도구는 MySQL Performance Schema를 기반으로 한 Percona Monitoring and Management와 mysqld-exporter였습니다. 이들은 데이터베이스 서버 내부의 인사이트를 제공하였습니다: 가장 오래 실행되는 쿼리, 다양한 작업으로 스캔된 행 수, 보유한 lock, 그리고 CPU 사용량 등을 볼 수 있었습니다.

이 서버 중심의 모니터링은 매우 중요했지만, 중요한 한계가 있었습니다. 클라이언트 상황은 부족했습니다: 데이터베이스는 어떤 쿼리가 문제가 되는지 알려주지만, 누가 또는 무엇이 그것을 트리거했는지에 대해 많은 것을 알려주지 않았습니다. 부하 증가는 높은 CPU 사용률과 특정 SQL 문의 실행 횟수 증가로 나타날 수 있습니다. 하지만 추가적인 정보 없이, 우리는 단지 증상만 알고 있었습니다(예: "쿼리 Q가 20% 로드 증가"), 근본 원인은 알 수 없었습니다("어느 테넌트나 기능이 갑자기 쿼리 Q를 더 자주 발행하고 있나요?"). 조사는 종종 시간을 기록하고 공격적인 쿼리의 원본을 찾기 위해 여러 서비스로부터 로그를 교차 검증하는 추측 작업을 포함했습니다. 이것은 활동 중인 사건 동안 시간 소비가 될 수 있습니다.

개선된 반응적 접근법 - 클라이언트 쿼리 추적

서버 측 모니터링의 맹점을 해결하기 위해, 우리는 클라이언트 측 쿼리 추적을 도입했습니다. 이 아이디어는 간단하지만 강력합니다: 언제든지 우리 플랫폼의 애플리케이션(데이터베이스 클라이언트)이 SQL 쿼리를 데이터베이스로 전송할 때, 우리는 테넌트 ID, 서비스 또는 API 이름, 요청 ID와 같은 추가적인 상황을 태그하고 로그합니다. 이러한 사용자 정의 차원을 각 쿼리와 함께 전파함으로써, 우리는 데이터베이스의 시각과 애플리케이션의 시각을 연결하는 전체적인 시각을 얻습니다.

이것이 실제로 어떻게 도움이 되는지? "쿼리 Z"가 갑자기 느려지거나 많은 자원을 소비하는 것으로 데이터베이스 지표를 통해 관찰한다고 상상해 보십시오. 클라이언트 추적을 사용하면, 우리는 즉시 물어볼 수 있습니다: 어떤 클라이언트나 테넌트가 쿼리 Z를 담당하는가? 우리 애플리케이션들이 구분자를 첨부하기 때문에, 우리는 예를 들어 테넌트 A의 작업 공간이 X 로드에서 쿼리 Z를 발행하고 있음을 알게 될 수도 있습니다. 이것은 모호한 관찰("데이터베이스가 높은 부하 상태로 있다")을 실제로 조치를 취할 수 있는 통찰력("테넌트 A가 특정 API를 통해 부하를 발생시킨다")으로 바꾸게 됩니다. 이러한 지식을 가지면, 대기 중인 엔지니어들은 빠르게 트라이아지를 할 수 있습니다 — 아마도 그 테넌트의 요청을 제한하는 방식으로.

클라이언트 쿼리 추적이 전역 데이터베이스 지표에 완전히 의존하고 근본 원인에 대해 추측해야 했던 과거의 여러 어려운 싸움에서 우리를 구해냈습니다. 이제, 서버 측 및 클라이언트 측 데이터의 결합은 분 단위로 중요한 질문에 답을 제공합니다: 어떤 테넌트 또는 기능이 쿼리 QPS를 급증시켰나요? 가장 많은 데이터베이스 시간을 사용하는 사람은 누구인가요? 특정 API 호출이 부담이나 오류의 불균형한 양을 책임지고 있는가요? 이러한 사용자 정의 차원에서 메트릭을 집계함으로써, 한 고객만이 자원을 독점하거나 새로운 기능이 본질적으로 비용이 많이 드는 쿼리를 내놓는 패턴과 같은 패턴을 감지할 수 있었습니다.

이 추가적인 맥락은 사고 발생 시 뿐만 아니라 사용자 대시보드 및 용량 계획에도 반영됩니다. 우리는 어떤 테넌트 또는 작업 부하가 데이터베이스에서 가장 높은지 추적하고 필요에 따라 리소스나 격리를 선제적으로 할당할 수 있습니다(예를 들어, 특히 많은 사용자를 그들만의 데이터베이스 인스턴스로 이전). 요약하자면, 어플리케이션 수준의 계측은 전통적인 데이터베이스 지표를 보완하는 새로운 관찰 가능성 차원을 우리에게 제공하였습니다.

하지만, 진단 속도가 빨라진다고 해도, 우리는 종종 그들이 발생한 후에 문제에대해 반응하곤 했습니다. 우리 여행에서 다음 로직 단계는 이러한 문제가 원래의 생산에서 발생하지 않도록 막는 것이었습니다.

적극적인 접근: CI에서의 쿼리/스키마 스코어러

정적 분석 도구가 코드가 병합되기 전에 코드 버그나 스타일 위반을 잡아낼 수 있듯이, 우리는 또한 SQL 쿼리 및 스키마 패턴을 미리 분석할 수 있다는 것을 깨달았습니다. 이로 인해, 우리의 사전 병합 CI 파이프라인에 Query Scorer가 통합되었습니다.

SQL 쿼리의 Develop Lifecycle; Scorer는 개발 주기 초기에 anti-patterns를 플래그합니다, 그들이 가장 쉽게 수정할 수 있는 곳에서.

개발자가 SQL 쿼리나 스키마에 대한 업데이트를 포함한 풀 요청을 열 때마다 쿼리 및 스키마 점수자가 작동합니다. 그것은 제안된 변경사항을 최선의 전략 규칙 및 알려진 안티 패턴에 대해 평가합니다. anti-patterns가 플래그되면, CI 시스템은 테스트를 실패시키고 수정을 위한 실행 가능한 제안을 제공할 수 있습니다.

우리는 어떤 종류의 쿼리와 스키마 안티 패턴을 찾아보는가? 지난 시간 동안, 우리는 과거 사건들과 일반적인 SQL 지식을 바탕으로 안티 패턴들의 라이브러리를 구축해왔습니다. 몇 가지 주요 예시는 다음과 같습니다:

  • 예측할 수 없는 실행 계획들: 데이터 분포나 최적화 꾀에 따라 다른 인덱스나 계획을 사용할 수 있는 쿼리들. 이것들은 시간의 폭탄입니다-그들은 테스트에서 잘 작동할 수 있지만, 특정 조건에서는 병리적으로 작동할 수 있습니다.
  • 비효율적인 쿼리들: 필요한 것보다 훨씬 많은 데이터를 탐색하는 쿼리들, 예를 들어 큰 테이블에서 전체 테이블 스캔, 누락된 인덱스 또는 비선택적 인덱스. 또는 과도하게 복잡한 쿼리와 깊게 nested 된 하위 쿼리는 최적화 프로그램에 부담을 줄 수 있습니다.
  • 제한이 없는 DML: DELETE 또는 UPDATE 작업에 WHERE 절이 없거나 전체 테이블을 잠글 수 있는 작업.
  • 나쁜 스키마 설계: 기본 키가 없는 테이블, 과도한/중복 인덱스가 있는 테이블, 또는 과도한 BLOB/TEXT 열을 사용하는 테이블, 이것이 중복 데이터, 느린 쓰기, 성능 저하를 초래할 수 있습니다.

예시 "Time Bomb" Sql 쿼리

SQL Query테이블 정의
t에서 삭제 
t.B = ? AND t.C = ?;
t 테이블 생성 (
   A INT 기본 키,
   B INT,
   C INT,
   KEY idx_b (B),
   KEY idx_c (C)
);

우리는 이 쿼리 안티 패턴을 "여러 인덱스 후보" 패턴이라고 부릅니다. 이런 문제는 쿼리의 WHERE 절이 두 개 이상의 인덱스(idx_bidx_c)에 의해 만족시킬 수 있을 때 발생하므로, 쿼리 최적화기에 여러 유효한 실행 경로를 제공합니다. 예를 들어, 위의 idx_bidx_c 모두 WHERE 절을 만족시키는 데 사용될 수 있습니다. MySQL은 어떤 인덱스를 사용하게 될까요? 이것은 데이터 분포의 변화나 인덱스 통계가 오래되어짐에 따라 변할 수 있는 쿼리 최적화의 추정에 따라 어느 경로가 더 저렴한지에 달려 있습니다.

위험한 점은 한 인덱스 경로가 다른 것보다 훨씬 비용이 많이 들 수 있지만, 최적화기가 잘못 추정하고 잘못된 것을 선택할 수 있다는 것입니다.

실제로 우리는 최적화기가 부적절한 인덱스를 선택한 사건을 겪었는데, 이로 인해 1억 행 이상의 전체 테이블이 삭제 도중에 잠겼습니다.

우리의 쿼리 점수자은 계획이 안정적이지 않은 쿼리를 차단할 것입니다. 쿼리가 여러 인덱스를 사용할 수 있고 명확하고, 일관된 계획이 없다면, 그것은 위험하다고 표시됩니다. 이런 경우 우리는 개발자들에게 FORCE INDEX 절을 사용하여 알려진 안전한 인덱스를 명시적으로 강제하거나, 더 결정적인 동작을 위해 쿼리를 재구성하도록 요청합니다.

이러한 규칙을 개발 주기 초기에 적용함으로써, 우리는 새로운 데이터베이스 함정의 도입을 크게 줄였습니다. 엔지니어들은 풀 요청에서 즉시 피드백을 받게 됩니다, 만약 그들이 데이터베이스 건강에 해를 끼칠 수 있는 쿼리를 도입한다면 — 그리고 시간이 지남에 따라, 그들은 이러한 최고의 연습을 배우고 내면화합니다.

통합된 데이터베이스 사용 점수표: 전체적인 시각

정적 안티 패턴을 잡는 것은 강력하다, 그러나 데이터베이스 신뢰성은 전체적인 속성이다. 단지 개별 쿼리만이 중요한 것은 아닙니다 — 트래픽 패턴, 데이터 볼륨, 스키마 진화에도 영향을 받습니다. 이를 해결하기 위해, 우리는 더 넓은 범위의 모범 사례를 정량화하는 통합된 데이터베이스 사용 점수표를 개발했습니다.

우리의 데이터베이스 효율성 항아리 채우기 철학 - 바위는 크고 중요한 작업, 모래는 작고 덜 중요한 작업, 조약돌은 그 중간의 작업입니다.

점수는 어떻게 계산하나요? 우리는 쿼리 생명주기의 모든 단계에서 데이터를 통합합니다:

  • CI 단계 (Pre-Merge): 우리는 모든 쿼리/스키마와 그들의 Anti Patterns를 델타 테이블로 가져옵니다.
  • 생산 단계: 클라이언트 측 쿼리 추적 및 서버 측 측정 항목을 사용하여, Delta Live Tables (DLT) 파이프라인은 실시간 성능 데이터를 수집합니다—예를 들면 쿼리 대기 시간, 스캔된 행 대비 반환된 행, 그리고 성공/실패 비율 등입니다.

모든 이 정보는 중앙 logfood의 AI/BI 대시보드에 통합되어 있습니다.

하나의 서비스에 대한 예 DB 사용 점수표. 기여 요인은 과도한 행 심사, SLA, 시간 초과, 단위 테스트 커버리지, Anti Patterns, 읽기/쓰기 증폭을 포함합니다.

주요 핵심 사항

Databricks에서 OLTP SQL 데이터베이스 신뢰성을 높이는 여정은 고성능 제품을 확장하는데 있어서 유용한 교훈을 제공합니다:

  • 반응적에서 예방적으로 전환: 사고 중심의 반응적 대응에서 벗어나, 데이터베이스 사용 점수표를 이용해 데이터베이스 모범 사례를 측정하고 실행 가능하게 함으로써, 우리는 데이터베이스 모범 이행을 적극적으로 향상시키는 방향으로 전환하고 있습니다.
  • Devloop에서 더 일찍 베스트 프랙티스를 강제하십시오: 쿼리 스코어러를 초기 개발 순환에 통합함으로써, 우리는 풀 테이블 스캔이나 불안정한 계획과 같은 안티 패턴을 고치는 비용과 노력을 줄였습니다, 개발자들이 코딩하는 동안 효율적으로 문제를 해결할 수 있게 했습니다.
  • 분석을 활용해 인사이트 얻기: Delta 테이블, DLT 파이프라인, AI/BI 대시보드와 같은 Databricks 제품을 활용함으로써, 데이터베이스 사용 점수표는 팀이 수천 개의 데이터베이스 인스턴스를 최적화하고 개발자를 효과적으로 지원하도록 돕습니다. Databricks 제품은 우리의 과정을 가속화하며, 이 솔루션은 다른 데이터 기반 플랫폼에도 적응 가능합니다.

이 글은 우리가 SREcon25 Americas 2025에서 발표한 발표에서 수정되었습니다 (슬라이드와 녹화는 여기에서 확인하실 수 있습니다). 우리는 커뮤니티에 우리의 경험을 공유하는 것을 영광으로 생각하며, 여기에서 그 인사이트를 더 넓은 대중에게 전달하는 것을 기대하고 있습니다.

데이터베이스 신뢰성 문제를 해결하는 데에 열정이 있으시다면, Databricks(https://www.databricks.com/company/careers/open-positions)에서의 경력 기회를 탐색해 보세요.

 

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

게시물을 놓치지 마세요

관심 있는 카테고리를 구독하고 최신 게시물을 받은편지함으로 받아보세요