Rust

37 개의 포스트

discord4분 읽기큐레이션 요약

디스코드 패치

Discord의 2025년 2월 3일 패치에서는 Android 실행 속도, 미디어 업로드, 푸시 알림, 화면 공유 등 핵심 성능과 안정성이 크게 개선됐다. 특히 Media Proxy를 Go에서 Rust로 재작성해 지연 시간과 신뢰성을 높였고, 대규모 서버의 알림 전달 능력도 강화했다. 이와 함께 DM에서 앱을 실행하는 기능, 개인정보 보호 설정 개편, Android 레이아웃 문제 수정 등 사용성과 UI 관련 개선도 다수 포함됐다. ## 성능과 안정성 개선 - Android 앱 초기화 과정을 개선해 중앙값 기기 기준 실행 시간이 약 20% 단축됐다. - Media Proxy 서비스를 Go에서 Rust로 재작성했다. - 업로드 미디어를 처리하는 서비스의 평균 지연 시간이 약 22% 개선됐다. - 90퍼센타일 지연 시간은 40% 이상 빨라졌다. - 인프라를 최신 표준으로 현대화해 서비스 안정성도 향상됐다. - Android 13 이하에서 기기 회전과 화면 크기 계산 때문에 발생하던 레이아웃 붕괴 문제를 수정했다. - 푸시 알림 전달 신뢰성을 여러 달에 걸쳐 개선했다. - 2,500명 미만 서버에서는 30초 이내 전달 성공률이 99.98%에 도달했다. - Midjourney처럼 대규모 서버에서도 2,000만 명에게 약 15분 이내 알림을 보낼 수 있게 됐다. ## DM에서 앱 실행 지원 - 데스크톱 DM에서 Discord 앱과 활동을 직접 실행할 수 있게 됐다. - DM 목록 상단에 최근 사용한 앱을 빠르게 실행하는 바가 추가됐다. - 전체 친구 서버에 알림을 보내지 않고도 Chess in the Park 같은 활동을 개별 DM에서 이용할 수 있다. ## 개인정보 보호 설정 개편 - User Settings의 Privacy & Safety 메뉴를 새롭게 구성했다. - 변경 사항은 다음과 같다. - 탭 기반의 새로운 구조 - 관련 설정을 더 명확하게 묶은 그룹화 - 이해하기 쉬운 설명 - 향후 Trust 관련 설정을 확장하기 위한 구조 개선 - 기존 일부 환경에서 탭이 작동하지 않거나 잘리는 문제도 수정됐다. ## 데스크톱 및 운영체제 지원 - macOS 데스크톱 알림이 운영체제의 네이티브 API를 사용하도록 변경됐다. - Focus 및 방해 금지 모드가 메시지 알림음에 반영된다. - 같은 채널의 여러 알림이 그룹으로 표시된다. - 데스크톱 메시지 검색에서 `from:me`, `mentions:me` 자동완성을 지원한다. - Linux에서 Soundshare와 Wayland 화면 공유를 지원한다. - Ubuntu 22 이상에서 화면 공유 영상과 오디오 문제가 줄어든다. - 좁은 화면에서 친구 요청 버튼이 불필요하게 `...`으로 축약되는 문제를 개선했다. - 채널 주제를 클릭할 때 모달이 두 개 겹쳐 열리는 문제를 수정했다. ## 모바일 및 UI 버그 수정 - Android에서 채널 이름을 만들 때 글자가 중복 표시되던 문제를 해결했다. - Android의 친구 삭제 확인 모달과 토스트가 다른 UI 뒤에 표시되던 문제를 수정했다. - 키보드가 텍스트 입력창 위에 표시되어 입력 내용을 가리던 문제를 해결했다. - iOS에서 앱이 과도하게 축소되거나 검색 화면의 뒤로 가기 제스처가 작동하지 않던 문제를 수정했다. - 모바일 검색 결과의 전체 결과 수가 잘못 표시되던 변경을 되돌렸다. - 모바일에서 서버 초대 링크를 편집할 수 있게 됐다. - DM 옵션 버튼이 사용자 이름과 겹치는 문제를 수정했다. - 채널 권한을 카테고리와 동기화한 뒤 팝업에서 빠져나오기 어려웠던 문제를 해결했다. - Mutual Friends/Servers 화면에서 공유 항목이 없을 때 로딩이 끝나지 않던 문제를 수정했다. - 사용자 지정 상태 기간이 제대로 적용되지 않던 문제를 해결했다. - 푸시 알림에 사용자의 닉네임이 포함되도록 개선했다. ## 채널, 포럼, 검색 관련 수정 - 포럼 채널 태그 편집 UI의 스타일 문제를 수정했다. - 삭제된 이모지 때문에 무효화된 이모지 포럼 태그도 편집할 수 있게 됐다. - 채널 생성 화면에서 이모지를 추가할 때 클라이언트가 충돌하던 문제를 해결했다. - 이모지 선택기의 서버 필터에 현재 서버가 표시되지 않던 문제를 수정했다. - iOS 채널 검색 입력창이 텍스트 입력 중 올바르게 스크롤되도록 개선했다. - 모바일 검색 결과에서 뒤로 가기 스와이프가 작동하지 않던 문제를 해결했다. - 채널 세부 설정을 수정할 수 없게 만드는 권한 관련 문제를 수정했다. ## 상점, 퀘스트 및 프로필 개선 - 태블릿에서 Shop 배너 이미지가 늘어나 보이던 문제를 수정했다. - Shop의 구매 완료 모달, 반응 이모지 선택기, 내부 여백 관련 시각적 문제를 조정했다. - Quests 완료 항목이 많은 사용자에게 Claimed Quests UI가 더 안정적으로 표시되도록 개선했다. - Nitro Credit 사용자의 프로필 꾸미기 기능을 수정했다. - Android에서 Space Evader 프로필 효과의 애니메이션 문제를 해결했다. - iOS에서 이모지를 탭한 뒤 애니메이션이 멈추던 문제를 수정했으며, 사용자 지정 상태에서도 애니메이션 이모지가 정상 작동하도록 했다. - Discover Servers 아이콘에 닫을 수 있는 배지가 잘못 표시되던 문제를 해결했다. 이번 패치는 새로운 대형 기능을 추가하기보다 앱 실행 성능, 대규모 알림 인프라, 미디어 처리, 운영체제 통합을 강화하고 플랫폼별 자잘하지만 반복적인 UI 문제를 폭넓게 제거한 업데이트다. Discord를 사용하는 일반 이용자는 Android 업데이트, macOS 네이티브 알림, DM 앱 실행 기능을 우선 확인할 만하다.

원문 읽기(새 탭에서 열림)
datadog원문

정적 분석기를 Java에서 Rust로 마이그레이션한 방법 (새 탭에서 열림)

Datadog은 정적 분석 도구의 성능 병목 현상을 해결하고 제한된 CI 환경에서의 효율성을 극대화하기 위해 기존 Java 기반의 엔진을 Rust로 완전히 재작성했습니다. 이 과정에서 ANTLR 대신 Tree-sitter를 도입하고 JavaScript 규칙 실행 엔진을 GraalVM에서 Deno(V8)로 교체함으로써, 분석 속도는 3배 향상시키고 메모리 사용량은 10배 절감하는 성과를 거두었습니다. 결과적으로 이번 전환은 고성능 정적 분석을 위해 언어와 런타임 수준의 근본적인 변화가 필수적이었음을 보여줍니다. **Java 기반 정적 분석기의 한계와 환경적 제약** * **CI 자원 최적화 문제:** 고객의 CI 환경(예: GitHub Actions)에서 분석기를 실행할 때, 2코어 및 7GB RAM과 같은 제한된 자원 내에서 Java 분석기는 수천 개의 파일을 스캔하는 데 5분 이상 소요되어 목표치(3분 이내)를 충족하지 못했습니다. * **환경 충돌 및 오버헤드:** Java 기반 분석기는 최신 JVM(17+)을 요구하는데, 이는 고객의 기존 CI 환경에 설치된 Java 버전과 충돌을 일으키거나 불필요한 설정 부담을 주었습니다. * **파싱 성능 저하:** 기존에 사용하던 ANTLR은 대규모 저장소에서 파싱 속도가 느렸고, 특정 언어에 대한 지원이 부분적이라는 기술적 한계가 있었습니다. **Tree-sitter 도입과 Rust로의 전환 결정** * **파서 교체:** 성능 향상을 위해 C로 구현되어 속도가 빠르고 오픈소스 커뮤니티가 활발한 Tree-sitter를 채택했습니다. * **Java 라이브러리의 한계:** Tree-sitter용 Java 라이브러리는 분석기 최적화에 필수적인 패턴 매칭 기능을 지원하지 않는 등 기능이 제한적이었습니다. * **언어 선택의 기로:** Tree-sitter가 가장 견고하게 지원하는 언어가 Rust라는 점에 착안하여, 예측 가능한 성능을 위해 Rust로의 전체 재작성이라는 도전적인 경로를 선택했습니다. **Rust 기반의 새로운 아키텍처 구성** * **AST 구축(Tree-sitter):** Rust는 Tree-sitter 생태계의 "일등 시민(First-class citizen)"으로, 직접적인 라이브러리 연동을 통해 별도의 Java 바인딩 유지보수 없이도 강력한 파싱 기능을 확보했습니다. * **자바스크립트 규칙 실행(Deno):** 정적 분석 규칙은 자바스크립트로 작성되는데, 기존 Java의 GraalVM 대신 Deno(deno-core)를 런타임으로 도입했습니다. * **보안 및 효율성:** Deno의 V8 엔진을 활용하되, 분석 규칙이 디스크나 네트워크에 접근하지 못하도록 `deno-core` 크레이트만 통합하여 보안이 강화된 샌드박스 환경을 구축했습니다. **마이그레이션 결과 및 기술적 권고** 성공적인 Rust 전환을 통해 동일한 프로그램에 대해 Java 버전과 일치하는 분석 결과를 보장하면서도 성능은 3배, 메모리 효율은 10배 개선되었습니다. 특히 리소스가 제한된 CI/CD 파이프라인에서 정적 분석 도구를 운영해야 한다면, JVM과 같은 무거운 런타임보다는 Rust와 같이 저수준 제어가 가능하고 메모리 오버헤드가 적은 언어를 선택하는 것이 장기적으로 유리합니다.

datadog원문

.NET 연속 프로파일러: CPU 및 월 타임 프로파일링 (새 탭에서 열림)

Datadog의 .NET 컨티뉴어스 프로파일러는 CPU 사용량과 Wall Time(실행 시간)을 효과적으로 수집하기 위해 저수준 스레드 샘플링 방식을 채택하고 있습니다. 운영 환경의 부하를 최소화하면서도 정확한 데이터를 확보하기 위해 관리되는 스레드(Managed Threads)를 정밀하게 추적하며, 가비지 컬렉션(GC)과 같은 네이티브 스레드의 영향까지 함께 분석합니다. 이를 통해 개발자는 연산 집약적인 코드뿐만 아니라 I/O 대기 등으로 인한 지연 원인까지 심층적으로 파악할 수 있습니다. ### CPU와 Wall Time 프로파일링의 개념적 차이 * **CPU 프로파일링**: 스레드가 CPU 코어에서 실제로 실행되는 동안 소모한 사이클을 측정하여 연산량이 많은 코드 블록을 찾는 데 집중합니다. * **Wall Time 프로파일링**: I/O 대기나 락(Lock) 경합 등 스레드가 중단된 시간까지 포함하여 메서드 실행에 걸린 전체 시간을 측정하며, 요청 지연의 근본 원인을 파악하는 데 유용합니다. * **샘플링 방식 채택**: ETW(Windows)나 perf(Linux) 같은 도구는 높은 권한과 시스템 부하 문제로 운영 환경에 부적합하므로, 특정 주기로 스레드 스택을 관찰하는 샘플링 방식을 사용하여 성능 영향을 최소화합니다. ### 효율적인 스레드 모니터링 구조 * **관리되는 스레드 추적**: `ICorProfilerCallback`의 메서드들을 활용해 .NET 런타임이 관리하는 스레드의 생성 및 파괴를 실시간으로 모니터링하고 `ManagedThreadList`에 보관합니다. * **네이티브 스레드 오탐 방지**: 초기 구현에서는 C#을 사용했으나, 네이티브 스레드가 관리되는 메서드를 호출할 때 발생하는 예외적인 상황을 방지하기 위해 전체 구조를 C++로 작성하여 프로파일러 자체 스레드가 샘플링되는 문제를 해결했습니다. * **공용 익스포터 활용**: 수집된 샘플 데이터는 Rust로 작성된 고성능 익스포터를 통해 Datadog 백엔드로 전송되며, 이 모듈은 PHP, Ruby 등 다른 언어 프로파일러와 공유되어 안정성을 확보했습니다. ### OS 수준의 CPU 프로파일링 최적화 * **상태 확인 메커니즘**: 10ms마다 실행 가능한 스레드를 검사하며, Windows는 `NtQueryInformationThread`를, Linux는 `/proc/self/task/<tid>/stat` 파일을 파싱하여 CPU 소비량을 확인합니다. * **저수준 C 구현을 통한 성능 개선**: Linux 환경에서 `std::ifstream` 등 고수준 C++ 클래스를 사용할 때 발생하는 메모리 할당 오버헤드를 줄이기 위해, 할당이 없는 저수준 C API로 교체하여 전체 메모리 할당량의 8%와 CPU 사용량의 2%를 절감했습니다. * **GC 스레드 가시화**: .NET 5 이상의 환경에서는 프로파일링 API가 감지하지 못하는 서버 GC 및 배경 GC 스레드의 CPU 소비량을 별도로 계산하여 플레임 그래프에 표시함으로써 성능 간섭 현상을 명확히 보여줍니다. ### 분산 추적과 연동된 Wall Time 분석 * **Code Hotspots 기능**: 분산 트레이서와 연동하여 특정 요청(Span)을 처리 중인 스레드를 우선적으로 샘플링하며, 이를 통해 느린 요청의 원인이 되는 코드 경로를 정확히 짚어냅니다. * **P/Invoke 비용 최소화**: 트레이서가 프로파일러를 호출할 때 발생하는 오버헤드를 줄이기 위해, 스팬 ID가 기록되는 메모리 위치를 직접 공유하여 추가적인 API 호출 없이 데이터를 실시간으로 읽어옵니다. * **동적 샘플링**: 실행 중인 스레드가 많아질수록 샘플링 간격을 조절하여 데이터의 정확도와 시스템 부하 사이의 균형을 유지합니다. 이 프로파일러는 고성능 환경에서 안정적으로 동작하기 위해 C++와 Rust를 기반으로 저수준 OS API를 직접 제어하도록 설계되었습니다. 특히 Linux 환경에서의 파일 파싱 최적화나 트레이서와의 메모리 공유 방식은 대규모 트래픽을 처리하는 서비스에서 프로파일러 자체의 오버헤드를 극단적으로 줄여야 하는 개발자들에게 유용한 참고 사례가 됩니다.

figma원문

피그마가 게임 세계에서 (새 탭에서 열림)

피그마는 단순한 웹 애플리케이션을 넘어 고성능 게임 엔진과 유사한 기술적 아키텍처를 기반으로 구축된 창의적 협업 도구입니다. 이 글은 피그마가 실시간 멀티플레이어 시스템, 물리 기반 애니메이션, 그리고 C++와 WebAssembly, Rust와 같은 고성능 스택을 통해 어떻게 디지털 세계를 구축하는지 설명합니다. 결과적으로 피그마는 게임 개발의 복잡한 시스템 상호작용 원리를 차용하여 사용자들에게 몰입감 있고 매끄러운 디자인 경험을 제공하고 있습니다. ## 디지털 세계를 구축하는 엔진으로서의 피그마 * 피그마의 핵심은 웹 기반의 2D 그래픽 및 렌더링 시스템으로, 이는 마인크래프트와 같은 게임 엔진의 근간과 동일한 구조를 가집니다. * 사용자가 생성하는 모든 텍스트, 도형, 선을 브라우저에서 실시간으로 구현하며, 방대한 캔버스에서의 팬(pan)과 줌(zoom) 조작 시에도 정확한 위치에 객체를 렌더링합니다. * 실시간 동시 편집 기능을 게임의 개념에서 착안한 '멀티플레이어(multiplayer)' 엔진이라고 명명하여 협업의 핵심 시스템으로 발전시켰습니다. * 브라우저 및 모바일 앱의 메모리와 성능 제약을 극복하기 위해 일반적인 웹 스택 대신 C++로 캔버스를 구축한 후 WebAssembly로 컴파일하여 로딩 속도를 3배 개선했으며, 서버 측 성능 향상을 위해 Rust 언어를 도입했습니다. ## 시스템 기반의 창의적 협업과 상호작용 * 게임 스튜디오에서 엔지니어와 아티스트가 협업하듯, 피그마 엔지니어들은 시스템의 한계를 밀어붙이기 위해 디자이너, PM, 데이터 과학자들과 긴밀하게 소통합니다. * '젤다의 전설: 브레스 오브 더 와일드'의 불(fire) 시스템이 빛, 온기, 공격 수단 등 다양한 방식으로 상호작용하는 것처럼, 피그마의 오토세이브, 멀티플레이어, 렌더링 시스템도 서로 유기적으로 연결되어 작동합니다. * 단순한 도구 기능을 넘어 스프링 물리 법칙을 적용한 애니메이션 시스템, 커서 채팅, 하이파이브 기능 등을 통해 사용자가 도구 내에서 살아있는 피드백을 느낄 수 있도록 설계했습니다. * 베리언트(Variants) 기능과 플러그인/위젯 시스템을 통해 디자인 컴포넌트와 코드를 긴밀하게 연결하고, 사용자가 직접 생태계를 확장할 수 있는 개방형 플랫폼을 지향합니다. 웹 환경에서 복잡하고 성능 집약적인 도구를 개발해야 한다면, 전통적인 웹 프레임워크의 틀을 벗어나 게임 엔진의 설계 방식과 고성능 언어(WASM, Rust) 도입을 검토해야 합니다. 기술적 한계를 극복하는 열쇠는 도구를 하나의 살아있는 '시스템'들의 집합으로 바라보고, 각 요소 간의 상호작용이 사용자 경험에 미치는 영향을 정교하게 설계하는 데 있습니다.

datadog원문

Glommio 소개: Rust와 Linux를 위한 코어당 스레드 크레이트 (새 탭에서 열림)

현대적인 클라우드 비용 절감과 성능 최적화를 위해서는 단순히 코드의 병목점을 찾는 것을 넘어, 하드웨어 성능을 극대화할 수 있는 '코어당 스레드(thread-per-core)' 아키텍처로의 전환이 필요합니다. 이 아키텍처는 애플리케이션의 꼬리 지연 시간(tail latency)을 최대 71%까지 개선할 수 있지만, 구현이 복잡하고 개발 생산성을 떨어뜨릴 수 있다는 단점이 있습니다. Datadog은 이러한 문제를 해결하기 위해 Rust 개발자들이 코어당 스레드 모델을 쉽게 구현할 수 있도록 돕는 오픈소스 라이브러리 'Glommio'를 제안합니다. **기존 멀티스레드 모델의 한계와 비용** * 전통적인 멀티스레딩 방식은 여러 스레드가 동일한 데이터에 접근할 때 데이터 정합성을 보장하기 위해 락(Lock)을 사용하며, 이는 실행을 멈추고 대기하는 시간을 발생시켜 비용을 증가시킨다. * 스레드 간 컨텍스트 스위칭(Context Switching)은 약 5마이크로초의 비용이 드는데, 이는 io_uring과 같은 최신 커널 인프라의 I/O 처리 시간(4마이크로초 미만)보다 길다. 즉, 스레드 전환 비용이 실제 I/O 작업보다 비싸지는 역전 현상이 발생한다. * 기존의 비동기 프로그래밍 방식 또한 파일 I/O 등을 처리할 때 내부적으로 스레드 풀을 사용해야 하는 경우가 많아 완전한 효율성을 달성하기 어렵다. **코어당 스레드(Thread-per-core)의 동작 원리** * 각 CPU 코어에 단 하나의 스레드만 할당하고 이를 특정 코어에 고정(Pinning)함으로써, OS 스케줄러에 의한 스레드 이동과 컨텍스트 스위칭을 원천적으로 차단한다. * 하드웨어 인터럽트나 시스템 에이전트와 같은 외부 작업을 위해 특정 코어를 전용으로 분리하고, 나머지 코어를 애플리케이션 스레드에 할당하여 간섭을 최소화한다. * 모든 작업은 협력적 스케줄링(Cooperative Scheduling) 방식으로 동작하며, 실행 중인 작업이 명시적으로 제어권을 양보하거나 완료될 때까지 CPU를 점유하여 선점형 스케줄링의 오버헤드를 없앤다. **데이터 샤딩을 통한 락 프리(Lock-free) 구현** * 각 스레드가 전체 데이터의 특정 부분집합(Shard)만을 담당하도록 설계하여, 서로 다른 스레드가 동일한 데이터에 접근할 가능성을 차단한다. * 예를 들어 특정 카프카 파티션이나 데이터베이스 키 범위별로 담당 스레드를 지정함으로써, 스레드 간의 데이터 공유를 최소화한다. * 데이터 업데이트 작업이 해당 스레드 내에서 자연스럽게 직렬화(Serialized)되므로, 복잡하고 비용이 큰 락(Lock) 메커니즘 없이도 안전하게 데이터를 조작할 수 있다. **Glommio를 통한 Rust 애플리케이션 최적화** * Glommio는 C++의 Seastar 프레임워크와 유사한 철학을 Rust 환경에 가져와, 개발자가 코어당 스레드 아키텍처의 복잡한 세부 사항을 직접 다루지 않고도 고성능 애플리케이션을 작성할 수 있게 한다. * 성능 민감도가 높은 대규모 데이터 스토어(Datastores)나 고처리량 메트릭 수집 시스템을 운영하는 팀에게 Glommio는 하드웨어 효율성과 개발 편의성을 동시에 잡을 수 있는 실질적인 대안이 된다.

figma4분 읽기큐레이션 요약

피그마의 멀티플레이어

Figma는 Google Docs처럼 복잡한 OT(Operational Transformation)를 적용하는 대신, 디자인 문서의 구조에 맞춘 단순한 자체 멀티플레이어 시스템을 구축했다. 클라이언트와 서버는 WebSocket으로 변경 사항을 동기화하고, 서버가 문서별 단일 조정자로 동작해 충돌을 관리한다. 이 방식은 실시간 협업뿐 아니라 오프라인 편집과 재접속까지 지원하면서도 Figma의 데이터 모델에 맞는 구현 단순성을 유지했다. ## 웹 기반 협업을 선택한 이유 - 멀티플레이어 기능이 있으면 파일을 내보내거나 복사본을 이메일로 주고받고, 변경 사항을 수동으로 동기화할 필요가 없다. - 링크 하나만으로 여러 사람이 현재 디자인 상태를 확인할 수 있다. - 디자이너뿐 아니라 카피라이터, 개발자 등도 같은 문서에 참여할 수 있다. - 초기에는 실시간 협업이 “디자인을 망치는 기능”으로 여겨졌지만, 웹 생산성 도구에는 자연스러운 기본 기능이 되었다. ## Figma의 클라이언트·서버 구조 - 웹 클라이언트는 WebSocket을 통해 멀티플레이어 서버 클러스터와 통신한다. - 문서마다 별도의 서버 프로세스를 두고, 해당 문서를 편집하는 사용자들이 같은 프로세스에 연결된다. - 문서를 열 때 클라이언트가 먼저 파일 전체를 내려받는다. - 이후 변경 사항은 양방향 WebSocket 연결을 통해 실시간으로 전송된다. - 댓글, 사용자, 팀, 프로젝트 같은 데이터는 멀티플레이어 시스템이 아니라 Postgres와 별도 동기화 시스템으로 관리한다. - 문서 편집과 기타 애플리케이션 데이터는 성능, 오프라인 지원, 보안 요구 사항이 다르기 때문에 구현을 분리했다. ## 오프라인 편집과 재접속 - 사용자는 네트워크가 끊긴 상태에서도 임의의 시간 동안 계속 편집할 수 있다. - 다시 온라인이 되면 클라이언트는 서버에서 최신 문서 사본을 받는다. - 그 위에 오프라인 동안 발생한 로컬 변경을 다시 적용한다. - 이후 새로운 WebSocket 연결을 통해 서버와 변경 사항을 계속 동기화한다. - 연결과 재연결 자체는 단순하게 만들고, 멀티플레이어의 핵심 복잡성은 이미 연결된 문서에 동시에 변경 사항이 들어오는 상황에 집중했다. ## OT와 CRDT 대신 자체 방식을 택한 이유 - OT는 Google Docs 등에서 널리 사용된 표준적인 협업 알고리즘이다. - 여러 사용자의 동시 작업을 변환해 충돌을 해결할 수 있지만, 구현과 검증이 복잡하다. - Figma는 텍스트 편집기와 달리 계층적인 디자인 객체를 편집하므로, 일반적인 OT 모델을 그대로 적용할 필요가 없다고 판단했다. - 스타트업으로서 빠르게 기능을 개발하고 실험하려면 더 단순한 구조가 유리했다. - Figma는 디자인 문서의 데이터 구조와 편집 패턴에 맞춘 전용 동기화 방식을 만들었다. ## 프로토타입을 통한 설계 검증 - 실제 제품 코드에 바로 적용하지 않고, 여러 클라이언트와 서버를 시뮬레이션하는 별도의 웹 기반 실험 환경을 만들었다. - 프로토타입에서는 여러 사용자의 상태와 변경 사항을 시각적으로 확인할 수 있었다. - 오프라인 클라이언트, 느린 네트워크, 제한된 대역폭 등 다양한 상황을 쉽게 재현했다. - 이를 통해 협업 알고리즘과 데이터 구조를 빠르게 비교하고 실험했다. - 설계가 확정된 뒤 프로토타입에서 검증한 아이디어를 기존 코드베이스에 이식했다. ## 서버 중심의 동기화 모델 - 하나의 문서에 연결된 사용자들은 같은 서버 프로세스를 공유한다. - 서버는 문서에 들어오는 변경 사항을 순서대로 처리하고 다른 클라이언트에 전달한다. - 클라이언트는 처음 받은 문서 상태를 기준으로 로컬 변경을 수행하면서 서버의 업데이트를 계속 반영한다. - 서버를 문서의 조정자로 두면 여러 클라이언트가 서로 직접 충돌을 해결할 필요가 줄어든다. - 동시에 발생한 변경의 처리 순서는 서버가 정하며, 모든 클라이언트가 최종적으로 같은 문서 상태에 도달하도록 한다. ## 이 접근법의 핵심 장점 - 범용 협업 알고리즘보다 Figma의 객체 중심 데이터 모델에 맞게 단순하게 구현할 수 있다. - 온라인 편집뿐 아니라 오프라인 작업과 재접속도 지원한다. - 별도 프로토타입으로 다양한 장애 상황을 반복적으로 테스트할 수 있다. - 문서 편집 동기화와 서비스 메타데이터 동기화를 분리해 각각의 요구 사항에 맞게 최적화할 수 있다. 실용적으로는 모든 협업 애플리케이션이 OT나 CRDT를 그대로 도입해야 하는 것은 아니다. 데이터 구조가 명확하고 충돌 패턴이 제한적이라면, 서버 중심의 단순한 프로토콜과 충분한 시뮬레이션 테스트를 결합하는 편이 더 빠르고 유지보수하기 쉬울 수 있다.

원문 읽기(새 탭에서 열림)
figma3분 읽기큐레이션 요약

Mozilla의 Rust가 어떻게

Figma는 TypeScript 기반 멀티플레이어 서버의 예측 불가능한 지연 문제를 해결하기 위해 성능에 민감한 부분을 Rust로 재작성했다. Rust 프로세스를 문서별로 분리하고 병렬 처리한 결과, 메모리 사용량을 크게 줄이고 직렬화 성능을 10배 이상 개선했다. 다만 Rust 생태계와 언어 자체의 성숙도가 낮아 전체 서버를 Rust로 전환하지 않고 핵심 성능 영역에만 적용했다. ## TypeScript 서버의 확장성 문제 - Figma의 멀티플레이어 서버는 고정된 수의 머신과 워커로 구성되며, 각 문서는 하나의 워커에 전적으로 할당됐다. - 기존 서버는 TypeScript와 Node.js 기반의 단일 스레드 구조였다. - 문서 인코딩처럼 오래 걸릴 수 있는 작업이 실행되면 해당 워커 전체가 차단됐다. - 일부 대형 문서만 문제를 일으켰지만, 같은 워커에 연결된 다른 모든 문서의 동기화도 지연됐다. - 하드웨어를 추가해도 단일 워커 내부의 작업 차단 문제는 해결되지 않았다. - 문서마다 별도의 Node.js 프로세스를 실행하는 방식은 JavaScript VM의 메모리 오버헤드가 커서 현실적이지 않았다. ## 임시 대응과 한계 - Figma는 문제가 큰 문서를 별도의 “heavy worker” 풀로 수동 이동했다. - 이 방식으로 서비스 장애를 방지할 수는 있었지만, 문제가 되는 문서를 계속 찾아서 재배치해야 했다. - 문서 특성에 따라 운영자가 직접 관리해야 하므로 확장성과 자동화 측면에서 한계가 있었다. ## Rust 기반 아키텍처 - 성능에 민감한 멀티플레이어 서버 일부를 별도의 자식 프로세스로 분리했다. - 자식 프로세스는 Rust로 작성했으며, 기존 호스트 프로세스와 표준 입력(stdin)·표준 출력(stdout)으로 통신했다. - Rust 프로세스는 기존 시스템보다 메모리를 훨씬 적게 사용했다. - 그 결과 문서별로 별도의 프로세스를 실행해 모든 문서를 완전히 병렬화할 수 있었다. - 특정 대형 문서의 느린 작업이 다른 문서의 동기화를 차단하지 않게 됐다. - 문서 직렬화 시간은 기존보다 10배 이상 빨라졌다. ## 운영 성능 개선 - 점진적 배포를 통해 Rust 기반 시스템을 단계적으로 확대했다. - 전체 배포가 완료된 시점에 서버 성능 지표가 크게 개선됐다. - 개선 효과는 주로 서버 내부 성능에 해당하며, 클라이언트 기능 자체가 빨라졌다기보다 서버가 부하 상황에서도 안정적으로 동작하도록 만든 것이다. - 결과적으로 대형 문서나 느린 작업 때문에 전체 사용자가 겪던 동기화 지연과 서비스 품질 저하가 완화됐다. ## Rust를 선택한 이유 - Rust는 C++에 가까운 성능과 낮은 수준의 메모리 제어 능력을 제공한다. - 가비지 컬렉터가 없어 메모리 사용량과 지연을 더 세밀하게 제어할 수 있다. - 타입 시스템이 C++에서 흔한 여러 종류의 버그를 자동으로 방지한다. - 저수준 성능과 서버 언어 수준의 안전성을 함께 확보할 수 있다는 점이 선택의 핵심이었다. - 특히 기존 서버의 성능 문제 중 일부가 가비지 컬렉터와 관련되어 있었기 때문에 낮은 메모리 사용량이 중요했다. ## Rust 도입의 장점과 한계 - 장점 - 메모리 사용량이 매우 낮았다. - 가비지 컬렉터 없이 메모리 레이아웃을 세밀하게 제어할 수 있었다. - 문서별 Rust 프로세스 실행이 가능할 정도로 프로세스 비용이 작았다. - 높은 성능과 병렬 처리 구조를 구현할 수 있었다. - 한계 - 당시 Rust는 일반적인 서버 언어보다 훨씬 새로운 언어였다. - 언어와 생태계가 충분히 성숙하지 않아 여러 거친 부분이 있었다. - 처음 계획했던 전체 서버의 Rust 재작성은 포기했다. - 대신 성능에 가장 큰 영향을 주는 부분에만 Rust를 제한적으로 적용했다. Figma의 사례는 새로운 언어를 전면 도입하기보다, 병목이 명확한 핵심 컴포넌트만 별도 프로세스로 분리해 적용하는 전략이 현실적임을 보여준다. 특히 메모리 사용량과 지연 시간이 중요한 서비스에서는 Rust가 효과적이지만, 언어의 성숙도와 팀의 운영 역량을 고려해 점진적으로 도입하는 것이 바람직하다.

원문 읽기(새 탭에서 열림)