Redis는 성능에 중점을 두고 개발되었습니다. 매우 안정적이고 빠른 제품을 경험할 수 있도록 모든 릴리스에 최선을 다합니다.
그럼에도 불구하고 Redis의 효율성을 개선할 여지를 찾거나 성능 회귀 조사를 추구하는 경우 Redis의 성능을 모니터링하고 분석하는 간결하고 체계적인 방법이 필요합니다. 이것은 이러한 최적화 중 하나에 대한 이야기입니다.
결국 우리는 스트림의 수집 성능을 약 20% 향상시켰으며, 이는 이미 Redis v7.0에서 활용할 수 있는 개선 사항입니다.
표준 SPEC
최적화를 시작하기 전에 최적화에 도달한 방법에 대한 높은 수준의 아이디어를 제공하고자 합니다.
이전에 언급했듯이 Redis 성능 회귀 및/또는 CPU 상의 잠재적인 성능 향상을 확인하고자 합니다. 그렇게 하기 위해 우리는 성과 및 관찰 가능성 요구 사항 및 기대와 관련된 모든 문제에 대해 기업 간 및 커뮤니티 간 표준 세트를 육성해야 할 필요성을 느꼈습니다.
간단히 말해서, 우리는 분기/태그별로 SPEC의 벤치마크를 지속적으로 실행하고 프로파일링 도구/프로버 출력 및 클라이언트 출력을 포함하는 결과 성능 데이터를 "제로 터치" 완전 자동화 모드에서 해석합니다.
사용된 도구는 모두 오픈 소스이며 memtier_benchmark, redis-benchmark, Linux perf_events, bcc/BPF 추적 도구 및 Brendan Greg의 FlameGraph 리포지토리와 같은 도구/인기 프레임워크에 의존합니다.
Redis에서 프로파일러를 사용하는 방법에 대한 자세한 내용을 알고 싶으시면 매우 상세한 “ 온 CPU 프로파일링 및 추적을 위한 성능 엔지니어링 가이드 .”
성능 향상을 위해 중복 계산 방지
이 첫 번째 단계가 주어지자마자 우리는 프로파일링 도구/프로버의 출력을 해석하기 시작했습니다. 흥미로운 패턴을 제시한 벤치마크 중 하나는 아래와 유사한 명령을 사용하여 데이터를 스트림으로 단순히 수집하는 Streams의 수집된 벤치마크였습니다.
`XADD 키 * 필드 값`.
우리는 ID가 없는 스트림에 추가할 때 SDS 생성/해제/sdslen에 대한 중복 작업을 생성하는 것을 관찰했는데, 이는 다음 두 개의 성능 보고서 인쇄에서 자세히 보여주듯이 CPU 주기의 약 10%를 차지합니다.
동일한 입력에 대해 sdscatfmt 및 _sdsnewlen이 두 번 호출되었습니다.
이를 통해 다음 벤치마크 결과에서 확인된 바와 같이 약 9-10%에서 스트림 수집을 최적화할 수 있었습니다.
불안정한 분기 기준( 6b403f5 ) :
이 PR의 첫 번째 커밋(중복 작업 방지):
성능 향상을 위해 중복 할당 방지
이 사용 사례 개선의 초기 초점은 CPU 주기의 또 다른 낭비를 발견한 Oran(코어 팀 구성원 중 한 명)의 추가 분석으로 이어집니다. 이번에는 동일한 코드 블록 내에서 최적화되지 않은 메모리 관리 때문이었습니다. 우리는 빈 SDS를 할당한 다음 다시 할당했습니다. 통화 수를 줄이면 아래와 같이 또 다른 속도 향상을 얻을 수 있습니다.
두 번째 커밋(재할당 방지):
측정된 개선
예상대로 단순히 중간 계산을 재사용하고 결과적으로 내부적으로 호출된 함수 내에서 중복 계산 및 할당을 줄임으로써 Redis Streams의 ~=20%에 달하는 전체 CPU 시간 감소를 측정했습니다.
우리는 이것이 Redis와 같이 이미 깊이 최적화된 코드의 경우에도 방법론적인 간단한 개선이 성능에 상당한 충돌을 초래할 수 있는 방법의 예라고 믿습니다.
우리의 목표는 Redis에 대한 성능 가시성을 확장하는 것이며 조직과 개인을 포함하여 업계와 학계의 구성원이 기여하도록 권장됩니다. 측정하지 않으면 개선할 수 없습니다.