DuckDB Quack 서버, 여러 프로세스의 한 파일 쓰기 중계…시험 처리량은 5개 클라이언트에서 최고
DuckDB의 Quack 확장은 데이터베이스 파일을 연 서버 프로세스로 여러 클라이언트의 SQL 요청을 모읍니다. Alex Georgiev의 DuckDB 2.0.0 시험에서는 10개 프로세스가 보낸 1,000건의 쓰기가 세 차례 모두 저장됐습니다. 처리량은 5개 클라이언트에서 가장 높았고, 20개에서는 단일 클라이언트의 직렬 실행과 비슷했습니다.

DEV Community에 글을 올린 Alex Georgiev는 11월 11일 DuckDB 2.0.0의 Quack 확장으로 여러 프로세스가 한 데이터베이스 파일에 쓰는 시험 결과를 공개했습니다. Python 프로세스 10개가 각각 단일 행 INSERT 100건씩 보내 총 1,000건을 기록했습니다. 세 차례 반복 모두 오류가 없었으며, 요청한 행 수와 각 클라이언트·순번 조합도 저장 결과와 일치했습니다.
파일을 공유하는 대신 서버에 질의를 보냅니다
DuckDB는 애플리케이션 안에서 실행되고 데이터를 파일로 저장하는 내장형 데이터베이스입니다. Georgiev가 시험한 기존 방식에서는 두 프로세스가 같은 파일에 쓰려고 열자 한쪽에서 잠금 오류가 났습니다. 그는 쓰기 작업이 없을 때 두 프로세스가 파일을 읽기 전용으로 열어 동시에 조회하는 방식은 이미 작동했다고 설명합니다. Quack은 여러 프로세스의 쓰기 요청을 서버 한곳으로 모아 처리하는 경로를 제공합니다.
Quack을 쓰면 서버 프로세스가 DuckDB 파일을 열고 quack_serve로 요청을 받습니다. 다른 프로세스는 Quack 주소로 원격 데이터베이스를 연결한 뒤 CONNECT를 실행합니다. 그러면 연결이 끊길 때까지 세션 전체의 질의가 서버에서 실행됩니다. DuckDB 공식 문서는 Quack의 통신을 HTTP 기반으로 설명합니다. 서버 프로세스 하나가 파일 잠금을 유지하고, 여러 클라이언트가 서버를 통해 데이터를 읽고 쓰는 구조입니다.
Georgiev의 비교 시험에서 두 프로세스가 파일을 직접 열어 쓰려 하자 잠금 오류가 발생해 행이 저장되지 않았습니다. Quack을 거친 시험에서는 클라이언트 10개가 각각 100건씩 INSERT해 총 1,000건을 기록했습니다. 세 차례 반복에서 저장 누락이나 중복은 없었습니다.
클라이언트 수를 늘린다고 쓰기 속도가 계속 오르지는 않습니다
Georgiev는 같은 1,000건의 INSERT를 1개, 5개, 10개, 20개 동시 클라이언트로 나눠 각각 세 차례 실행했습니다. 초당 삽입 건수는 5개 클라이언트일 때 655~735건으로 가장 높았습니다. 10개에서는 508~570건으로 낮아졌고, 20개에서는 332~362건을 기록해 클라이언트 하나로 직렬 실행한 348~401건과 비슷한 수준이 됐습니다.
Georgiev는 DuckDB가 한 파일에 대한 쓰기를 내부적으로 한 번에 하나씩 처리하고, 여기에 Quack의 연결 처리 비용이 더해진다고 설명했습니다. 클라이언트가 적을 때는 서버 쪽 요청 대기열을 활용하는 이점이 있었지만, 수가 많아지면 연결 처리 부담이 처리량을 낮췄습니다. 그는 5개라는 결과가 자신의 장비와 작업에서 나온 값이며 다른 환경에 그대로 적용될 근거는 없다고 적었습니다.
질의 시간은 작업 크기에 따라 달랐습니다. 200회 측정에서 단순 질의 SELECT 1의 중앙값은 프로세스 내부 실행에서 0.25ms, Quack 경유 실행에서 1.92ms였습니다. 반면 100만 행을 모두 가져오는 질의는 0.334초에서 0.391초로 늘었습니다. 짧은 질의에서는 서버 왕복 비용의 비중이 크게 나타났고, 결과가 많은 질의에서는 두 방식의 시간 차이가 상대적으로 작았습니다.
CONNECT 중에는 로컬 테이블이 보이지 않습니다
CONNECT를 실행하면 클라이언트 세션 전체가 서버 쪽 데이터베이스로 전환됩니다. Georgiev는 연결 중 클라이언트의 로컬 테이블을 조회할 수 없었고, DISCONNECT 뒤에는 다시 조회할 수 있었다고 밝혔습니다. 따라서 로컬 테이블과 원격 테이블을 같은 세션에서 결합하는 작업에는 제약이 있습니다. 그는 원격 세션을 별도 연결 객체로 유지하는 방식을 대안으로 제시했습니다.
서버는 기본적으로 localhost에서만 요청을 받고 클라이언트 인증 토큰을 요구합니다. 외부 주소에서 요청을 받으려면 allow_other_hostname=true를 설정해야 합니다. DuckDB 공식 문서는 외부에 서비스를 공개할 때 TLS를 처리하는 역방향 프록시를 앞세우라고 권합니다. Quack 서버는 서버 세션이 볼 수 있는 데이터베이스의 테이블에 읽기·쓰기 SQL을 제공합니다. 기본 권한 처리는 질의를 그대로 통과시키므로 토큰은 접속 인증에 쓰이며, 읽기 전용이나 테이블별 접근 제한에는 별도의 권한 처리가 필요합니다.