GN⁺: 분산형 SQLite: 패러다임의 전환인가 과장된 선전인가?
(kerkour.com)- SQLite는 매우 빠름. 싱글 ~40€/m 일반 서버에서 동시에 ~168,000 읽기와 ~8000 쓰기를 지속할 수 있음
- 임베디드 시스템, 폰, 데스크톱 애플리케이션 등의 클라이언트 사이드 애플리케이션을 위해 설계된 임베디드 라이브러리이기 때문에, SQLite 데이터베이스는 애플리케이션 서버에 함께 위치해야 하며 네트워크를 통해 액세스할 수 없음
- 하나 이상의 머신이 필요한 상황에서의 SQLite 활용?
- 주말 프로젝트가 폭발적인 인기를 얻어 빠르게 확장해야 할 수도 있음
- CTO의 요구사항 중 하나는 최소 2개의 다른 데이터 센터에 고가용성 서비스를 배포하는 것일 수 있음
- 지난 몇 년 동안 SQLite를 백엔드 애플리케이션을 위한 백엔드 데이터베이스로 개조하려는 몇 가지 프로젝트가 등장함.
- 이것이 조직이 더 나은 사용자 경험을 더 빠르게 제공할 수 있게 하는 패러다임 전환인지, 아니면 "고유 판매 제안(Unique Selling Proposition)"을 부풀리려는 회사들이 밀고 있는 마케팅 과대광고인지 알아보는 글
SQLite를 에지 데이터베이스로 활용
- SQLite는 단순한 백엔드 데이터베이스가 아니라 에지 데이터베이스로 홍보되고 있음
- 가장 대표적인 플레이어는 Cloudflare D1, LiteFS를 사용하는 fly.io, Turso 등임
- 대부분의 SQLite 파생 제품들은 비슷한 방식으로 작동함
- 어딘가에 쓰기를 받아들이는 주 데이터베이스가 있고, 이는 다른 지역에 비동기적으로 복제됨
- 복제는 주로 데이터베이스에서 실행된 모든 트랜잭션의 로그인 SQLite의 Write-Ahead Log를 스트리밍하는 방식으로 이루어짐
- 이러한 아키텍처에서는 이론적으로 읽기는 에지 데이터 센터에서 처리할 수 있지만, 쓰기는 여전히 중앙 위치로 전달되어야 함
- 실제로는 고객이 이커머스 애플리케이션에서 주문을 완료했는데, 주 SQLite 데이터베이스에서는 주문이 승인되었지만 지역 읽기 복제본이 뒤처져서 아직 업데이트된 데이터를 받지 못해 찾을 수 없음 오류 메시지를 표시하고 싶지 않을 것임
- "고통스러운 Eventual Consistency의 세계"에 오신 것을 환영함
LiteFS의 해결책과 한계
- LiteFS는 해킹 같은 솔루션을 제안함. 애플리케이션이 지역 복제본이 가진 마지막 트랜잭션을 추적하기 위해
__txid
쿠키를 설정하고, 너무 오래된 경우 읽기 쿼리를 기본 데이터베이스로 전달함. - 이제 애플리케이션은 데이터베이스 및 역방향 프록시와 밀접하게 연결됨
- LiteFS는 초당 약 100개의 쓰기만 지원한다는 사실은 언급하지 않음
대부분의 분산 SQLite 시스템의 주요 단점
- 대부분의 분산 SQLite 시스템은 트랜잭션의 서로 다른 쿼리 사이에 일부 계산을 수행하는 대화형 트랜잭션을 지원하지 않음.
- 한 번에 하나의 쓰기 트랜잭션만 활성화될 수 있음. 일반 SQLite 데이터베이스에서는 대부분의 쓰기가 수십 마이크로초 이상 지속되지 않기 때문에 일반적으로 괜찮음
- 그러나 애플리케이션과 SQLite 데이터베이스 사이에 네트워크 지연 시간을 도입하면 시스템이 중단됨. 데이터베이스는 트랜잭션의 왕복 시간 동안 잠기게 되고 초당 몇 번의 쓰기로 제한될 것임
- Turso는 이를 배치로 "해결"함. 여러 쿼리를 배치로 묶어 단일 트랜잭션으로 실행할 수 있음. Cloudflare D1은 배치 및 저장 프로시저로 문제를 "해결"함
더 간단한 솔루션이 있다면?
- 웹 애플리케이션에는 전 세계적으로 매우 빠르게 만들 수 있는 매우 간단하고 강력한 방법이 이미 있음:
Cache-Control
과ETag
헤더를 사용한 HTTP 캐싱임 - HTTP 캐싱을 사용하면 약한 일관성 데이터베이스와 유사한 기술을 사용할 필요가 없어 웹 애플리케이션이 너무 복잡해지거나 경쟁 조건에 취약해지는 것을 방지할 수 있음
- 이 글의 작성자는 새 책 "Cloudflare for Speed and Security"에서 웹 애플리케이션을 빠르게 만들 뿐만 아니라 최소한의 리소스로 많은 동시 사용자를 처리할 수 있는 다양한 캐싱 전략을 설명하는 데 많은 시간을 할애함
추상화로서의 데이터베이스
- 지연 시간은 분산 SQLite가 해결하려고 했던 유일한 문제점이 아님. 다른 하나는 운영 복잡성임.
- 네트워크로 연결된 서버 클러스터를 관리하는 것은 어렵고 종종 가동 중지 시간과 수익 손실로 이어짐. 2017년 GitLab이 겪었던 것과 같은 재앙을 피하기 위해 지속적인 관리와 우수한 보안 문화가 필요한 데이터베이스 관리는 말할 것도 없음.
- 따라서 아이디어는 데이터베이스를 애플리케이션과 번들로 제공하고 모든 것을 단일 서버에 배치하는 것임
- 단일 개발자가 있을 때는 좋지만, 대규모 조직에서는 데이터베이스 서버 유지 관리를 전담하는 사람이나 팀이 있을 것임
- 이것이 바로 임베디드 라이브러리가 아닌 소켓을 통해 액세스하는 데이터베이스가 실제로 기술적인 추상화가 아닌 조직적 추상화라는 점에서 훌륭한 추상화인 이유임. 개발 중에는 개발자 머신에서 실행되는 간단한 컨테이너일 수 있지만, 프로덕션에서는 애플리케이션과 동일한 서버에서 실행되는 컨테이너부터 네트워크를 통해 액세스하는 분산 클러스터까지 무엇이든 될 수 있음. 개발자는 단일 구성 변수인
DATABASE_URL
만 교체하면 되고 운영팀이 나머지를 모두 처리함 - 반대로 전통적인 Unix 파일 시스템은 분산 컴퓨팅에 적합하지 않은 추상화였음. 물론 NFS(Network File System)가 존재하지만 Unix 파일 시스템이 단일 머신 액세스용으로 설계되었기 때문에 성능이 상당히 좋지 않음. 반면에 S3 프로토콜은 대량의 비정형 데이터를 효율적이고 확장 가능하며 안정적인 방식으로 저장하는 데 상당히 좋은 추상화임. 개발자는 S3 호환 SDK를 사용하고 잊어버리기만 하면 되고, 운영팀이나 클라우드 제공업체가 성능, 내구성, 안정성 등 모든 것을 처리할 것임
결론
- SQLite는 정말 놀라운 데이터베이스이지만 대부분의 팀은 SQLite를 피하고 대신 PostgreSQL을 선택하는 것이 좋음
- 수많은 엔지니어링 시간이 PostgreSQL을 최고의 백엔드 데이터베이스로 만드는 데 사용되었음. SQLite를 선택하면 불가피하게 PostgreSQL이 오랫동안 가지고 있던 것을 취약하고 버그가 많은 방식으로 재발명해야 함
- 현재 SQLite를 백엔드 데이터베이스로 만들려는 움직임은 컴퓨팅이 데이터 저장소 없이는 아무것도 아니라는 것을 깨달은 에지 컴퓨팅 인프라를 판매하는 회사들의 마케팅 쿠데타에 불과하다고 봄. 이들에 대한 (요청하지 않은) 조언은 CDN을 구축하고 애플리케이션에 복잡성을 강요하는 대신 HTTP 캐싱에 투자하는 것임. 이는 훨씬 더 나은 결과를 가져다줌
- 유발된 복잡성 때문에 백엔드 애플리케이션의 99.9%는 에지로 이동하는 데 어떤 이점도 보지 못할 것이며, 대신 전 세계적으로 100ms 미만의 훌륭한 경험을 제공하기 위해 좋은 캐싱 전략을 배포하는 데 주력해야 함
- 그리고 이것이 서버 사이드 애플리케이션을 위한 SQLite 실험이 끝나는 지점임. PostgreSQL의 승리임
-
"아마추어는 전술을 논하고, 전문가는 물류를 논한다. (Amateurs discuss tactics. Professionals discuss logistics.)"
성공을 위해서는 현장에서의 전술적 결정보다는 그러한 결정을 가능하게 하는 뒷받침되는 시스템과 과정, 즉 물류와 관리가 더 중요하다는 것
GN⁺의 의견
- 저자의 주장대로 대부분의 백엔드 애플리케이션에서 SQLite를 사용하는 것은 복잡성만 증가시킬 뿐 실질적인 이점이 없어 보임. 이미 검증되고 성숙한 PostgreSQL과 같은 데이터베이스를 사용하는 것이 더 나은 선택일 것임.
- 에지 컴퓨팅 인프라 업체들이 SQLite를 밀어붙이는 것은 기술적 장점보다는 마케팅 전략의 일환으로 보임. 이들이 HTTP 캐싱과 CDN에 더 투자하는 것이 애플리케이션 개발자들에게 도움이 될 것임.
- 대부분의 백엔드 애플리케이션은 적절한 캐싱 전략만으로도 충분히 빠르고 확장 가능한 서비스를 제공할 수 있음. 에지 컴퓨팅이 반드시 필요한 경우가 아니라면 과도한 복잡성을 피하는 것이 좋음.
- 분산 SQLite는 특정 유즈케이스에서는 유용할 수 있지만, 범용 솔루션으로 사용하기에는 아직 한계가 있어 보임. 개발 편의성과 성능, 일관성 등을 모두 만족시키기는 쉽지 않을 것임
- 결국 애플리케이션의 요구사항과 팀의 역량에 맞는 기술을 선택하는 것이 가장 중요함. 유행에 휩쓸리기보다는 장단점을 철저히 분석하고 신중하게 의사결정해야 함.
- 저자는 SQLite가 백엔드 데이터베이스로 사용되기에는 아직 부족한 점이 많다는 것을 강조하지만 SQLite의 장점을 살릴 수 있는 다른 유즈케이스가 있을 수 있으므로 완전히 배제할 필요는 없어 보임.
Hacker News 의견
- LiteFS의 작성자에 따르면, 분산 SQLite는 개발자들에게 패러다임 전환이나 과대 광고가 아닌, 확장 또는 "다음 단계"로 볼 수 있음
- SQLite의 수평적 확장성에 대한 우려를 해결함
- 분산 SQLite를 통한 예정된 패러다임 전환은 사용자 기기를 향할 것으로 예상됨
- 로컬 우선 앱을 가능하게 하여, 빠른 UI 상호작용과 동기화를 통한 최종 일관성을 제공함
- 프로덕션 환경에서 LiteFS를 사용하면 데이터베이스 쿼리를 즉시 해결할 수 있어, 웹 앱에서 로딩 상태를 제거하고 빠른 로드 시간을 가능하게 함
- 자체 호스팅을 위한 간단하고 분산된 오픈 소스 스토리지 솔루션에 대한 필요성이 있음
- Ceph, SeaweedFS, MinIO 등 기존 솔루션은 도전과제와 복잡성을 가지고 있음
- LiteFS의 아이디어는 읽기 중심 애플리케이션을 위해 네트워크 n-티어 아키텍처를 대체함으로써 SQLite의 성능 이점을 활용하는 것임
- 모든 애플리케이션에 완벽하게 적합하지는 않을 수 있음
- SQLite 사용이 "몇 밀리초만 절약"할 것이라는 기사의 주장은 과소평가로 여겨짐
- 애플리케이션을 사용자에게 더 가깝게 실행하면 쿼리 대기 시간을 크게 줄일 수 있음
- SQLite와 PostgreSQL은 서로 다른 사용 사례와 장점을 가짐
- 둘 사이의 직접적인 경쟁은 아님
- PostgreSQL이 최고의 백엔드 데이터베이스이고 SQLite를 사용하면 취약한 방식으로 기능을 재발명하게 될 것이라는 기사의 주장에 의문이 제기됨
- 다른 데이터베이스에 대해서도 유사한 주장을 할 수 있음
- 사용자별로 별도의 데이터베이스를 만들어 SQLite를 분할하는 것은 잠재적인 접근 방식임
- 단, 사용자들이 서로의 데이터와 상호작용할 필요가 없어야 함