Rust 시스템 프로그래밍은 이제 실험 단계를 지났다
11 views
# Rust 시스템 프로그래밍, 실험은 끝났다
## 반세기 동안 지불해 온 청구서
소프트웨어 장애 뉴스는 대개 비슷하게 시작한다. 어떤 서비스가 멈췄고, 어떤 데이터가 유출됐고, 원인은 조사 중이다. 그런데 조사가 끝나면 원인의 상당수가 놀랍도록 오래된 한 가지 범주로 수렴한다. 프로그램이 이미 반납한 메모리를 다시 건드리거나, 할당된 영역의 경계를 넘어 읽고 쓰는 실수. 메모리 안전성 결함이다.
이 결함은 특정 개발자가 태만해서 생기는 문제가 아니다. 운영체제, 브라우저, 데이터베이스 같은 시스템 소프트웨어는 반세기 가까이 C와 C++로 작성되어 왔고, 두 언어는 하드웨어를 직접 다루는 대가로 메모리 관리 책임을 전부 인간에게 넘긴다. 인간은 실수하고, 그 실수는 수백만 줄의 코드 속에 잠복했다가 취약점이라는 청구서로 돌아온다. Google이 공개한 분석으로는 한때 Android 시스템 코드의 심각한 보안 취약점 중 75%가 메모리 안전 문제였다. 문제의 규모가 언어 선택이라는 상류에서 이미 결정되고 있었던 셈이다.

대안이 없진 않았다. Java나 Go처럼 사용이 끝난 메모리를 런타임이 알아서 회수하는 가비지 컬렉터를 갖춘 언어들이다. 다만 이 장치는 회수할 때마다 프로그램을 잠깐씩 멈춰 세운다. 마이크로초를 다투는 커널이나 네트워크 스택, 실시간 시스템에서는 감당할 수 없는 세금이다. 그래서 시스템 프로그래밍 세계에는 오래된 통념이 자리 잡았다. 성능을 원하면 안전을 포기하고, 안전을 원하면 성능을 포기하라. Rust는 이 양자택일을 겨냥해 설계된 언어다.
2025년, Linux 커널의 Rust 도입을 이끌어 온 Miguel Ojeda는 "실험은 끝났다. Rust는 계속 남는다(The experiment is done, Rust is here to stay)"고 선언했다. 세계에서 가장 보수적인 코드베이스가 새 언어를 영구 구성 요소로 받아들인 것이다.
## 수치가 증언하는 프로덕션 가치
2025년 State of Rust Survey와 JetBrains 조사는 Rust 생태계 규모를 약 227만 명으로 집계한다. 취미 언어의 규모가 아니다. 이 규모를 견인한 건 대규모 인프라를 굴리는 기업들이 내놓은 정량적 성과였다.
보안 쪽 증거는 Google Android가 제공한다. 신규 코드에 Rust를 도입한 뒤 전체 심각 취약점 중 메모리 안전 결함 비율이 75%에서 20% 미만으로 떨어졌다. 밀도는 더 극적이다. 같은 분량 기준으로 Rust 코드의 취약점 밀도는 C/C++보다 1,000배 낮게 분석됐다. 취약점을 사후에 찾아 고치던 비용 구조가, 취약점이 애초에 컴파일되지 않는 구조로 바뀐 것이다.
성능 쪽에서는 Discord의 Read States 서비스가 대표적이다. 본래 Go로 작성된 이 서비스는 가비지 컬렉터가 주기적으로 일으키는 전체 정지(Stop-The-World) 구간 탓에 지연 시간 그래프에 규칙적인 스파이크가 찍혔다. Rust로 재작성하자 스파이크가 사라졌고, 상위 1% 요청의 지연을 뜻하는 P99 지연 시간이 50% 줄었다. 속도보다 중요한 건 예측 가능성이다. 런타임이 임의 시점에 끼어들지 않으니 최악 지연을 설계 단계에서 통제할 수 있다.
인프라 쪽에서는 두 사례가 나란히 선다. Cloudflare는 NGINX를 대체하는 자체 프록시 Pingora를 Rust로 구축해 CPU 사용량 70%, 메모리 사용량 67%를 절감했다. AWS는 Lambda와 Fargate의 기반인 경량 가상화 기술 Firecracker microVM을 Rust로 작성해 125밀리초 미만의 콜드 스타트를 달성했다. 이 정도 규모에서는 자원 절감이 곧 운영 비용이고 탄소 비용이다. 언어 선택이 취향이 아니라 손익계산서의 문제가 된다.

## 안전과 성능이 공존하는 기술적 토대
### 소유권과 빌림 검사기
Rust에서 모든 값은 정확히 하나의 소유자를 가지며, 소유자가 범위를 벗어나는 순간 값은 자동으로 해제된다. 다른 코드가 값을 쓰려면 빌려야 하고, 컴파일러에 내장된 빌림 검사기(Borrow Checker)가 모든 참조의 수명(Lifetime)을 정적으로 추적한다. 해제된 메모리를 가리키는 댕글링 참조도, 같은 메모리를 두 번 해제하는 이중 해제도 이 규칙 아래에서는 컴파일 자체가 거부된다. 가비지 컬렉터가 런타임에 하던 일을 컴파일러가 컴파일 타임의 증명으로 대체한 셈이다. 실행 시점 비용은 없고, 오류는 배포 전에 차단된다.

### 제로 비용 추상화
고수준 언어의 표현력은 보통 런타임 오버헤드를 동반한다. Rust의 제네릭 코드는 사용된 각 구체 타입마다 전용 코드를 생성하는 모노모피제이션(Monomorphization)을 거쳐 손으로 최적화한 것과 동등한 어셈블리로 변환된다. 이터레이터 체인 같은 추상이 기계어 수준에서는 단순 반복문과 구별되지 않는다. 추상화를 쓰지 않았을 때보다 느려지지 않는다는 이 원칙 덕에, C++의 성능 문화를 계승하면서도 표현력을 포기하지 않을 수 있었다.
### 동시성과 저수준 접근
Rust는 `Send`와 `Sync`라는 트레이트로 어떤 타입이 스레드 간에 안전하게 이동·공유될 수 있는지를 타입 시스템에 기록한다. 두 스레드가 동기화 없이 같은 데이터를 동시에 수정하는 데이터 레이스(Data Race)는 디버깅이 가장 어려운 버그 축에 들지만, Rust에서는 컴파일 오류로 강등된다. 이 기반 위에서 비동기 런타임 Tokio는 유휴 스레드가 바쁜 스레드의 작업을 가져가는 워크-스틸링(Work-Stealing) 스케줄러로 코어 활용률을 끌어올린다. 아래로는 C와의 상호운용을 위한 FFI 패턴이 기존 자산과의 점진적 공존을 허용하고, 표준 라이브러리 없이 동작하는 `#![no_std]` 환경에서는 Embassy 같은 프레임워크가 임베디드 기기에서까지 같은 비동기 동시성 모델을 돌린다. 커널에서 마이크로컨트롤러까지 하나의 안전 모델이 관통한다.
## 냉정한 대차대조표
Rust가 취약점을 끝장낸 건 아니다. 2025년에는 Microsoft Windows 커널의 Rust 코드에서 최초의 원격 코드 실행 취약점(CVE-2025-30388)이 나왔고, Linux의 Rust 기반 Binder 드라이버에서도 해제 후 사용(Use-After-Free) 취약점(CVE-2025-68260)이 보고됐다. 하드웨어와 FFI를 다루기 위해 검사기의 보증을 벗어나는 `unsafe` 블록이 존재하는 한 위험은 사라지지 않고 그 블록 안으로 압축된다. 역설적으로 이 사실이 Rust 설계의 타당성을 다시 보여준다. 감사해야 할 표면이 코드 전체에서 명시적으로 표시된 소수 구역으로 좁혀졌다는 것, 그게 이 언어가 주는 실질이다. `unsafe`의 엄격한 격리와 감사는 선택이 아니라 규율이다.
도입 비용도 실재한다. 모노모피제이션은 실행 속도를 사는 대신 컴파일 시간을 지불한다. 대형 프로젝트의 빌드 시간은 여전히 흔한 불만이고, 소유권과 수명 개념의 학습 곡선은 가파르다. 빌림 검사기와 싸우는 신입의 첫 몇 주는 거의 통과의례다. 다만 이 비용은 성격이 다르다. 런타임 장애로 지불하던 비용을 컴파일 타임과 학습 기간으로 앞당겨 내는 구조이고, 앞당긴 비용은 예측 가능하며 상환이 끝난다.
생태계는 아직 수렴 중이다. 비동기 진영에서는 async-std가 유지보수를 중단하면서 Tokio 중심의 사실상 표준화가 진행됐다. 표준 없는 분열보다는 나은 결말이지만, 비동기 자원의 정리를 언어 차원에서 보장하는 비동기 Drop(Async Drop)의 부재 같은 과제가 남아 있고, 2027 에디션을 향한 로드맵 논의에서 다뤄지고 있다.
## 규제와 아키텍처가 수렴하는 지점
이 전환은 더 이상 엔지니어링 조직 내부의 선택만이 아니다. 미국 CISA와 NSA, 백악관 ONCD는 메모리 안전 언어로의 이행을 공식 권고했다. 국가 기관이 특정 언어군을 지목해 산업 전반의 이행을 촉구한 일은 소프트웨어 역사에서 전례를 찾기 어렵다. 메모리 안전성이 개별 기업의 품질 문제를 넘어 사회 기반시설의 문제로 재정의된 것이다. DARPA의 TRACTOR 프로그램처럼 레거시 C 코드를 Rust로 자동 번역하는 연구도 진행 중이어서, 신규 코드만이 아니라 축적된 과거까지 이행의 사정권에 들어오고 있다.
Rust가 해낸 건 새 기능의 발명이 아니라 오래된 이분법의 해체다. 안전은 런타임의 감시로만, 성능은 안전의 포기로만 얻을 수 있다는 통념을 컴파일 타임의 정적 증명이라는 세 번째 길로 무너뜨렸다. 그 길이 커널과 클라우드와 임베디드에서 동시에 검증됐고, 규제 기관이 방향을 추인했다. 질문은 이제 Rust를 쓸 것인가가 아니라, 검증되지 않는 코드를 언제까지 신뢰할 것인가다. 표준이 된다는 건 예외를 정당화해야 하는 쪽이 바뀌었다는 뜻이다.