퀀트 만들면서 redis, postgresql 짜증
제가 만든 뉴로모픽AI모델로 퀀트를 테스트 중입니다
예전에도 몇개의 KRX용 퀀트를 만들었었죠
이번에는 BTC, SOL, XRP 선물 스캘핑 시뮬레이터입니다
왜냐하면 binance websocket은 20호가잔량, 체결내역을 api key조차 없이 공짜로 가져올 수 있거든요 24시간 거래되고 변동성도 크기 때문에 재미있는 시장입니다
예전에 퀀트를 만들때에는 지난 30년간 웹,앱의 습성에 젖어서 여전히 redis(via uds), postgresql(via tcp/ip) 를 퀀트 메인앱(rust 빌드)와 연동해서 썼죠
아주 짜증납니다. 각각 서버도 heathcheck해야 되고 각각의 redis, postgresql 다 따로 챙기고 정합성 맞추고 통신 맞추고 queue 맞추고 lock 맞추고… 에휴 이거 하다가 지치면 그냥 퀀트 거래 로직 짜는건 뒷전이 되어 버립니다
redis, postgresql은 기본적으로 다중사용자(즉 네트워크용)인데 내가 왜 거추장스러운 이걸 사용하고 있는건지 문득 짜증이 매우 몰려옵니다
왜 그걸 사용했으냐? 바로 sqlite가 성능이 떨어진다고 생각했기 때문이죠
실제로 sqlite가 퀀트부띠끄에서 사용하기에 부족한가? 엄청난 데이터로 통계와 계산을 많이 한다면 확실히 postgresql로 가는 것이 맞습니다만 스캘핑이라면 이야기가 달라질 것 같습니다
또한 redis도 rust에서는 redb로 대체 가능합니다. redb가 redis만큼의 기능이 많고 좋은 것은 아니지만 redb는 rust와 일체형이고 오히려 redis와의 통신과 파일기록에서 어긋날 수 있는 부분이 제거되기 때문에 더 빠르고 더 안전하다고도 볼 수 있습니다. raw데이터/log데이터 캐시, 메시지 큐 같은 기능으로 사용하기에 충분합니다
아래는 sqlite 와 postgresql의 용도별 사용 장단점입니다. vscode도 내부적으로 sqlite 씁니다
네, 부띠끄 퀀트(Boutique Quant)처럼 내부 인프라를 직접 통제하고 외부 다중 접속을 고려하지 않는 환경이라면 SQLite는 최고의 선택 중 하나입니다. 말씀하신 대로 PostgreSQL의 고급 기능들을 Rust 로직으로 직접 구현(예: 시계열 처리, 복잡한 통계 연산 등)한다면, "서버형 DB가 왜 필요한가?"라는 질문에 도달하게 되죠.
하지만 '순수 SQL 성능'과 '엔진의 설계 구조' 관점에서 SQLite가 PostgreSQL이나 MySQL에 비해 물리적으로 부족할 수밖에 없는 지점들이 있습니다. 퀀트 데이터를 다룰 때 체감될 수 있는 부분 위주로 짚어 드릴게요.
1. 쿼리 병렬 처리 (Parallel Query Execution)
이 부분이 퀀트 분석에서 가장 큰 차이일 수 있습니다.
PostgreSQL: 하나의 복잡한
SELECT문(예: 수억 건의 백테스팅 데이터 집계)을 처리할 때, 설정에 따라 여러 개의 CPU 코어를 동시에 동원합니다.SQLite: 쿼리 하나는 무조건 CPU 코어 1개만 사용합니다. 아무리 노트에 코어가 많아도, 하나의 거대한 쿼리는 한 놈만 팹니다.
퀀트 영향: 수천만 건의 데이터를 조인하거나 무거운 집계(
AVG,STDDEV등)를 돌릴 때, 데이터가 커질수록 PostgreSQL이 물리적으로 더 빠를 수 있습니다.
2. 쿼리 옵티마이저(Query Optimizer)의 지능
DB 엔진의 '두뇌' 수준 차이입니다.
PostgreSQL: 수십 년간 엔터프라이즈 환경에서 다듬어진 '비용 기반 옵티마이저(CBO)'를 가집니다. 조인 순서, 인덱스 활용 여부, 데이터 분포 통계 등을 매우 정교하게 계산해서 최적의 경로를 찾습니다.
SQLite: 옵티마이저가 상대적으로 단순합니다. 쿼리가 아주 복잡해지면(서브쿼리가 여러 개 겹치거나 조인이 5~6개 이상 붙을 때), SQLite는 가끔 비효율적인 길로 빠질 수 있습니다.
3. 대용량 메모리 관리 (Buffer Pool Control)
PostgreSQL: 시스템 메모리의 수십 GB를 'Shared Buffers'로 할당해서 아주 정교하게 데이터를 캐싱합니다. 데이터가 디스크로 가기 전에 메모리에서 최대한 처리되도록 설계되어 있습니다.
SQLite:
cache_size설정이 있지만, 대규모 서버급 DB처럼 복잡한 알고리즘으로 페이지를 교체하거나 메모리를 공격적으로 점유하며 최적화하는 능력은 조금 떨어집니다.
4. 인덱스의 다양성 (Advanced Indexing)
PostgreSQL: B-Tree 외에도 GIN(역색인, 검색용), GiST(지리 정보, 범위 검색), BRIN(초대용량 시계열용) 등 괴물 같은 인덱스들이 많습니다.
SQLite: 거의 B-Tree 하나에 의존합니다. 물론 퀀트 데이터의 핵심인 시간(Time)과 심볼(Symbol)은 B-Tree만으로도 충분히 빠르지만, 특정 범위 검색이나 특수한 형태의 데이터 검색에서는 PostgreSQL의 특수 인덱스가 압도적일 수 있습니다.
💡 그럼에도 불구하고 Boutique Quant에게 SQLite가 정답인 이유
위의 단점들은 보통 "데이터가 수억 건을 넘어가고, 서버 하드웨어가 수십 개의 코어를 가졌을 때" 비로소 체감되는 것들입니다.
지연 시간(Latency)의 승리: 쿼리 실행 자체는 PostgreSQL이 병렬로 해서 빠를지 몰라도, Rust 앱에서 PostgreSQL까지 데이터를 요청하고 응답받는 네트워크/소켓 통신 시간을 합치면, 결국 옆방에 있는 SQLite가 더 빨리 결과를 내놓는 경우가 허다합니다.
Rust가 DB의 뇌를 대체: 말씀하신 대로 복잡한 연산을 SQL로 짜지 않고, SQLite에서는 데이터만 빠르게 뽑아온 뒤 Rust의 고성능 로직(Iterators, Rayon 등)으로 병렬 처리해버리면 DB 엔진의 병렬 처리 부재를 완벽히 상쇄하고도 남습니다.
리소스 집중: 노트북 환경에서 PostgreSQL이 점유할 자원을 아껴서 Rust 앱의
wgpu연산이나 전략 로직에 쏟는 것이 퀀트 수익률 측면에서 훨씬 이득입니다.
결론
순수 SQL의 '복잡한 대량 집계 연산' 성능은 PostgreSQL이 앞섭니다. 하지만 "빠르게 쓰고, 필요한 데이터만 딱 집어서 가져오는" 스캘핑과 퀀트의 일상적인 작업에서는 SQLite가 주는 가벼움과 속도를 이기기 어렵습니다.
"DB는 저장소로만 쓰고, 머리는 Rust를 쓴다"
이 원칙만 지키신다면 SQLite의 부족한 부분은 전혀 문제가 되지 않을 것입니다.