본문 바로가기
C.W.K.
Stream
Lesson 06 of 10 · published

SQLite가 잘못된 선택인 경우

~12 min · sqlite, limits, fit

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

잘못된 도구가 되는 자리

SQLite를 정직하게 편들려면 대놓고 잘못된 도구가 되는 자리부터 짚어야 해. 아래 상황이면 Postgres나 다른 네트워크 DB로 가.

  • 여러 머신에서 여러 writer가 쓴다 — SQLite는 파일 하나 안에서 write를 한 줄로 세워. 로드 밸런서 뒤에 앱 서버를 여러 대 두고 같은 logical DB에 다 쓰는 워크로드는 Postgres 영역이야.
  • 네트워크로 붙어야 한다 — 다른 호스트의 클라이언트가 데이터를 query해야 하면 서버가 필요해. SQLite에는 빌트인 네트워크 프로토콜이 없어.
  • 유저 단위로 잘게 나눈 인증이나 row-level security가 필요하다 — Postgres는 RBAC과 RLS를 풍부하게 줘. SQLite가 가진 건 파일 권한이 전부야.
  • 데이터가 아주 크고 write가 뜨겁다 — read나 append 위주라면 TB 단위도 감당해. 하지만 writer 수천이 동시에 OLTP로 두드리는 10 TB짜리 시스템은 진짜 DB 서버의 영역이야.
  • replication과 HA가 기본으로 있어야 한다 — Postgres는 streaming replication이 들어 있고 매니지드 서비스도 어디나 있어. SQLite는 Litestream이나 LiteFS, Turso로 얹는 건데 semantic이 달라.
  • RBAC이 필수다 — multi-tenant SaaS에서 tenant마다 SQL 레벨 자격증명으로 갈라놔야 하는 경우.
Warning: 가장 흔한 SQLite 사고는 로드 밸런싱된 서버 여러 대 뒤에 SQLite를 두고 replication 레이어 없이 굴리는 거야. 서버마다 자기 사본이 생기고 조용히 갈라져. NFS나 GlusterFS, '그냥 rsync로 때우지' 같은 생각이 떠올랐다면 거기서 멈춰. 다른 DB를 쓰거나 Litestream이나 Turso를 들여와.

SQLite도 scale한다의 정직한 버전은 이래. 노드 한 대 위에서 수직으로, 그리고 read 쪽으로는 사람들 생각보다 훨씬 잘 늘어나. 반면 동시 writer를 위한 수평 확장은 제대로 된 replication 레이어 없이는 안 되고, SQLite도 된다고 우기지 않아.

Code

'한 번에 하나의 writer'가 어떻게 보이나·python
# 두 프로세스가 동시에 쓰려고 하면, 두번째가 첫번째 commit 까지 잠깐 block.
# WAL + busy_timeout 이면 일반 트래픽에선 OK.
# 많은 프로세스가 hot-loop 으로 쓰면 병목.
import sqlite3, time, threading

def writer(name):
    conn = sqlite3.connect('contention.db', timeout=5.0)
    conn.execute('PRAGMA journal_mode=WAL')
    conn.execute('CREATE TABLE IF NOT EXISTS log(id INTEGER PRIMARY KEY, who TEXT, t REAL)')
    for _ in range(1000):
        conn.execute('INSERT INTO log(who, t) VALUES (?, ?)', (name, time.time()))
        conn.commit()
    conn.close()

threading.Thread(target=writer, args=('A',)).start()
threading.Thread(target=writer, args=('B',)).start()

External links

Exercise

Postgres나 MySQL을 쓰는 서비스를 하나 골라. 그 워크로드의 어떤 성질이 SQLite를 부적합하게 만드는지 짚어봐. 네트워크 접근인지, writer가 여럿인지, RBAC인지. 그다음 질문이 진짜야. 아키텍처를 처음부터 다시 짠다면 — 유저마다 DB를 따로 두거나, edge runtime으로 옮기거나, tenant별로 쪼개거나 — SQLite로도 됐을까? 그러려면 디자인의 어디가 달라져야 했을까?

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.