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

Serverless는 데몬이 없다는 뜻

~12 min · sqlite, architecture, in-process

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

클라우드가 훔쳐 간 단어

SQLite가 자기를 serverless라고 부를 때, 그건 AWS Lambda나 Cloudflare Workers가 말하는 serverless와 다른 뜻이야. 여긴 진짜로 서버 프로세스라는 게 없어. 백그라운드 데몬도 없고, 붙을 소켓도 없고, 네트워크 프로토콜 자체가 없어.

대신 SQLite는 네 앱이 링크해서 쓰는 라이브러리야. 앱이 SQLite 함수를 부르면 라이브러리가 디스크 파일을 곧장 읽고 써. DB 엔진이 네 앱 프로세스 안에서, 앱의 메모리와 CPU와 file descriptor를 나눠 쓰면서 도는 거지.

이 구조가 끌고 오는 결과가 꽤 깊어.

  • Latency가 얹히지 않아 — 네트워크를 왕복할 일이 없거든. PK로 SELECT 하나 하면 로컬 파일에서 0.01 ms쯤에 끝나. localhost에 띄운 Postgres도 TCP를 타니까 1–10 ms는 먹어.
  • Connection pooling이 필요 없어 — PgBouncer를 세울 일도, max_connections를 만질 일도, connection이 새는 버그를 잡을 일도 없어.
  • 인증 레이어가 없어 — 누가 접근하느냐는 파일 시스템 권한이 정해. SQL GRANT는 안 써.
  • 배포랄 게 없어 — 바이너리를 보내면 DB 엔진이 그 안에 같이 따라가.
Tip: 프로세스 안에서 도니까 SQLite는 edge compute, embedded 시스템, 모바일 앱, CLI 도구, 그리고 Cloudflare Workers나 Fly Machines처럼 DB 연결을 오래 붙들고 있을 수 없는 환경에 딱 맞아.

뒤집어도 그대로 사실이야. 다른 머신에 있는 웹 서버 열 대가 같은 logical DB에 동시에 쓴다면 SQLite는 잘못 고른 도구야. '네트워크 프로토콜이 없다'는 성질은 양날의 검이거든.

Code

Latency 비교 — 로컬 SQLite·python
import sqlite3, time

# SQLite: open 거의 공짜, query 는 그냥 함수 호출
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE t(id INTEGER PRIMARY KEY, v TEXT)')
conn.execute('INSERT INTO t VALUES (1, "hello")')

start = time.perf_counter_ns()
for _ in range(10000):
    conn.execute('SELECT v FROM t WHERE id = 1').fetchone()
elapsed_us = (time.perf_counter_ns() - start) / 10000 / 1000
print(f'SQLite per query: {elapsed_us:.2f} µs')
# SQLite per query: ~3–10 µs

External links

Exercise

SQLite의 in-process 모델이 대놓고 이기는 제품 시나리오 세 개, 대놓고 아픈 시나리오 세 개를 적어봐. 각각 어떤 성질이 그 판단을 끌고 갔는지도 같이 써. 네트워크가 없다는 점인지, 인증 레이어가 없다는 점인지, 파일 시스템 권한인지, writer가 하나뿐이라는 점인지.

Progress

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

댓글 0

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

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