주요 컨텐츠로 이동
공학

모놀리스에서 레이크베이스, LTAP까지: 스토리지부터 다시 생각하는 데이터베이스

작성자: Reynold Xin

  • 거의 모든 기존 데이터베이스는 쓰기 전용 로그(write-ahead log)와 데이터 파일을 단일 머신의 디스크에 저장합니다. 이는 데이터 손실 위험, 비용이 많이 드는 읽기 복제본(read replicas) 및 고가용성(HA) 클론, 그리고 트랜잭션 성능을 저하시키는 분석 쿼리의 근본적인 원인이 됩니다.
  • Lakebase는 로그와 데이터 파일을 독립적인 클라우드 서비스(SafeKeeper 및 PageServer)로 외재화하여 Postgres 컴퓨팅을 상태 비저장(stateless) 방식으로 만듭니다. 이를 통해 유의미한 대기 시간(latency) 증가 없이 무제한 스토리지, 탄력적 컴퓨팅, 내구성 있는 쓰기, 더 간단한 고가용성(HA), 즉각적인 브랜칭(branching)을 지원합니다.
  • LTAP는 여기서 더 나아가 Postgres와 Lakehouse 엔진이 모두 읽을 수 있는 개방형 열 지향(columnar) 형식으로 운영 데이터를 한 번만 저장합니다. 따라서 CDC 파이프라인이나 두 번째 복사본 없이, 그리고 트랜잭션 워크로드의 속도 저하 없이 트랜잭션이 방금 기록한 것과 동일한 최신 데이터에서 분석을 실행할 수 있습니다. 두 워크로드를 하나의 엔진으로 통합하려는 HTAP와 달리, LTAP는 스토리지 레이어에서 통합하고 각 작업에 가장 적합한 엔진을 유지합니다.

16년 전 제가 UC 버클리에서 PhD 과정을 시작했을 때, 지도 교수님은 제게 이렇게 말씀하셨습니다. "OLTP 데이터베이스는 이미 해결된 문제입니다. 잘 작동하니 분석에 집중하세요." 당시는 정형 및 비정형 데이터를 훨씬 더 많이 수집하고 머신러닝(지금은 'AI'라고 부르는 것)을 적용할 수 있는 초기 단계였습니다. 그래서 저는 그 조언을 받아들여 공동 창업자들과 함께 Apache Spark가 된 연구 프로젝트에 참여했고, 이후 Databricks를 창업했습니다.

Databricks를 구축하면서 시중의 다양한 데이터베이스를 사용하기 시작했고, OLTP 데이터베이스가 해결된 문제와는 거리가 멀다는 사실을 깨달았습니다. 데이터베이스들은 투박하고, 확장하기 어려우며, 믿을 수 없을 정도로 취약했습니다. 어느 순간 너무 답답한 나머지, '오늘날 OLTP 데이터베이스를 처음부터 다시 설계한다면 어떤 모습일까?'라는 의문이 들었습니다. 그 질문이 바로 저희의 서버리스 Postgres 데이터베이스인 Lakebase로 이어졌습니다.

이 글에서는 Lakebase OLTP 아키텍처를 깊이 있게 살펴봅니다. 먼저 기존 모놀리식 데이터베이스의 스토리지 레이어에서 어떤 문제가 발생하는지 알아보고, Lakebase가 이러한 구성 요소를 독립적이고 외부화된 서비스로 어떻게 재구성하는지 살펴보겠습니다. 마지막으로, 동일한 아키텍처를 통해 CDC나 '미러링'의 지연 및 추가 비용 없이 단일 데이터 사본에서 실시간으로 트랜잭션과 분석을 모두 실행할 수 있는 LTAP에 대해 알아보겠습니다.

모놀리스로서의 데이터베이스

오늘날 전 세계에서 실행되는 데이터베이스의 대부분은 모놀리스입니다. 여기에는 MySQL, Postgres, 기존 Oracle 등이 포함됩니다. Lakebase는 Postgres(우연히도 이 역시 버클리에서 탄생했습니다)를 기반으로 구축되었으므로 여기서는 Postgres를 주요 예시로 사용하겠지만, 대부분의 데이터베이스도 비슷하게 작동합니다. 즉, 데이터베이스 엔진과 스토리지를 실행하는 머신 하나를 프로비저닝하는 방식입니다. 이러한 데이터베이스 시스템에서 디스크 상에 가장 중요한 두 가지는 write ahead log (WAL)데이터 파일입니다.

트랜잭션을 커밋할 때 데이터베이스가 즉시 데이터 파일을 다시 쓰지는 않습니다. 수정하려는 행들이 파일 전체에 흩어져 있어 무작위 I/O가 필요하므로 속도가 느려지기 때문입니다. 대신 데이터베이스는 먼저 디스크의 순차 로그(sequential log)인 WAL에 변경 사항에 대한 설명을 추가합니다. 해당 로그 항목이 영구적으로 기록되는 순간 트랜잭션이 커밋된 것으로 간주됩니다. 그 이후에야 비동기적으로 데이터베이스가 실제 데이터 파일을 업데이트하여 변경 사항을 반영합니다.

이를 쉽게 생각하는 방법은 다음과 같습니다. WAL은 쓰기를 빠르게(그리고 안전하게) 만들기 위해 존재하고, 데이터 파일은 읽기를 빠르게 만들기 위해 존재합니다. 로그를 사용하면 분산된 무작위 I/O 대신 단일 순차 추가(sequential append)로 트랜잭션을 커밋할 수 있습니다. 데이터 파일은 데이터베이스의 전체 기록을 처음부터 다시 실행할 필요 없이 현재 상태를 직접 읽어 쿼리에 응답할 수 있도록 해줍니다. (이 설계의 복잡한 세부 사항을 모두 이해하고 싶다면 69페이지 분량의 ARIES 논문을 읽어보세요. 컴퓨터 과학에서 가장 복잡한 논문 중 하나이므로 주의하시기 바랍니다.)

이 설계가 사실상 시중의 모든 데이터베이스의 기반이 되었지만, 모놀리식 아키텍처는 많은 과제도 안겨줍니다.

잘못된 구성으로 인한 데이터 손실. 커밋의 내구성은 그 뒤에 실행되는 디스크 플러시(disk flush)의 내구성에 좌우됩니다. 데이터베이스, 운영체제 또는 스토리지 레이어가 WAL에 대한 쓰기가 실제 내구성이 있는 미디어에 플러시되기 전에 클라이언트에 승인되도록 구성된 경우, 전원 공급 중단이나 커널 패닉 발생 시 커밋이 사라질 수 있습니다. 이러한 설정은 미묘하고 잘못 설정하기 쉬우며, 오류가 발생해도 알아차리기 어려운 경우가 많습니다. 심지어 운영체제가 플러시 완료에 대해 거짓말을 할 수도 있습니다!

노드 손실로 인한 데이터 손실. 플러시가 올바르게 구성되어 있더라도 WAL과 데이터 파일은 단일 머신에 존재합니다. 해당 머신의 디스크가 고장 나면 그 안의 데이터도 함께 사라집니다. 네트워크 연결 스토리지나 RAID-1/RAID-10과 같은 중복성 기술이 내구성을 향상시킬 수는 있지만, 이 문제를 근본적으로 해결하지는 못한다는 점에 유의하세요. 스토리지 마운트가 고장 나면 데이터 액세스도 불가능해집니다.

읽기 확장을 위해서는 물리적 복제가 필요합니다. 단일 장비가 더 이상 트래픽을 감당할 수 없을 때 일반적인 해결책은 읽기 복제본(read replica)을 추가하는 것입니다. 하지만 읽기 복제본은 전체 데이터베이스의 완전한 물리적 사본으로, 기본(primary) 데이터베이스에서 WAL을 스트리밍하여 다시 실행합니다. 이를 프로비저닝하려면 전체 데이터 세트를 복사한 다음 로그를 따라잡아야 합니다. 대규모 데이터베이스의 경우 이는 빠른 작업이 아니며 데이터베이스가 다운될 수도 있습니다.

고가용성(HA) 역시 물리적 복제가 필요합니다. 기본 노드의 손실에 대비하려면 최소한 하나의 대기(standby) 노드를 추가로 실행해야 하며, 이 노드 자체도 WAL을 통해 동기화 상태를 유지하는 데이터베이스의 완전한 물리적 사본입니다. 최소 두 배의 인프라 비용을 지불해야 하고, 대기 노드를 온라인 상태로 만드는 데 오랜 시간이 걸리며, 기본 노드가 다운되었을 때 데이터 손실을 방지하기 위해 동기식 복제를 설정해야 합니다. (실제로는 많은 이들이 3개 이상의 노드를 권장합니다.)

분석 작업이 트랜잭션 트래픽과 경합합니다. 무거운 분석 쿼리는 대기 시간에 민감한 트랜잭션 워크로드와 동일한 하드웨어 리소스를 두고 경쟁합니다. 대규모 보고서 쿼리 하나나 GDPR 정리 작업 하나가 주요 OLTP 쿼리의 성능을 저하시킬 수 있습니다. 별도의 복제본에서 분석 쿼리를 실행할 수도 있지만, 결국 복제본 비용을 지불해야 하고 OLTP 스토리지의 행 지향적 특성 때문에 여전히 최적의 성능을 얻지 못합니다(고성능을 위해서는 분석에 열 지향적 스토리지가 필요합니다).

이러한 문제의 거의 대부분은 모놀리식 아키텍처의 동일한 근본 원인으로 거슬러 올라갑니다. 바로 WAL과 데이터 파일이 단일 머신 내에 저장된다는 점입니다. 내구성은 해당 머신의 디스크에 종속됩니다. 확장성과 가용성을 확보하려면 해당 머신을 물리적으로 복제해야 합니다. 머신을 공유하기 때문에 워크로드 간에 간섭이 발생합니다.

Lakebase 아키텍처

오늘날 OLTP 데이터베이스를 다시 설계한다면, 저렴하고 내구성이 뛰어난 클라우드 오브젝트 스토리지와 탄력적인 컴퓨팅이라는 현대적인 클라우드 구성 요소부터 시작할 것입니다. 이것이 바로 Neon 팀이 택한 경로이자 Lakebase의 기반이 된 토대입니다.

핵심적인 조치는 Postgres 컴퓨팅 인스턴스를 상태 비저장(stateless)으로 만드는 것입니다. 로컬 디스크의 WAL과 데이터 파일을 목적에 맞게 구축되고 독립적으로 확장 가능한 서비스로 외부화함으로써 이를 달성합니다. 컴퓨팅 레이어는 더 이상 데이터를 소유하지 않기 때문에 자유롭게 시작, 중지 및 복제할 수 있는 상태 비저장 Postgres 엔진이 됩니다.

이 두 스토리지 서비스가 어떻게 함께 작동하여 성능 저하 없이 앞서 언급한 과제들을 해결할 수 있는지 살펴보겠습니다.

쓰기 확장: WAL이 SafeKeeper가 되다

모놀리스에서는 로컬 디스크에 플러시하여 쓰기의 내구성을 보장합니다. Lakebase에서는 WAL이 SafeKeeper라는 분산 스토리지 서비스로 외부화됩니다. 내구성을 디스크 플러시에 의존하는 대신, Paxos 기반 네트워크 복제를 사용하여 SafeKeeper 노드의 정족수(quorum) 전체에 로그 레코드를 복제함으로써 커밋의 내구성을 보장합니다. 이제 디스크 고장으로 데이터를 잃을 염려가 없으며, 잘못 구성된 플러시로 인해 내구성 보장이 조용히 약화되는 일도 없습니다.

이 시점에서 다음과 같은 의문이 드는 것은 자연스럽습니다. 커밋을 로컬 디스크의 WAL에서 SafeKeeper의 WAL로 이동하면 추가적인 네트워크 홉으로 인해 쓰기 대기 시간이 늘어나지 않을까요? 답은 '아니요'입니다. 내구성과 가용성을 중요하게 생각하는 진지한 Postgres 배포의 경우, 추가 네트워크 홉이 필요한 동기식 복제를 설정해야 하므로 WAL을 SafeKeeper로 외부화해도 추가적인 오버헤드가 발생하지 않습니다. 사실 Postgres의 내부 작동 방식 덕분에 SafeKeeper와 PageServer를 결합하면 쓰기 처리량은 5배 향상되고 읽기 대기 시간은 2배 단축될 수 있습니다.

읽기 확장: 데이터 파일이 PageServer가 되다

데이터 파일은 PageServer라는 또 다른 분산 스토리지 서비스로 이동합니다. WAL은 SafeKeeper에서 PageServer로 스트리밍되며, PageServer는 이러한 변경 사항을 자체 데이터 버전에 비동기적으로 적용하여 페이지를 저비용 클라우드 오브젝트 스토리지(레이크)에 구체화(materialize)합니다. PageServer는 기본 오브젝트 스토리지를 위한 라이트스루(write-through) 캐시로 생각할 수 있습니다.

이는 단일 구조(monolith)의 'WAL 후 데이터 파일' 관계와 유사하지만, 이제 두 부분이 동일한 디스크에 있는 대신 네트워크로 연결되어 독립적으로 확장 가능한 별도의 서비스에 존재한다는 점이 다릅니다. PageServer에 페이지가 요청되었을 때 PageServer에 아직 최신 버전이 없는 경우(변경 사항은 PageServer로 전달되기 전에 SafeKeeper에 먼저 기록된다는 점에 유의하세요), PageServer는 SafeKeeper의 로그를 적용하여 최신 상태를 재구성합니다.

비슷한 질문으로, 데이터 파일을 로컬 디스크에서 PageServer로 이동하면 추가적인 네트워크 홉으로 인해 읽기 대기 시간(latency)이 늘어날까요? 실질적인 모든 목적에서 대답은 '아니오'입니다. 이 시스템은 공격적인 다층 캐싱을 통해 대기 시간 영향을 격리하고 최소화하도록 설계되었습니다. 페이지를 가져오기 위해 Postgres는 먼저 노드의 로컬 메모리에 있는 버퍼 풀을 조회합니다. 페이지가 없으면 로컬 디스크 캐시를 조회합니다. 캐시 미스가 발생한 경우에만 PageServer로 이동하면 됩니다. 컴퓨트 노드는 단일 구조 설정과 동일한 로컬 메모 및 디스크 용량으로 구성할 수 있으므로 로컬 캐시 히트율은 그대로 유지됩니다. 대부분의 작업에서 읽기 대기 시간은 단일 구조와 구별할 수 없을 정도로 동일하지만, 분리된 가상의 무한한 스토리지를 사용할 수 있는 이점을 얻게 됩니다.

이를 통해 가능해지는 것들

WAL이 SafeKeeper에 있고 데이터 파일이 PageServer에 있게 되면, 단일 구조에서는 어렵거나 불가능했던 수많은 기능들이 아키텍처의 자연스러운 결과로 가능해집니다. 다음 기능들은 이미 Databricks와 Neon 모두에서 Lakebase 제품의 일부로 널리 제공되고 있습니다.

여전히 Postgres입니다. 이것은 실제 Postgres이므로 와이어 프로토콜, SQL, 드라이버 및 확장 기능이 모두 그대로 작동합니다.

무제한 스토리지. 데이터는 프로비저닝된 로컬 디스크가 아닌 클라우드 오브젝트 스토리지에 저장됩니다. 더 이상 용량 한계에 맞춰 장비 크기를 조정할 필요가 없습니다. 스토리지는 실질적으로 무한합니다.

서버리스, 탄력적 컴퓨트. 컴퓨트가 상태 비저장(stateless) 방식이기 때문에 부하가 걸리면 즉시 확장(scale up)할 수 있고, 유휴 상태일 때는 0까지 축소(scale down)할 수 있습니다. 트래픽을 기다리며 대기하는 대형 장비에 비용을 지불하지 않아도 됩니다.

내구성 있는 쓰기 및 데이터 무손실. 커밋은 단일 로컬 디스크가 플러시되었다고 보고할 때가 아니라, Paxos를 통해 SafeKeeper 노드 전체에 복제될 때 내구성을 갖게 됩니다. 개별 노드가 손실되어도 커밋된 데이터는 손실되지 않습니다.

더 간단한 고가용성. 단일 구조에서 HA는 두 번째 전체 물리적 복제본을 유지하고, 비용을 두 배로 지불하며, 전환(cutover) 시 데이터 손실 위험을 감수해야 함을 의미했습니다. 여기서는 내구성 있는 상태가 이미 개별 컴퓨트 인스턴스와 독립적인 복제된 스토리지 레이어에 존재합니다. 장애 조치(failover)를 수행할 때 더 이상 데이터베이스의 별도 물리적 복사본을 승격시키고 로그의 마지막 세그먼트가 제대로 전달되었기를 바랄 필요가 없습니다.

즉각적인 브랜칭, 복제 및 복구. 제가 가장 좋아하는 기능입니다. 코드의 경우 브랜치를 생성하는 것은 전체 코드베이스를 1초 미만으로 완전히 격리하여 복사하는 것이며, 우리는 하루에도 수십 번씩 아무 생각 없이 이 작업을 수행합니다. 단일 구조 데이터베이스에서 복제는 전체 데이터 세트를 물리적으로 복사하는 것을 의미하며, 이는 느리고 비용이 많이 들며 운영 시스템에 위험을 초래합니다. 데이터가 외부화된 버전 관리 스토리지 레이어에 있는 경우, 브랜치나 복제는 물리적 복사가 아닌 메타데이터 작업입니다. 대규모 운영 데이터베이스를 몇 초 만에 브랜칭하고, 해당 브랜치에서 테스트나 위험한 마이그레이션을 실행한 다음 버릴 수 있습니다. 특정 시점으로의 복구도 동일한 방식으로 작동합니다. 마침내 데이터베이스가 코드만큼 빠르게 움직이게 됩니다.

컴퓨트와 스토리지를 분리하는 것 자체는 새로운 것이 아닙니다. 이전 포스트에서 이를 수행한 2세대 클라우드 데이터베이스에 대해 논의했습니다. 하지만 Lakebase의 핵심은 운영 데이터를 범용 오브젝트 스토리지에 개방형 형식으로 저장한다는 점입니다. 이를 통해 다른 엔진이 데이터를 직접 읽을 수 있는 기회가 열리며, 이는 LTAP로 이어집니다.

LTAP: 트랜잭션과 분석을 위한 단 하나의 복사본

지금까지는 단일 운영 데이터베이스를 더 내구성 있고, 더 탄력적이며, 운영 비용이 저렴하고, 더 빠르게 브랜칭할 수 있도록 개선하는 것에 대한 내용이었습니다. 하지만 데이터가 외부화된 스토리지 레이어에 존재하게 되면 훨씬 더 흥미로운 일이 가능해집니다. 트랜잭션 데이터베이스와 분석 시스템을 두 개의 서로 다른 세계로 취급하는 것을 멈출 수 있습니다.

잠시 PageServer로 돌아가 보겠습니다. PageServer는 이미 WAL의 변경 스트림을 가져와 페이지를 오브젝트 스토리지에 비동기적으로 구체화(materialize)합니다. 데이터가 레이크에 도달하는 순간인 그 구체화 단계가 훨씬 더 오래된 문제를 해결하기에 정확히 적절한 위치인 것으로 밝혀졌습니다...

Lakebase를 사용하더라도 오브젝트 스토리지의 데이터는 여전히 Postgres의 기본 페이지 형식으로 행 단위로 배치되어 기록되었습니다. 이 형식은 트랜잭션에는 적합하지만 분석에는 적합하지 않으므로, 이를 읽으려는 분석 엔진은 읽을 때마다 변환 비용을 지불하거나, 더 흔하게는 파이프라인에 의해 동기화 상태가 유지되는 별도의 데이터 복사본에 의존해야 했습니다. 파이프라인은 취약할 수 있으며, 두 개의 데이터 복사본은 권한이 분산되어 거버넌스의 악몽이 될 수 있습니다.

최근 저희는 두 개의 데이터 복사본 문제를 해결하는 Lake Transactional/Analytical Processing의 약자인 LTAP를 발표했습니다. 핵심 아이디어는 엔진 레이어가 아닌 스토리지 레이어에서 두 세계를 통합하는 것입니다. 트랜잭션과 분석 모두에 뛰어난 하나의 엔진을 만들려고 하지 않습니다. 트랜잭션에는 완전한 ACID 의미 체계(semantics)를 갖춘 Postgres를, 분석에는 Lakehouse 엔진을 사용하여 각 작업에 가장 적합한 도구를 유지합니다. 변화하는 것은 그 아래에 있는 데이터입니다. 두 가지 형식의 두 복사본 대신, 양쪽 모두가 읽을 수 있는 Parquet로 저장된 Delta 및 Iceberg와 같은 개방형 열 지향(columnar) 형식의 내구성 있는 단일 복사본이 존재합니다(더 나은 성능을 위해 다양한 수준의 캐시가 함께 제공됨).

열 지향(columnar) 형식으로 구체화하기

참고: 이 섹션은 다른 섹션보다 Postgres 내부 지식이 더 많이 필요합니다.

PageServer가 페이지를 오브젝트 스토리지에 구체화할 때, Postgres 데이터를 행 형식에서 Parquet의 열 지향 레이아웃으로 변환하여 레이크에 저장합니다. 모든 값의 정확한 Postgres 표현을 비트 단위까지 보존하므로, Postgres 호환 엔진은 정보 손실 없이 이를 재해석할 수 있습니다. 이는 논리적 변경 이벤트 스트림을 외부 스키마로 전송하고 Postgres의 물리적 및 트랜잭션 의미 체계를 남겨두는 CDC 기반 접근 방식과는 다릅니다. 여기서는 이를 유지합니다. 고도로 최적화된 엔진을 통해 PageServer 레이어의 여유 CPU가 데이터를 오브젝트 스토리지에 구체화하는 과정의 일부로 행-열 변환을 수행하므로, 트랜잭션을 처리하는 Postgres 컴퓨트에 부담을 주지 않습니다. 트랜잭션 읽기를 효율적으로 처리하기 위해 PageServer는 여전히 로컬 캐시에 기존의 행 기반 페이지를 구체화하지만, 이는 엄격히 성능 향상을 위한 캐시입니다. 기본이 되는 내구성 있는 저장소는 양쪽 모두에서 액세스할 수 있도록 레이크에 통합된 상태로 유지됩니다.

열 지향 형식에서 Postgres 의미 체계를 보존하는 것은 타입 시스템과 다중 버전 관리(multi-versioning)라는 두 가지로 요약됩니다.

타입 시스템. 대부분의 Postgres 타입은 기본 Parquet 타입에 직접 매핑됩니다. 손실 없는 열 지향 대응 항목이 없는 소수의 값(예: NaN 및 ±Infinity, 소수점 범위를 벗어나는 NUMERICs, 특이하거나 확장된 타입)은 삭제되거나 강제 변환되지 않습니다. 이러한 값들은 동일한 테이블 내의 구조화된 오버플로우 필드에 원래 열과 함께 전달되어 해당 값에 대한 정식 Postgres 텍스트를 유지합니다. 이 필드는 모든 엔진에서 직접 쿼리할 수 있으며, 되돌아오는 과정에서 원래 Postgres 바이트를 정확하게 재구성하기에 충분합니다.

다중 버전 관리. Postgres에서는 트랜잭션이 관찰할 수 있는 모든 행 버전이 유지되므로 스냅샷 격리 및 시점 복구(point-in-time recovery)가 가능합니다. 반면, 개방형 테이블 형식은 중간 행 버전 없이 테이블 전체에 일관된 스냅샷을 노출합니다. 우리는 내구성과 가시성을 분리하여 두 가지 접근 방식의 이점을 모두 얻습니다. 열 지향 형식으로 구체화된 모든 행은 물리적 힙 주소(블록 및 오프셋)를 전달하므로 힙 페이지를 완전히 재구성할 수 있습니다. 기존 Postgres 힙 페이지는 포인트 읽기를 가속화하는 캐시가 되고, 내구성 있는 단일 소스(source of truth)는 오브젝트 스토리지의 열 지향 파일에 존재합니다. Postgres 인덱스는 열로 변환되지 않고 해당 핫 캐시 티어에서 제공되고 재구축됩니다. Postgres의 MVCC 의미 체계와 PITR을 보존하기 위해 중간 행 버전이 유지되지만, Iceberg/Delta 리더에게는 보이지 않으며 결국 가비지 컬렉션됩니다. 최종 결과적으로, 분석 엔진은 깨끗하고 스냅샷 일관성이 있는 테이블을 보게 되며, 그 아래의 Postgres 시스템은 여전히 시간 여행이 가능한 전체 버전 기록을 보게 됩니다.

긍정적인 부작용도 있습니다. 열 기반 데이터는 행 기반 데이터보다 압축률이 훨씬 뛰어나며, 대개 10배 이상 더 압축됩니다. 따라서 열 기반 스토리지로 변환하면 캐싱 레이어와 오브젝트 스토리지 간의 네트워크를 통과하는 데이터 양이 크게 줄어들어 거의 무시할 수 있는 수준이 됩니다. 분석 속도를 높여주는 이 포맷은 스토리지 비용도 절감해 줍니다. 저희는 이러한 장점을 활용하여 LTAP의 과도기적 출시 단계에서 데이터 검증을 위해 오브젝트 스토리지에 행 포맷과 열 포맷을 모두 이중 기록(dual write)하고 있습니다(스토리지 변경에는 극도로 신중해야 하기 때문입니다).

Postgres에 영향을 주지 않고 최신 데이터 읽기

한 가지 큰 과제는 데이터의 최신성(freshness)입니다. 분석 도구가 레이크에 있는 복사본에서 데이터를 읽는다면, 방금 커밋되어 아직 오브젝트 스토리지에 구체화(materialized)되지 않은 데이터를 어떻게 볼 수 있을까요? 이는 "분석 도구가 레이크를 바라보게만 하면 된다"는 식의 대부분의 설계를 무너뜨리는 질문이기에, LTAP가 이 문제를 어떻게 해결하는지 자세히 살펴볼 가치가 있습니다.

분석 쿼리가 시작되면(예: 저희가 방금 발표한 Lakehouse//RT 제품에서 시작되는 경우), 먼저 Postgres에 현재 LSN을 요청합니다. LSN은 읽어야 할 WAL의 정확한 위치를 나타내는 로그 시퀀스 번호입니다. 이는 비용이 적게 드는 메타데이터 조회 작업입니다. 분석 엔진은 이 LSN을 사용하여 해당 시점까지 이미 구체화된 모든 데이터를 포함한 대다수의 데이터를 오브젝트 스토리지에서 직접 읽습니다. 남은 것은 아직 레이크에 구체화되지 않은 아주 최근의 소규모 변경 사항뿐이며, 이는 PageServer에서 가져와 위에 병합합니다.

그 결과, 해당 LSN 시점의 일관되고 완전히 최신 상태인 데이터를 읽을 수 있습니다. 거의 모든 작업은 저렴하고 확장성이 뛰어난 오브젝트 스토리지에서 처리됩니다. 그리고 결정적으로, Postgres 자체는 단 하나의 숫자(LSN)를 반환하는 것 외에는 분석용 읽기 트래픽을 전혀 처리하지 않습니다. 누군가 대규모 분석 쿼리를 실행하더라도 트랜잭션 워크로드가 느려지지 않습니다.

여기서 언급할 만한 실용적인 최적화가 하나 있습니다. 몇 개의 행만 있는 아주 작은 테이블의 경우, 굳이 열 기반 포맷으로 변환하고 관련 Iceberg 메타데이터를 생성하지 않습니다. 메타데이터 관리 비용이 절약되는 비용보다 더 크며, 그렇게 작은 테이블은 어떻게 배치되든 분석 성능에 측정 가능한 영향을 미치지 않기 때문입니다. 이러한 테이블도 여전히 존재하며 단일 복사본의 일부로 쿼리할 수 있습니다.

모든 테이블을 자동으로

이 문제가 매우 중요하기 때문에 시장에서는 OLTP와 분석을 통합하는 것에 대해 많은 이야기가 오가고 있습니다. 전통적인 접근 방식은 CDC로, OLTP 스토리지의 데이터를 별도의 분석 스토리지 계층으로 효과적으로 복제하는 것입니다. "미러링(mirroring)"이나 "zero CDC" 또는 "zero ETL"과 같은 다른 이름으로 들어보셨을 수도 있습니다.

CDC나 "미러링"에서는 데이터 복제 파이프라인에 비용이 발생하기 때문에 모든 테이블에 적용할 수는 없습니다. 관심 있는 테이블을 명시적으로 선택해야 하며, 이러한 복제에는 일반적으로 지연이 발생합니다.

LTAP는 사용자가 별도로 선택(opt-in)할 필요가 없습니다. 존재하는 테이블은 구조상 이미 레이크에 있으며 즉시 쿼리할 수 있습니다. 복제가 없기 때문에 복제되거나 미러링된 테이블 목록도 존재하지 않습니다. 오픈 포맷으로 관리되는 단 하나의 데이터 복사본만 존재하므로, (고객이나 저희가) 구축하고 모니터링하거나 복구해야 할 ETL 파이프라인이 없습니다. 트랜잭션 엔진과 분석 엔진은 각각의 워크로드에 맞게 독립적으로 확장됩니다. 또한 데이터 이동이 없고 두 번째 복사본도 없기 때문에 두 뷰가 서로 달라질 수 없습니다. 분석 도구는 항상 애플리케이션이 방금 기록한 것과 동일한 데이터를 읽습니다.

LTAP가 어떻게 구성되는지 자세히 알아보려면 Data and AI Summit의 데모를 확인해 보세요.

HTAP는 어떨까요?

이 분야를 잘 아신다면 LTAP가 HTAP(hybrid transactional/analytical processing, 하이브리드 트랜잭션/분석 처리)를 의도적으로 변형한 이름이라는 것을 이미 눈치채셨을 것입니다. HTAP는 트랜잭션 워크로드와 분석 워크로드를 모두 처리할 수 있는 단일 엔진을 만드는 데 초점을 맞춘 데이터베이스 엔지니어링의 오랜 숙원이었습니다.

실제로 널리 채택된 HTAP 데이터베이스 시스템은 아직 시장에 존재하지 않습니다. 왜 그럴까요? 제 생각에 HTAP 시스템은 다음과 같은 문제 중 하나 이상을 겪고 있기 때문입니다.

불완전한 기능 세트. 단 하나의 작업을 수행하는 새로운 독점 엔진을 처음부터 설계하는 데도 수년의 투자가 필요합니다. 여러 엔진의 역할을 동시에 수행할 수 있는 단일 엔진을 구축하려는 시도는 엔지니어들이 성숙한 데이터베이스에서 당연하게 여기는 기능 세트를 갖추기 위해 필요한 투자를 배가시킵니다. 이러한 시스템은 광범위한 SQL 지원(예: 외래 키 지원)부터 쿼리 옵티마이저의 성숙도에 이르기까지, 사람들이 항상 존재할 것이라고 생각하는 기능들에서 뒤처지는 경우가 많습니다.

생태계 부재. Postgres와 Spark는 각각 드라이버, 확장 기능, 도구, 수십 년간 축적된 운영 지식 등 방대한 생태계의 중심에 있습니다. 완전히 새로운 엔진은 이 모든 것의 외부에서 시작해야 하며, 엔진의 유용성은 팀이 실제로 활용할 수 있는 생태계의 크기에 비례합니다.

성능 격리 불가. 많은 HTAP 시스템은 동일한 하드웨어에서 트랜잭션과 분석을 실행하므로 두 워크로드가 동일한 CPU 및 메모리를 두고 경쟁합니다. 이는 분석 쿼리가 트랜잭션 워크로드의 자원을 고갈시키는, 모놀리스(monolith)에서 겪었던 것과 동일한 실패를 반복하는 것입니다.

이 세 가지 문제 모두 두 워크로드를 하나의 엔진으로 통합하려는 동일한 결정에서 비롯됩니다. Lakebase와 LTAP는 스토리지 레이어에서 통합하는 동시에 서로 다른 워크로드에 서로 다른 컴퓨팅 엔진을 사용하여 이러한 문제를 우회합니다. 이를 통해 완전한 성능 격리를 유지하면서 각 엔진의 전체 기능 세트와 생태계 지원을 활용할 수 있습니다.

마치며

지난해 저희가 Lakebase 아키텍처를 처음 제안했을 때, Neon 플랫폼에서 확인한 바를 바탕으로 무제한 스토리지, 탄력적 컴퓨팅, 내구성 있는 쓰기, 더 간단한 HA, 즉각적인 브랜칭(branching)이 가능해질 것임을 이미 알고 있었습니다. WAL이 SafeKeeper에 있고 데이터 파일이 PageServer에 있게 되면서 이러한 이점들은 거의 기계적으로 뒤따라왔습니다.

LTAP 아이디어는 이후 Neon과 Databricks 팀이 힘을 합쳐 가장 최신의 트랜잭션 데이터를 대상으로 분석을 수행하는 수십 년 된 과제를 해결하는 과정에서 나왔습니다. 앞으로 몇 달 동안 LTAP의 미비한 점들을 보완하고 출시함에 따라, 모든 Lakebase 테이블을 Lakehouse 데이터만큼 높은 성능으로 분석에 활용할 수 있게 될 것입니다.

저를 가장 설레게 하는 것은 앞으로 다가올 미래입니다. LTAP는 자연스러운 다음 단계이지만, 이와 동일한 설계는 다른 무거운 유지 관리 작업과 핵심 트랜잭션 워크로드를 분리할 수 있는 많은 최적화 기회도 열어줍니다. 저희는 이제 막 이 아키텍처가 가능하게 하는 것들을 탐색하기 시작했으며, 다음에 어떤 결과물이 나올지 공유할 수 있기를 기대하고 있습니다.

감사의 글: 이 블로그에서 논의한 모든 내용을 현실로 만들어 주고, 글을 검토하며 기술적 세부 사항을 솔직하게 유지할 수 있도록 도와준 Lakebase 팀에 감사드립니다.

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

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

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