본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Fly.io에서 LiteFS 시작하기

원문 보기 위키 갱신

LiteFS는 SQLite를 위한 분산 파일 시스템으로, 여러 Machine에 걸쳐 데이터베이스를 복제하고 쓰기는 단일 프라이머리(primary) 노드에서만 처리해요. 이 가이드는 Fly.io에서 LiteFS 클러스터를 구성하고 실행하는 전체 과정을 안내해요. 완전한 작동 예시는 litefs-example 저장소에서 볼 수 있어요.

출처: 문서

본문

개요 (Overview)

이 가이드는 Fly.io에서 LiteFS 클러스터를 구성하고 실행하는 단계를 안내해요. 완전한 작동 예시는 litefs-example 저장소를 참고하세요.

LiteFS 설치

의존성

litefs 바이너리는 자체 완결형(self-contained)이지만, LiteFS가 로컬 파일 시스템을 마운트할 수 있도록 fuse3 라이브러리를 설치해야 해요. 또한 Consul에 연결한다면 ca-certificates도 필요하고, 거의 확실히 sqlite 설치도 필요할 거예요. 설치는 패키지 매니저에 따라 달라지지만, alpine 기반이나 debian 기반 이미지의 Dockerfile에 추가할 수 있는 줄은 다음과 같아요:

# for alpine-based images
RUN apk add ca-certificates fuse3 sqlite
# for debian/ubuntu-based images
RUN apt-get update -y && apt-get install -y ca-certificates fuse3 sqlite3

LiteFS 설치

LiteFS는 애플리케이션과 함께 컨테이너 안에서 실행되도록 만들어졌어요. 공식 Docker 이미지에서 litefs 바이너리를 복사해 가져올 수 있어요:

COPY --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs

Docker에서 USER 명령으로 사용자를 바꾸는 대신, LiteFS는 root로 실행하는 것을 권장해요. 애플리케이션을 다른 사용자로 실행해야 한다면 su 명령으로 애플리케이션을 비-root 사용자로 실행하세요.

예시는 litefs-example 저장소의 예시 Dockerfile을 참고하세요.

LiteFS 구성

LiteFS의 대부분의 설정 옵션은 litefs.yml이라는 YAML 설정 파일로 지정해요. 이 파일은 보통 /etc/litefs.yml에 두지만, -config 플래그로 경로를 변경할 수 있어요.

litefs-example 저장소의 litefs.yml 파일에서 전체 예시를 보거나, 이 섹션의 나머지를 따라가며 더 자세한 설명을 확인할 수 있어요!

파일 시스템

먼저 LiteFS가 파일 시스템을 마운트할 위치와 내부 데이터를 저장할 위치를 알려주는 필드 두 개를 설정해요.

# This directory is where your application will access the database.
fuse:
  dir: "/litefs"

# This directory is where LiteFS will store internal data.
# You must place this directory on a persistent volume.
data:
  dir: "/var/lib/litefs"

Fly.io에서 실행한다면 볼륨을 만들어야 해요:

fly volumes create litefs --size 10

그런 다음 fly.toml에서 마운트로 지정하세요:

[mounts]
  source = "litefs"
  destination = "/var/lib/litefs"

리스 구성 (Lease configuration)

LiteFS는 특정 시점에 단일 노드만 *프라이머리(primary)*가 될 수 있어요. 프라이머리 노드만 데이터베이스에 데이터를 쓸 수 있어요. 다른 노드는 *레플리카(replica)*라고 하며 읽기 전용 복사본을 제공해요.

프라이머리는 분산 리스(distributed lease)로 결정돼요. 이 가이드에서는 높은 쓰기 가용성을 위해 프라이머리가 자동으로 장애 조치할 수 있게 해주는 Consul 리스를 사용할 거예요. 다음으로 앱에 Consul URL을 추가할 수 있어요:

fly consul attach

그러면 앱에 FLY_CONSUL_URL 시크릿이 설정되고, 여기에 클러스터 URL이 담겨요.

그런 다음 litefs.yml에 lease 섹션을 설정하세요:

lease:
  type: "consul"

  # Specifies if this node can become primary. The expression below evaluates
  # to true on nodes that are run in the primary region. Nodes in other regions
  # act as non-candidate, read-only replicas.
  candidate: ${FLY_REGION == PRIMARY_REGION}
  
  # If true, then the node will automatically become primary after it has
  # connected with the cluster and sync'd up. This makes it easier to run
  # migrations on start up.
  promote: true
  
  # The API URL that other nodes will use to connect to this node.
  advertise-url: "http://${FLY_ALLOC_ID}.vm.${FLY_APP_NAME}.internal:20202"

  consul:
    # The URL of the Consul cluster.
    url: "${FLY_CONSUL_URL}"

    # A unique key shared by all nodes in the LiteFS cluster.
    # Change this if you are running multiple clusters in a single app!
    key: "${FLY_APP_NAME}/primary"

자세한 내용은 설정 가이드의 [리스 관리][] 섹션에서 확인할 수 있어요.

프록시 구성 (Configuring the proxy)

LiteFS는 모든 쓰기가 프라이머리 노드에서 발생해야 해요. 즉 애플리케이션이 쓰기 요청을 현재 프라이머리로 리다이렉트해야 합니다. 또한 프라이머리에 쓰기를 하고 변경 사항이 그 레플리카로 전파되기 전에 레플리카에서 읽는 것도 가능해요.

대부분의 웹 애플리케이션은 LiteFS 내장의 얇은 프록시를 활용할 수 있는데, 이 프록시가 쓰기 리다이렉션과 레플리카 일관성 문제를 자동으로 처리해요. 이 프록시를 사용하려면 애플리케이션이 다음 규칙을 따라야 해요:

  • GET 요청은 절대 쓰기 작업(예: INSERT, UPDATE 등)을 수행하지 않아야 해요.

  • 클라이언트는 쿠키가 활성화되어 있어야 해요.

프록시를 구성하려면 설정 파일에 proxy 섹션을 설정해야 해요:

proxy:
  # Bind address for the proxy to listen on.
  addr: ":8080"

  # Hostport of your application - replace 8081 with whatever port
  # your application is listening on!
  target: "localhost:8081"

  # Filename of the SQLite database you want to use for TXID tracking.
  db: "my.db"

자세한 내용은 [프록시 구성 가이드][]에서 확인할 수 있어요.

LiteFS 실행

LiteFS를 시작하는 데 사용하는 주요 명령은 litefs mount예요. 이 명령은 FUSE 파일 시스템을 마운트한 다음 LiteFS 노드들이 서로 통신할 수 있는 API 서버를 시작해요. Dockerfile의 ENTRYPOINT로 사용할 수 있어요:

ENTRYPOINT litefs mount

슈퍼바이저로 실행하기

LiteFS는 단독으로 실행되거나 애플리케이션의 간단한 슈퍼바이저 프로세스 역할을 할 수 있어요. 슈퍼바이저로 실행하면 LiteFS가 클러스터에 연결된 후에 애플리케이션을 시작하도록 기다릴 수 있어요.

구성의 exec 섹션에 하나 이상의 명령을 지정할 수 있어요. lease.promote를 true로 설정하면 마이그레이션 스크립트를 후보(candidate) 노드에서만 실행하도록 지정할 수 있어요. 이는 후보 노드가 자동으로 프라이머리로 승격되어 마이그레이션을 실행한다는 뜻이에요.

exec:
  # Only run migrations on candidate nodes.
  - cmd: "rails db:migrate"
    if-candidate: true

  # Then run the application server on all nodes.
  - cmd: "rails server"

LiteFS 인스턴스 테스트

LiteFS가 마운트되면 SQLite 클라이언트나 sqlite3 CLI를 사용해 마운트 디렉터리의 데이터베이스와 상호작용할 수 있어요:

sqlite3 /litefs/my.db

LiteFS는 마운트의 루트에 있는 파일만 허용하며, 현재 서브디렉터리는 지원하지 않아요.

데이터베이스 가져오기

기존 데이터베이스가 있다면 litefs import 명령으로 가져올 수 있어요.

litefs import -name my.db /path/to/database

자세한 내용은 litefs import 문서를 참고하세요.

경고: LiteFS의 SQLite 데이터베이스는 SQLite 클라이언트를 통해서만, 아니면 litefs 도구를 통해서만 상호작용해야 해요.

데이터베이스를 복사해 넣기 위해 cp를 사용하지 마세요.

더 알아보기 (Learn more)