복원력이 있는 앱은 여러 Machine을 사용해요
이 가이드는 앱을 단일 호스트 장애에 강하게 만들기 위해 여러 Machine을 사용하는 방법을 설명해요. Fly Proxy의 autostop/autostart와 대기(standby) Machine 같은 플랫폼 내장 기능 덕분에 필요할 때만 여분의 Machine을 시작할 수 있어요. 단일 Machine에서 시작해 같은 리전에 Machine을 추가하고, 리전을 넘어 확장하는 각 계층의 장단점을 함께 살펴봐요.
출처: 문서
본문
**Fly Machines는 빠르게 시작하는 VM으로, Fly.io 플랫폼의 기본 컴퓨팅 단위예요. 각 Machine은 단일 물리 호스트에서 실행돼요. 그 호스트가 실패하면 Machine은 다운되고 다른 호스트에서 자동으로 다시 시작되지 않아요.**개요
앱을 단일 호스트 장애에 강하게 만들려면 앱 또는 프로세스당 최소 두 개의 Machine을 만들어 보아요. Fly Proxy autostop/autostart와 대기(standby) Machine은 플랫폼에 내장된 기능으로, 필요할 때만 여분의 Machine을 시작하는 데 사용할 수 있어요.
복원력: 왜, 언제
왜 복원력이 필요할까요? Machine은 훌륭하지만 언제나 그런 건 아니에요. 호스트가 실패하고, 리전이 어두워지고, 네트워크가 불안정해질 수 있어요. 앱이 단 하나의 Machine에서만 실행된다면, 그 어떤 장애도 다운타임을 의미해요. 하나 이상의 Machine을 실행하거나 리전에 걸쳐 분산하는 것이 바로 밑바닥 인프라가 흔들릴 때 불을 끄는 방법이에요.
언제 사용할까
사람들이 의존하는 무언가를 만들고 있다면, 아마 어느 정도 복원력이 필요할 거예요. 유료 사용자가 있는 운영 앱, 다운타임이 사람들을 화나게 하는 고객 대상 서비스, 또는 사용자가 어디에 있든 빠르게 응답해야 하는 글로벌 앱이 여기에 해당해요. 특정 지역에서 시스템을 계속 유지해야 한다는 규정 때문에 필요해질 수도 있어요.
언제 그만한 가치가 없을까
어떤 앱에게는 다운타임이 그렇게 중요하지 않아요. 사이드 프로젝트, 스테이징 환경, 내부 도구는 단일 Machine으로 충분히 잘 돌아갈 수 있어요. 위험이 낮다면 여분의 Machine을 추가하는 것이 오히려 필요 이상의 복잡도가 될 수 있어요.
성능
Machine은 시작하고 멈추는 게 정말 빨라요. 앱 사용자가 많거나 높은 사용량의 폭주가 있다면, Fly Proxy가 요청을 로드 밸런싱하고 앱에 가해지는 트래픽에 따라 Machine을 자동으로 멈추고 시작할 수 있어요. 더 빠른 첫 응답 시간이 필요하다면 하나 이상의 Machine을 항상 실행해 두어도 돼요.
비용
Machine이 실행 중이지 않을 때는 CPU와 RAM이 아니라 rootfs에 대해서만 비용을 지불해요. Machine rootfs는 저렴해요. 예를 들어 1.2 GB의 rootfs를 사용하는 평범한 Elixir 앱은 한 달에 약 18센트 정도예요.
서비스가 있는 앱을 위한 여러 Machine
Fly Proxy가 필요에 따라 시작하고 멈출 수 있도록 Machine을 더 추가할 수 있어요. 내장 복제가 있거나 데이터를 공유하지 않는 앱에 특히 좋아요.
첫 배포 시 두 개의 Machine을 얻어요
fly launch 또는 fly deploy 명령으로 앱을 처음 배포하면, fly.toml에 HTTP/TCP 서비스가 구성된 프로세스에 대해 똑같은 Machine 두 개를 자동으로 얻어요. Machine에는 autostop/autostart가 활성화되어 있어서 Fly Proxy가 앱에 가해지는 트래픽에 따라 시작하고 멈출 수 있어요. 0으로 확장한 뒤 fly deploy를 해도 이 기본 중복 Machine을 얻게 돼요.
직접 Machine 더 추가하기
앱에 autostop/autostart가 구성된 여러 Machine이 아직 없다면 직접 설정할 수 있어요. 사용자 수요를 충족하고 호스트 장애에 대한 중복(redundancy)을 제공하기 위해 원하는 수만큼 Machine을 만들 수 있어요.
1. autostop/autostart 설정하기
Fly Proxy autostop/autostart를 사용해 트래픽에 따라 Machine을 자동으로 멈추고 시작해 보아요. 원한다면 기본 리전에 하나 이상의 Machine을 계속 실행해 두어도 돼요. 예시 fly.toml 구성:
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = "stop" # Fly Proxy stops Machines based on traffic
auto_start_machines = true # Fly Proxy starts Machines based on traffic
min_machines_running = 0 # No. of Machines to keep running in primary region
[http_service.concurrency]
type = "requests"
soft_limit = 200 # Used by Fly Proxy to determine Machine excess capacity
Fly Proxy는 동시성 soft_limit을 사용해 Machine에 여유 용량이 있는지 판단해요. Fly Proxy autostop/autostart가 어떻게 동작하는지 자세히 알아보아요.
Machines API 사용하기: Machines API로 autostop/autostart 설정을 추가하거나 변경하려면, create 또는 update 호출에서 Machine 구성의 services 객체에 있는 설정을 사용해요.
2. Machine 더 만들기
flyctl을 사용해 Machine을 더 만들거나, 심지어 단 하나만 더 만들 수도 있어요:
fly scale count 2
아니면 하나 이상의 리전에 더 많은 Machine을 배포해 보아요:
fly scale count 20 --region ams,ewr,gig
Machine 수 확장에 대해 자세히 알아보아요.
Machines API 사용하기: Machines API로 Machine 수를 확장하려면 Machine을 "복제(clone)"할 수 있어요. Machine 구성을 가져와 수정하고 그 구성을 사용해 어떤 리전에든 새 Machine을 만들 수 있어요. Machines 리소스 문서를 참고해 보아요.
서비스가 없는 앱을 위한 대기 Machine
cron 같은 도구를 실행하고 로컬 스토리지가 필요 없거나 외부 요청을 받지 않는 앱이나 프로세스에서는 Machine을 하나만 실행하는 것이 흔해요. 이런 Machine에는 서비스가 구성되어 있지 않으므로 Fly Proxy가 자동으로 시작하거나 멈출 수 없어요. 이런 종류의 Machine에 호스트 장애에 대한 중복성을 추가하려면 대기(standby) Machine을 사용해 보아요. 대기 Machine은 멈춰 있다가 원래 Machine을 사용할 수 없게 되면 인수할 준비를 하고 있어요.
앱 트래픽에 따라 Machine을 시작하는 Fly Proxy autostop/autostart와 달리, 대기 Machine은 짝을 이루는 Machine을 지켜보다가 그 Machine을 사용할 수 없게 되었을 때만 시작돼요. 대기 Machine에 대해 자세히 알아보아요.
첫 배포 시 대기 Machine을 얻어요
fly launch 또는 fly deploy 명령으로 앱을 처음 배포하면, fly.toml에 서비스가 구성되지 않은(따라서 Fly Proxy에 보이지 않는) 프로세스에 대해 자동으로 대기 Machine을 얻어요. 그 대기 Machine은 실행 중인 원본 Machine의 복사본이에요. 0으로 확장한 뒤 fly deploy를 해도 이 대기 Machine을 얻게 돼요.
직접 대기 Machine 만들기
워커 Machine에 대한 대기 Machine이 아직 없다면 직접 만들 수 있어요.
워커 Machine이 다운되었을 때 같은 작업을 인수할 대기 Machine을 만들려면, 다음 명령 하나로 워커 Machine을 복제하고 복제본을 대기로 만드세요:
fly machine clone <worker machine id> --standby-for <worker machine id>
Machines API 사용하기: Machines API로 대기 Machine을 만들려면 워커 Machine 구성을 가져와 수정하고 그 구성을 사용해 새 대기 Machine을 만들어요. Machine 구성 객체에 대기를 지정하세요: config.standbys.
대기 Machine의 보너스 활용법
대기 Machine은 지켜보는 Machine의 복사본일 필요 없어요. 지켜보는 Machine을 사용할 수 없게 되면 어떤 이미지로든 실행되도록 대기 Machine을 구성할 수 있어요. 복구 스크립트 실행, 알림 트리거 등 무엇이든 할 수 있어요. 서비스가 있는 Machine을 포함해 어떤 Machine에든 대기 Machine을 만들 수 있어요.
다른 이미지로 대기 Machine을 만들려면:
fly machine run <image> --standby-for <machine-id>
여러 리전으로 확장하기
한 리전에서 여러 Machine을 실행하면 호스트 장애로부터 보호받을 수 있어요. 하지만 리전 전체가 실패할 수도 있어요. 정전, 네트워크 문제, 상류 제공자의 장애는 자주 일어나지 않지만, 일어나면 그 리전의 모든 Machine이 다운돼요. 앱이 그런 종류의 장애를 견뎌야 한다면 다음 단계는 리전을 걸쳐 분산하는 것이에요.
언제 사용할까
가동 시간(uptime)이 정말 중요할 때 멀티 리전 구성을 사용할 만해요. 엄격한 SLA가 있는 운영 시스템, 다운타임이 고통을 유발하는 고객 대상 앱, 사용자와 가까운 곳에서 응답성을 유지해야 하는 글로벌 서비스가 그런 경우예요. 특정 지역에서 인프라를 계속 운영해야 하는 경우 규정도 요인이 될 수 있어요.
예시
단일 명령으로 Machine을 둘 이상의 리전에 배치할 수 있어요:
fly scale count 6 --region ams,ewr,syd
이 예시는 암스테르담에 두 대, 뉴저지에 두 대, 시드니에 두 대를 실행해요. Fly Proxy는 사용자를 가장 가까운 정상 리전으로 라우팅해요.
중요한 주의사항 하나: 볼륨은 리전 간에 복제되지 않아요. 앱이 데이터를 쓴다면 그 데이터가 어디에 있고 어떻게 동기화되는지 신중하게 생각해야 해요. 흔한 접근법은 기본 "쓰기(write)" 리전을 하나 두고 나머지는 읽기 전용으로 취급하는 것이에요.
기억할 점
멀티 리전은 실질적인 장점을 주지만 트레이드오프도 있어요. 리전 Machine 근처의 사용자는 더 빠른 응답을 보겠지만, 특히 대부분의 앱이 글로벌 쓰기를 위해 설계되지 않았기 때문에 리전 간 데이터 조정은 어려워요. 그리고 중복성은 안정성을 높이지만 비용도 늘려요. 더 많은 장소에 더 많은 Machine은 더 많은 비용을 의미하고, 리전 간 트래픽도 빠르게 쌓일 수 있어요.
요약
복원력은 층층이 쌓여요. 바닥에는 단일 Machine이 있어요. 저렴하고, 단순하고, 깨지기 쉬워요. 같은 리전에 두 번째 Machine을 추가하면 호스트 장애로부터 보호받아요. Machine을 리전에 걸쳐 분산하면 사이트 전체를 쓰러뜨리는 정전에도 강해지고, 전 세계 사용자에게 더 빠른 응답이라는 보너스도 얻어요.
각 계층은 가용성을 높이지만 비용과 복잡도도 더해요. 올바른 선택은 무엇을 만들고 누가 그것에 의존하는지에 달려 있어요.
어떤 전략을 선택하든 연습해 보아요. 실제 정전이 발생할 때까지 앱이 어떻게 행동하는지 알기 위해 기다리지 마세요. Machine 하나를 멈추고 트래픽이 이동하는지 확인해 보아요. 리전 하나를 죽이고 데이터 계층이 어떻게 반응하는지 지켜보아요. 복원력 계획은 신뢰할 만큼 충분히 리허설했을 때만 효과가 있어요.
관련 읽을거리
Fly 앱이 어떻게 가용성을 유지하고 어떤 장애 모드를 기대해야 하는지 더 자세히 파고들고 싶다면, 다음이 좋은 다음 단계예요:
- App availability and resiliency: 앱을 하드웨어 장애나 정전 같은 이벤트에 더 강하게 만들 수 있는 모든 기능에 대한 개요예요.
- Multi-region with Fly-Replay: 사용자와 가까운 곳에서 읽기를 서빙하고 기본 리전으로 쓰기를 돌려보내는 방법이에요.
- Machine placement and regional capacity: Fly가 Machine을 어디에 배치할지 어떻게 결정하는지, 배치를 직접 어떻게 안내하는지, 리전의 용량이 소진되면 어떻게 되는지에 대한 내용이에요.
- Run Ordinary Rails Apps Globally: 스마트 라우팅으로 리전에 걸쳐 Rails를 분산한 프로젝트 수준의 예시예요.