10P by GN⁺ | ★ favorite | 댓글 1개
  • libzstd-rs-sys는 Trifecta 재단의 zlib·bzip2 이후 세 번째 압축 프로젝트로, zstd의 첫 Rust 기반 릴리스임
  • Zstd는 현대 CPU에 맞춘 압축 형식으로 gzip보다 빠르고 압축률도 높아, 웹 트래픽에서 gzip을 점진적으로 대체할 것으로 예상됨
  • 기존 Rust zstd 크레이트는 C 코드를 소스에서 컴파일하므로 C 툴체인과 대상 지원이 필요해 Windows·WebAssembly 설정이 어려울 수 있음
  • Rust 구현은 드롭인 호환 C 라이브러리로 컴파일 가능하며, 테스트 스위트·퍼즈 테스트·Miri로 C 참조 구현의 대안을 검증 중임
  • 기본 압축 해제는 C보다 몇 퍼센트 느리지만, 약 3% 성능 저하는 메모리 안전성 비용이며 실험 플래그로 C 성능에 맞출 수 있음

첫 릴리스와 Rust 구현의 의미

  • Trifecta Tech Foundation은 zlib, bzip2에 이어 세 번째 압축 프로젝트로 zstd를 다루는 libzstd-rs-sys의 첫 릴리스를 발표함
  • Zstd는 현대 CPU를 염두에 두고 설계된 압축 형식으로, gzip보다 훨씬 빠르고 더 나은 압축률을 낼 수 있음
  • zstd는 이미 널리 쓰이고 있으며 웹 트래픽에서 gzip을 점진적으로 대체할 것으로 예상됨
  • Rust에서는 이미 zstd 크레이트로 zstd를 사용할 수 있지만, 기존 크레이트는 C 코드를 소스에서 컴파일하므로 대상용 C 툴체인과 대상 지원이 필요함
  • Windows나 WebAssembly용 C 툴체인 설정은 어려울 수 있어, 순수 Rust 구현은 Rust 개발자에게 더 나은 의존성 사용 경험을 제공함
  • libzstd-rs-sys는 zlib·bzip2 작업처럼 드롭인 호환 C 라이브러리로 컴파일할 수 있으며, C 참조 구현의 대안을 목표로 함
  • C 참조 구현은 Meta가 유지보수하고 기여 시 Meta와 기여자 계약을 체결해야 하므로, 독립적이고 성능이 좋으며 호환되는 구현이 오픈소스 생태계를 강화할 수 있음

검증, 성능, 남은 작업

  • 초기 참조 구현은 c2rust로 변환됐고, 이후 압축 해제와 딕셔너리 빌더의 정리 작업이 완료됨
  • Rust 코드는 C 정적 라이브러리로 컴파일한 뒤 참조 구현의 테스트 스위트로 검증됨
  • 퍼즈 테스트와 Miri도 구현 정확성을 검증하는 데 사용됨
  • 프리릴리스는 libzstd-rs-sys v0.0.1-prerelease.2에서 제공됨
  • 메모리 안전성의 비용

    • 기본 압축 해제 성능은 C 참조 구현보다 몇 퍼센트 느림
    • main에 병합되는 각 변경은 벤치마크 스위트에서 측정됨
    • unsafe-performance-experimental 기능 플래그를 켜면 C 성능과 일치함
    • 이 플래그는 입력 데이터가 자료구조 인덱싱에 쓰이는 4곳의 경계 검사를 비활성화함
    • 대부분의 사용자에게 약 3% 성능 저하는 향상된 메모리 안전성을 위한 수용 가능한 비용일 가능성이 큼
    • 마지막 성능까지 필요하다면 위험을 감수하고 해당 플래그를 켤 수 있으며, 이 4곳의 동작은 경계 검사를 하지 않는 C와 일치함
  • 압축 구현과 생태계 통합

    • 압축 부분은 아직 펀딩을 찾고 있음
    • 압축과 압축 해제 사이에 코드 공유가 있어 압축 코드도 일부 살펴봤지만, 대부분의 정리 작업은 남아 있음
    • 압축 성능 퇴보를 막기 위한 벤치마크가 설정됐고, 참조 구현의 테스트 스위트로 올바른 결과 생성 여부를 확인 중임
    • 남은 작업은 Milestone 4: Encoder implementation에 정리돼 있음
    • libzstd-rs-sys를 C 라이브러리 대신 사용하는 zstd 포크가 있으며, 향후 업스트림 반영을 원함
    • 가장 많이 쓰이는 API에서는 통합이 비교적 단순함
    • experimental 기능에서는 zstd-safe가 enum을 쓰지만 FFI 안전성을 위해 struct를 써야 하는 불일치가 있음
  • 후원

댓글과 토론

Lobste.rs 의견들
  • 정말 반가운 소식임. 며칠 전 의존성 하나 때문에 zstd 빌드를 하려고 libc-dev를 끌어와야 했고, 누가 Rust로 진지하게 재구현해 본 적이 있는지 궁금했음
    커뮤니티에서 널리 채택되면 좋겠음

  • WireGuard 기반 프로젝트를 Rust로 만들고 있어서 여러 Rust 암호화 라이브러리를 가져오고 있음. 메모리 안전성이라는 분명한 장점은 있지만, 오래된 C 라이브러리와 달리 전부 보안 감사를 받은 건 아님
    결국 궁금한 건 이런 알고리즘들을 Rust로 다시 쓰는 게 그만한 비용을 감수할 가치가 있느냐는 것임

    • 충분히 가치 있음. 암호는 알고리즘 자체가 깨지는 경우보다 구현 결함 때문에 우회되는 경우가 훨씬 많음
      파싱, 프로토콜 상태, 버퍼 관리 같은 “지루한” 비암호화 코드가 제대로 동작해야 시스템이 안전해짐. 공격자는 임의 코드 실행이 되는 마법 패킷을 보낼 수 있다면, 수천 년 걸릴 해독을 수십 년으로 줄이는 고급 암호분석이나 타이밍 부채널에 매달리지 않음
    • 프로젝트의 성능 요구가 너무 빡빡하지 않고 FFI를 조금 감수할 수 있다면, Rust에서 Go 암호화 스택을 쓰는 것도 가능함
      양쪽 모두 메모리 안전하고, 좁은 unsafe FFI 경계만 두면 된다는 장점이 있음. Go 암호화 라이브러리는 현재 Rust, 더 정확히는 crates.io 생태계에서 제공되는 것보다 더 성숙해 있음
  • -sys-rs-sys 접미사를 언제 써야 하는지 문서로 정리된 설명을 아는 사람이 있는지 궁금함. 직감으로는 -sys가 Rust로 작성되지 않은 시스템 라이브러리를 감싸는 crate용이라고 생각했음
    그런데 그 틀에서는 -rs-sys 접미사가 잘 이해되지 않으니, 내 직감이 틀렸던 듯함. 권위 있는 출처를 아는 사람이 있을까?

    • 이 패키지 이름은 상상 가능한 수준으로 거의 최악에 가깝게 지어졌음. 이름을 이루는 네 부분 중 세 부분이 틀렸거나 바람직하지 않음
      *-sys: 오래되고 널리 쓰이는 관례이며 https://doc.rust-lang.org/cargo/reference/… 에 설명돼 있음. 하지만 이 crate에는 전혀 맞지 않음
      lib*: 라이브러리라는 건 이미 알고 있고, Rust에서는 이 접두사가 관례적이지 않으며, 위 링크에서도 *-sys와 함께 반쯤 직접적으로 피하라고 짚고 있음. libzstd-sys라면 liblibzstd에 링크할 것으로 기대될 수 있음. 덧붙이면 Rust와 무관하게 실제로 이중 lib 이름을 본 적도 있음
      *-rs: https://rust-lang.github.io/api-guidelines/naming.html 에서 말하듯 “모든 crate는 Rust다! 사용자에게 계속 이것을 상기시킬 필요는 없다”
    • -sys crate들은 보통 매우 날것의 C식 인터페이스를 노출하고, 내부에 unsafe 코드가 많으며, 대개 외부 라이브러리를 빌드하거나 링크함
      -rs-sys 이름은 덜 일관되게 쓰이는 걸 봤음. Rust crate 안에 다시 포장된 외부 코드를 빌드하는 라이브러리, 예컨대 아직 C 부분이 남아 있는 미완성 Rust 구현이나 sys crate를 위한 Rust 지원 코드에 쓰이는 듯함
    • 나름의 논리는 있음
      libzstd는 원래 이름임. C 라이브러리는 이름에 lib를 포함하는 경향이 있고, Rust/Cargo 관례에 맞게 바꾸는 대신 참조용으로 그대로 둔 것임
      -rs는 Facebook의 C 구현과 구분하기 위한 Rust 재작성판 표시임. 여러 Rust 프로젝트에서 흔히 쓰는 일반 접미사이고, Python 라이브러리들이 pysomething 식으로 이름 짓는 것과 비슷함
      -sys는 이 구현이 unsafe C API를 노출하는 드롭인 대체품이기 때문임. Cargo 사용자 입장에서는 Rust 라이브러리가 아님. Rust 인터페이스가 없고, C 함수로 된 C 코드처럼 호출함
      그러니 -rs-sys가 아니라 libzstd-rs-sys 버전임
  • 왜 ruzstd보다 이걸 택해야 함? 기존 crate에 투자하는 편이 더 낫지 않을까?

    • ruzstd는 압축이 아직 완전히 구현되지 않았음
      1:1 포팅은 다른 코드베이스 위에서 똑같이 빠르고 완전한 압축기를 어떻게 만들지 다시 알아내는 대신, 비교적 곧은 코드 변환으로 비슷한 속도와 기능 동등성을 확보할 수 있게 해줌
  • “C 참조 구현은 Meta가 관리하며, 기여하려면 Meta와 기여자 계약에 서명해야 한다”
    최근에 알게 된 재미있는 사실인데, Facebook이 관리하는 참조 zstd 구현도 LLM으로 코딩되고 있고 openssl의 의존성이기도 해서, 대안이 더 많아지는 건 전적으로 찬성함

  • “기본 설정에서 우리 구현의 압축 해제 성능은 C 참조 구현보다 몇 퍼센트 느리다”
    이 프로젝트에 대해 알아야 할 건 이게 전부임

    • 그 문장이 어떤 의미로 다가왔는지 조금 더 설명해 줄 수 있을까?
      참고로 인용한 문장 바로 뒤에는 이런 내용이 이어짐
      “다만 unsafe-performance-experimental 기능 플래그를 켜면 C 성능과 같아지기 때문에, 이 성능 저하는 정당화할 수 있다고 봅니다. 이 플래그는 입력 데이터가 자료구조 인덱싱에 쓰이는 네 곳에서 경계 검사 4개를 비활성화합니다. 대부분의 사용자에게 약 3% 성능 저하는 메모리 안전성 향상을 위한 받아들일 만한 비용일 가능성이 큽니다. 정말 마지막 성능까지 필요하다면 본인 책임하에 이 플래그를 켤 수 있습니다. 이 네 위치에서의 동작은 경계 검사를 하지 않는 C와 같으며, 많은 프로덕션 시스템에서 문제없이 동작하는 것으로 보입니다”