Rustls: 지속적인 벤치마킹 사례 연구

Everett Pompeii

Everett Pompeii


Rustls란 무엇인가요?

Rustls는 러스트로 작성된 현대적인 트랜스포트 레이어 보안(TLS) 라이브러리로, 메모리가 안전하지 않은 OpenSSL과 같은 대안을 대체하려는 목표를 가지고 있습니다. TLS 프로토콜은 보통 웹 서버와 클라이언트 사이의 안전한 통신을 제공하기 위해 사용됩니다. TLS는 이전에 Secure Socket Layer (SSL)이라고 불리웠습니다. TLS는 두 당사자 사이에서 전송되는 데이터가 암호화되어 있으며 도청이나 조작으로부터 안전하다는 것을 보장합니다. 따라서 Rustls와 같은 TLS 라이브러리가 빠르면서도 안전해야하는 것이 매우 중요합니다.

🐰 httpss는 이 페이지를 보기 위해 TLS를 사용하고 있다는 것을 의미합니다!

Rustls 벤치마킹

Rustls의 첫 커밋은 프로젝트의 창시자 Joseph Birr-Pixton이 2016년 5월 2일에 만들었으며, 첫 번째 성공적인 TLS 연결은 그달의 27일까지 이루어지지 않았습니다. 그 해 9월까지, 그는 이미 Rustls를 벤치마킹하고 있었습니다. 그의 허리에 상당한 성능 향상을 가지고, 그는 2019년 7월에 Rustls와 OpenSSL을 비교한 직접적인 벤치마크를 수행했습니다.

그 벤치마크 비교에서 나온 결과는 다음과 같습니다:

  • Rustls는 데이터를 전송하는 데 15% 더 빨랐습니다.
  • Rustls는 데이터를 수신하는 데 5% 더 빨랐습니다.
  • Rustls는 클라이언트 연결을 설정하는 데 20-40% 더 빨랐습니다.
  • Rustls는 서버 연결을 설정하는 데 10% 더 빨랐습니다.
  • Rustls는 클라이언트 연결을 재개하는 데 30-70% 더 빨랐습니다.
  • Rustls는 서버 연결을 재개하는 데 10-20% 더 빨랐습니다.
  • Rustls는 OpenSSL의 절반 이하의 메모리를 사용했습니다.

2023년에, 인터넷 보안 연구 그룹은 Rustls 프로젝트의 성능 벤치마킹을 지원했으며, 그결과 Rustls와 OpenSSL을 비교한 갱신된 직접적인 벤치마크 비교가 생겼습니다. 이러한 갱신된 결과들은 Rustls 프로젝트에 대해 강점과 향상할 수 있는 영역 모두에 대한 정보를 제공했으나, 가장 큰 성능 관련 문제는 이제 새로운 코드가 성능 회귀를 초래하지 않도록 보장하는 데 있습니다.

Rustls를 위한 지속적인 벤치마킹

성능 저하를 릴리스 되기 전에 잡기 위해, Rustls 프로젝트는 지속적인 벤치마킹에 투자하기로 결정했습니다.

지속적인 벤치마킹은 팀원들이 자주 자신의 작업을 벤치마킹하는 소프트웨어 개발 방법론이며, 보통 각 사람들이 하루에 적어도 한 번은 벤치마킹을 하기 때문에 하루에 여러 번의 벤치마킹이 이루어집니다. 각 벤치마킹은 자동화된 빌드에 의해 검증되어 가능한 빠르게 성능 저하를 감지합니다. 많은 팀들이 이 방법으로 성능 저하는 크게 줄였다는 것을 알게 되며, 이러한 접근 방식을 통해 팀이 보다 빠르게 성능이 우수한 소프트웨어를 개발할 수 있게 되었습니다.

Rustls 프로젝트의 지속적인 벤치마킹 해결책은 두 가지 주요 구성 요소로 이루어져 있습니다:

  • CI 벤치: CI에서 벤치마킹을 실행하기 위해 특별히 설계된 커스텀 벤치마킹 허니스
  • 벤치 러너: 커스텀, 베어 메탈 지속적인 벤치마킹 서버 및 동반 GitHub App

Rustls CI 벤치

CI 벤치는 최고 수준의 연속 벤치마킹을 위한 하네스입니다. 이는 두 가지 다른 모드에서 정확히 같은 벤치마크를 실행합니다: 명령어 수 모드와 벽시간 모드. 이것은 독창적인 맞춤형 비동기 런타임을 사용하여 이루어집니다. 명령어 수 모드에서는 I/O가 여전히 차단됩니다. 내부적으로, 작업은 단 한 번의 폴에서 완료됩니다. 그런 다음 벽시간 모드에서는 I/O가 실제로 비차단됩니다. 이를통해 공유되는 메모리 버퍼를 시뮬레이션할 수 있습니다. 서버와 클라이언트가 번갈아 폴링됩니다. 이를 통해 CI 벤치는 벤치마크에서 비동기 런타임의 노이즈와 비결정성을 제거할 수 있습니다.

Rustls는 CPU 명령어를 추적하기 위해 cachegrind를 선택했습니다. 이 결정은 Rust 컴파일러의 연속 벤치마킹 솔루션을 본따 만들었습니다. 명령어 수는 같은 소프트웨어의 두 버전을 비교하는 매우 일관된 방법을 제공합니다. 이로써 CI 벤치는 연속 벤치마킹에 이상적입니다. 그러나 명령어 수 증가의 실제 런타임 비용을 추론할 수는 없습니다. 명령어가 10% 증가하더라도 실행 시간 성능이 10% 증가한다는 것을 의미하지는 않습니다. 그러나 명령어 수의 큰 증가는 런타임 성능이 다소 증가했다는 것을 나타냅니다. 이런 이유로 CI 벤치는 벽시간도 측정합니다.

벽시간은 Rustls 프로젝트가 실제로 신경 쓰는 것입니다. 명령어 수를 측정하는 것은 단지 유용한 프록시일 뿐입니다. 명령어 수 기반 벤치마킹은 같은 수의 명령어를 사용하지만 완전히 다른 벽시간 성능으로 이어지는 변경사항을 구분할 수 없습니다. 예를 들어, 새 알고리즘이 정확히 같은 수의 명령어를 가지지만 두 배 느린 속도로 실행될 수 있습니다.

Rustls 벤치 러너

Rustls 벤치 러너는 사용자 정의 지속적인 벤치마킹 서버입니다. 이는 베어 메탈 호스트에서 실행되도록 설계되었고, 웹훅을 통해 동반 GitHub 앱으로부터 이벤트를 받습니다. main 브랜치에 푸시가 있을 때마다, 벤치 러너는 명령어 개수 및 벽시간 벤치마크를 모두 실행합니다. 결과는 로컬에 저장되고 Bencher API를 사용해 Bencher의 Rustls 프로젝트로 전송됩니다.

풀 요청이 승인되거나 Rustls 관리자가 @rustls-benchmarking bench가 포함된 코멘트를 남기면 벤치마크 세트가 실행됩니다. 벤치 러너는 GitHub에서 웹훅을 받고, 풀 요청의 코드를 가져와서, 명령어 개수 벤치마크를 실행하고, 벽시간 벤치마크를 실행하고, 풀 요청 결과와 대상 main 브랜치 결과를 비교하고, 그 후 결과를 풀 요청에 코멘트로 게시합니다. 벤치 러너는 성능 회귀가 발생했는지 여부를 판단하기 위해 통계적 임계값으로 Delta Interquartile Range 모델을 사용합니다. 이 임계치를 초과하는 결과는 풀 요청 코멘트에서 강조하여 표시됩니다.

베어 메탈 서버

월타임 벤치마크에 1%의 해상도를 얻기 위해, Rustls 프로젝트는 특별히 구성된 베어 메탈 지속적인 벤치마킹 서버에 투자했습니다. 대부분의 현대 CI 러너와 달리, 이 서버는 일시적이지 않습니다. 즉, 각 실행에 동일한 기본 서버 하드웨어와 운영 체제가 사용됩니다. 가상화는 없습니다.

베어 메탈 서버는 가능한 가장 일관된 결과를 생성하도록 특별히 구성되었습니다. 주파수 스케일링 (인텔의 TurboBoost) 및 동시다발적 멀티스레딩 (인텔의 Hyper-Threading)은 BIOS에서 모두 비활성화되었습니다. CPU 스케일링은 performance로 설정됩니다. 주소 공간 레이아웃 무작위화 (ASLR) 및 Non-Maskable Interrupt (NMI) 감시dog은 각각 sysctl.conf에서 kernel.randomize_va_space=0kernel.nmi_watchdog=0 설정으로 비활성화됩니다. 베어 메탈 서버는 OHVcloud에 의해 호스팅됩니다.

트로피 케이스

  • PR #1640: write_vectored에서 write로 전환을 평가하기 위해 Rustls 연속 벤치마킹 통합의 첫 번째 사용 중 하나입니다. 이 변경으로 Rustls의 송신 방향 전송 벤치마크가 일부 경우에 거의 20% 향상되었습니다.
  • PR #1730: TLS ClientHello 확장의 순서를 무작위로 변경할 때 성능 하락이 발생했습니다. 이로 인해 개발의 또 다른 반복과 더 효율적인 접근법의 사용을 초래하였습니다.
  • PR #1834: 중요한 보안 수정이 성능 하락을 도입하지 않았음을 빠르게 검증하는데 도움을 주었습니다. 이를 통해 팀은 여러 보안 패치 버전을 빠르게 출시하는 데 집중할 수 있었습니다.

마무리

프로젝트 창조자가 세운 기초 위에, Adolfo Ochagavía는 Rustls 프로젝트를 위한 놀랍게도 디테일한 연속 벤치마킹 솔루션을 구축했습니다. 이것에는 동일한 테스트에 대한 명령어 수와 벽시간 벤치마킹을 모두 실행하는 맞춤형 벤치마킹 하네스, 맞춤형 벤치마킹 러너, 맞춤형 GitHub 앱, 그리고 맞춤형, 전용 베어 메탈 서버가 포함됩니다. 이것은 가장 인상적인 프로젝트 특화 연속 벤치마킹 솔루션 중 하나입니다. 만약 당신의 프로젝트가 맞춤형 연속 벤치마킹 솔루션을 구축하고 유지하기 위한 시간과 자원을 가지고 있다면, Rustls 프로젝트는 목표로 하는 높은 기준을 설정합니다.

이 사례 연구를 검토해 주신 Adolfo Ochagavía에게 매우 특별한 감사를 표합니다. 그의 블로그 글인 Rustls를 위한 연속 벤치마킹 그리고 Rustls 성능은 이것의 내용의 기초였습니다.

Bencher: 지속적인 벤치마킹

🐰 Bencher

Bencher는 지속적인 벤치마킹 도구 모음입니다. 성능 회귀가 사용자에게 영향을 미친 경험이 있나요? Bencher가 그런 일이 일어나는 것을 막을 수 있었습니다. Bencher를 이용하면 성능 회귀를 상용 환경으로 이동하기 전에 탐지하고 예방할 수 있습니다.

  • 실행: 기존 벤치마킹 도구를 사용하여 로컬 또는 CI에서 벤치마크를 실행합니다. bencher CLI는 기존 벤치마킹 하네스를 감싸고 결과를 저장합니다.
  • 추적: 벤치마크 결과를 시간이 지남에 따라 추적합니다. 소스 브랜치, 테스트 베드, 측정 기반의 Bencher 웹 콘솔을 사용하여 결과를 모니터링, 쿼리, 그래프로 만듭니다.
  • 캐치: CI에서 성능 회귀를 잡아냅니다. Bencher는 최첨단, 사용자 정의 가능한 분석을 사용하여 상용 환경으로 가기 전에 성능 회귀를 탐지합니다.

단위 테스트가 CI에서 기능 회귀를 방지하기 위해 실행되는 것처럼, 벤치마크는 Bencher와 함께 CI에서 실행되어 성능 회귀를 방지해야 합니다. 성능 버그도 버그입니다!

CI에서 성능 회귀를 잡아내기 시작하세요 - Bencher Cloud를 무료로 시도해보세요.

🤖 이 문서는 OpenAI GPT-4에 의해 자동으로 생성되었습니다. 정확하지 않을 수도 있고 오류가 있을 수도 있습니다. 오류를 발견하면 GitHub에서 문제를 열어주세요.