re:Invent에서 공개된 Aurora DSQL 프리뷰를 소개하며, 멀티리전 액티브-액티브, 지연 시간 모델, 강한 일관성과 스냅샷 격리, 서버리스 운영 및 PostgreSQL 호환성 등 핵심 개념과 배경, 그리고 개인적인 뒷이야기를 전합니다.
드디어 시작됐습니다.
오늘 아침 re:Invent 기조연설에서 Matt Garman이 Aurora DSQL을 발표했습니다. 이번 프리뷰를 고객분들 손에 드리게 되어 모두가 기대하고 있고, 어떤 사람들은 무척이나 들떠 있습니다. 앞으로 며칠 동안 DSQL이 무엇인지, 어떻게 동작하는지, 어떻게 가장 잘 활용하는지에 대해 몇 편의 글을 쓰려 합니다. 이 글은 제품 자체와 약간의 개인적인 이야기를 다룹니다.
공식 문서인 AWS의 Aurora DSQL 문서가 DSQL이 무엇이며 어떻게 사용하는지 이해하기 위한 좋은 출발점입니다.
Aurora DSQL이란?
Aurora DSQL은 트랜잭션 처리에 최적화되고 클라우드를 위해 설계된 새로운 서버리스 SQL 데이터베이스입니다. DSQL은 취미 프로젝트부터 가장 큰 엔터프라이즈 애플리케이션까지 거의 모든 규모의 워크로드를 처리할 수 있도록 수평·수직으로 확장 및 축소되도록 설계되었습니다. 여러분이 기대하는 모든 SQL 기능이 있습니다. 트랜잭션, 스키마, 인덱스, 조인 등등이며, 강한 일관성과 격리성5을 제공합니다.
DSQL은 단일 리전 내 여러 가용 영역(AZ)에서, 혹은 여러 리전에 걸쳐 액티브-액티브 멀티 라이터 기능을 제공합니다. 읽기와 쓰기, 심지어 읽기-쓰기 트랜잭션에서도 빠르고 로컬이며, 교차 리전 통신이 필요하지 않습니다(단일 리전 구성에서는 교차 AZ 통신도 필요하지 않습니다). 트랜잭션 커밋은 리전 간(멀티 리전 구성) 또는 AZ 간(단일 리전 구성)으로 전파되어, 트랜잭션의 내구성, 격리성, 원자성을 보장합니다.
DSQL은 PostgreSQL 호환으로, PostgreSQL의 방대한 SQL 기능 집합 중 일부를 제공합니다. 선호하는 PostgreSQL 클라이언트(예: psql CLI)로 연결하고, 선호하는 ORM과 프레임워크를 사용할 수 있습니다. 앞으로 PostgreSQL 호환 기능을 더 추가하여 기존 코드를 DSQL로 쉽게 가져올 수 있도록 할 예정입니다.
DSQL은 서버리스입니다. 여기서 말하는 서버리스란, AWS 콘솔(또는 API, CLI)에서 클러스터를 생성하면 그 클러스터가 엔드포인트를 포함하고, 여러분은 그 엔드포인트에 PostgreSQL 클라이언트를 연결하기만 하면 된다는 뜻입니다. 관리, 확장성, 패치, 장애 허용, 내구성 등은 모두 기본 제공됩니다. 인프라에 대해 걱정할 필요가 없습니다.
Aurora DSQL을 출시하면서 멀티 리전 액티브-액티브 이야기를 많이 하고 있지만, 그것만을 위한 것은 아닙니다. 우리는 DSQL을 모든 규모의 단일 리전 애플리케이션에도 훌륭한 선택이 되도록 만들었습니다. 하루에 몇 건의 요청만 있는 경우부터 초당 수천 건을 훌쩍 넘는 경우까지요.
개인적인 이야기
2020년에 저는 AWS에서 서버리스 컴퓨팅을 담당하며, 대부분의 시간을 훌륭한 AWS Lambda 팀1과 보냈습니다. 늘 그랬듯이 고객 분들과 많은 대화를 나눴고, 서버리스와 컨테이너 고객들로부터 일관되게 두 가지 이야기를 듣고 있음을 깨달았습니다.
기존의 관계형 데이터베이스 제품들은 빠르게 움직이며 확장 가능한 서버리스와 컨테이너 환경에 그리 잘 맞지 않았습니다. 이 고객들은 관계형 데이터베이스와 SQL을 사랑했습니다. 사람들이 40년 동안 관계형을 사랑해 온 모든 이유 때문이죠. 하지만 서버리스 컴퓨팅의 요구와 기존 관계형 제품 사이에 많은 마찰을 느꼈습니다. Amazon RDS Proxy가 이런 마찰의 일부를 완화해 주긴 했지만, 문제를 완전히 없애지는 못했습니다.
전 세계적으로 사업을 운영하는 대형 규제 산업 고객들은 여러 AWS 리전에 걸쳐 애플리케이션을 구축하고 있었지만, 까다로운 아키텍처적 트레이드오프에 부딪혔습니다. 예를 들어 DynamoDB Global Tables처럼 멀티 리전 액티브-액티브를 선택하면, SQL, ACID, 강한 교차 리전 일관성을 포기해야 합니다. 반대로 Aurora Global Database처럼 액티브-스탠바이를 선택하면, 여러 장소에서 애플리케이션이 실제로 동시에 동작하고 있다는 마음의 평안과, 고객의 가장 가까운 리전에서 강한 일관성의 데이터를 제공하는 능력을 포기해야 합니다. 이 고객들은 두 가지를 모두 원했습니다.
같은 시기에 몇 가지 기술이 결합되기 시작했습니다. 하나는 새로운 가상화 기능들이었습니다. Caspian(가상 머신에 할당된 리소스를 동적으로, 안전하게 증감할 수 있음), Firecracker3(빠른 확장을 위한 경량 VMM), 그리고 우리가 Lambda Snapstart를 구축할 때 사용한 VM 스냅샷 기술입니다. 우리는 Caspian을 사용해 Aurora의 전체 기능 집합에 수직 오토 스케일링을 제공하는 Aurora Serverless V22를 만들었습니다.
두 번째는 EC2의 time sync로, 전 세계 EC2 인스턴스에 마이크로초 단위의 정확한 시간을 제공합니다. 고품질의 물리적 시간은 온갖 분산 시스템 문제에 매우 유용합니다. 더 흥미로운 점은 분산 시스템 내에서 조정(코디네이션)을 회피하는 방법을 가능하게 하여 확장성과 성능을 모두 개선한다는 것입니다. Aurora Postgres의 새로운 수평 샤딩 기능인 Aurora Limitless Database는 이러한 클록을 사용해 샤드 간 트랜잭션을 더 효율적으로 만듭니다.
세 번째는 Journal로, 여러 AWS 서비스(예: MemoryDB, Valkey 호환의 내구성을 갖춘 인메모리 데이터베이스4)의 핵심 부분을 구축할 때 사용한 분산 트랜잭션 로그입니다. 가용 영역과 리전 간에 원자성, 내구성, 복제를 제공하는 신뢰할 수 있고 검증된 프리미티브가 있으면 데이터베이스 시스템을 구축할 때 많은 부분이 단순해집니다. 결국 ACID의 절반은 _A_tomicity와 _D_urability니까요.
네 번째는 AWS의 강력한 형식 기법과 자동 추론 도구 모음입니다. 형식 기법은 설계와 구현 선택지의 공간을 빠르게 탐색할 수 있게 해주고, 신뢰할 수 있고 안정적인 분산 시스템 구현6을 만드는 데에도 도움이 됩니다. 분산 데이터베이스, 특히 빠른 분산 트랜잭션은 수많은 흥미로운 트레이드오프와 미묘한 함정들, 그리고 강한 정확성 근거가 필요한, 악명 높은 어려운 설계 문제입니다. 형식 기법 덕분에 우리는 더 빠르게 움직이고, 우리가 무엇을 만들고 싶은지 더 크게 생각할 수 있었습니다.
마지막으로, AWS는 오랫동안 대규모 클라우드 시스템을 구축해 왔습니다(S3는 내년에 19살이 됩니다! 믿기시나요?). 그 과정에서 엄청난 경험을 쌓았습니다. 그 경험과 함께, 사물을 만들고 운영하는 방법을 아는 놀라운 엔지니어, 과학자, 리더들이 있습니다. AWS의 진짜 비법(시크릿 소스)을 하나 꼽자면, 우리 엔지니어와 리더들이 서비스의 일상적인 운영7과 가깝게 지낸다는 점입니다. 이는 기존 서비스를 개선하고 더 나은 새로운 서비스를 만들기 위한 실전 교훈이 끊임없이 흘러들어오게 합니다.
이 모든 것의 조합이 새로운 분산 관계형 데이터베이스를 대담하게 생각해 볼 적기임을 보여주었습니다. 고객을 대신해 정말 어려운 문제 몇 가지를 해결하고자 했고, 그 해결 방법을 보기 시작했습니다.
그래서 2021년에 저는 AWS의 데이터베이스 팀들, 특히 Aurora와 QLDB 뒤에 있는 믿을 수 없을 만큼 뛰어난 팀들과 더 많은 시간을 보내기 시작했습니다. 우리는 대담한 일을 하려는 팀을 꾸렸습니다. SQL과 ACID, 글로벌 액티브-액티브, 상하향(읽기, 쓰기, 저장소를 독립적으로) 확장성, PostgreSQL 호환성, 그리고 서버리스 운영 모델을 갖춘 새로운 분산 데이터베이스 시스템을 만드는 일입니다. 이 시스템을 만든 믿을 수 없을 만큼 재능 있는 사람들로 이루어진 팀이 자랑스럽고, 고객들이 어떻게 사용하실지 정말 기대됩니다.
한 가지 큰 것
DSQL에서 우리가 취한 접근법에는 흥미로운 이점이 많지만, 제가 특히 흥분되는(키노트에서 Matt이 강조한 것과 같은) 하나가 있습니다. 바로 트랜잭션 내 문(statement) 수가 지연 시간에 미치는 영향이 어떻게 스케일되는가 하는 부분입니다. 리전 간 액티브-액티브에서는 지연 시간은 왕복 시간(RTT)에 달려 있습니다. 설령 쿼럼 리전까지 20ms 떨어져 있다 하더라도, 매 문마다(예: 락 서버로) 왕복한다면 지연 시간에 큰 타격이 됩니다. DSQL에서 리전 내 로컬 읽기는 1.2ms만큼 빠르기 때문에, 거기에 20ms가 더해지면 정말로 아픕니다.
처음부터 우리는 이를 피하는 것을 트랜잭션 프로토콜의 핵심 설계 목표로 삼았고, 그 목표를 달성했습니다. Aurora DSQL에서는 액티브-액티브 구성의 어떤 엔드포인트에서든 트랜잭션 내의 각 개별 SELECT, UPDATE, INSERT에 대해 추가적인 교차 리전 지연이 발생하지 않고, 오직 COMMIT에서만 교차 리전 지연이 발생합니다. 이는 중요합니다. 비교적 단순한 OLTP 세계에서도 트랜잭션 안에 수십, 심지어 수백 개의 문이 들어가는 일이 흔하기 때문입니다. 오직 COMMIT할 때(그리고 그것도 읽기-쓰기 트랜잭션을 COMMIT할 때만) 교차 리전 지연이 추가로 발생합니다. 읽기 전용 트랜잭션과 읽기 전용 자동 커밋 SELECT는 항상 리전 내에서 빠르게 처리됩니다(그리고 강한 일관성과 격리를 제공합니다).
DSQL을 설계하면서 우리는 개발자들이 트랜잭션의 모든 힘과 SQL의 모든 힘을 마음껏 활용할 수 있도록 하고 싶었습니다. 이번 주 후반에 그 내부가 어떻게 동작하는지 더 많이 공유하겠습니다. 우리의 목표는 개발자와 아키텍트의 일을 단순화하고, 클라우드에서 신뢰할 수 있고 확장 가능한 시스템을 더 쉽게 만들 수 있도록 하는 것이었습니다.
그 밖의 몇 가지
Aurora DSQL에서는 강한 일관성과 _스냅샷 격리_를 제공하기로 했습니다. 20년 넘게 Amazon에서 팀들이 시스템을 구축하는 것을 지켜보며, 애플리케이션 개발자들이 최종적 일관성(eventual consistency)을 다루기 어려워하고, 기본값으로 최종적 일관성을 노출하면 애플리케이션 버그로 이어지는 경우가 많다는 것을 알게 되었습니다. 최종적 일관성은 분산 시스템에서 분명히 제자리가 있습니다8. 하지만 강한 일관성이 좋은 기본값입니다. 우리는 리전 내(그리고 단일 리전 구성에서는 AZ 내) 읽기를 강한 일관성으로 제공하도록 DSQL을 설계했으며, 많은 애플리케이션에 대해 거의 트레이드오프 없이 강한 일관성을 제공합니다.
또한 기본 격리 수준으로 스냅샷 격리를 선택했습니다. 분산 데이터베이스에서 스냅샷 격리9는 높은 수준의 격리를 제공하면서도 성능상의 놀라움이 적은 달콤한 지점(sweet spot)이라고 믿습니다. 여기서도 우리의 목표는 운영자와 애플리케이션 개발자의 삶을 단순화하는 것입니다. 더 높은 격리 수준은 많은 성능 튜닝의 복잡성을 애플리케이션 개발자에게 떠넘기고, 더 낮은 수준은 추론하기가 어렵습니다. 앞으로 DSQL의 아키텍처를 더 이야기하면서, 어떻게 처음부터 스냅샷 격리를 염두에 두고 설계했는지 살펴보겠습니다.
서버리스 운영 모델과 PostgreSQL 호환성을 선택한 것도 운영자와 빌더의 일을 단순화하려는 목표에 기반합니다. 이미 많은 분들이 Postgres를 알고(그리고 사랑)하고 있으며, 새로운 것을 배우게 하고 싶지 않았습니다. 많은 애플리케이션에서는 Aurora DSQL로의 이전이 연결 설정 몇 줄만 바꾸면 될 정도로 간단합니다. 다른 애플리케이션은 더 큰 변경이 필요할 수도 있지만, 우리는 그 작업을 시간이 지남에 따라 줄이고 단순화하기 위해 노력할 것입니다.
각주
REPEATABLE READ 수준과 동일합니다.