mmap을 io_uring으로 바꿨더니 쿼리 엔진이 더 느려졌다
We Replaced MMAP with Io_uring in Our Rust Query Engine. It Got Slower

Conviva의 Evan Chan은 Rust 쿼리 엔진에서 mmap을 io_uring으로 교체했다. mmap은 동시 부하에서 페이지 캐시 스래싱과 커널 락 경합으로 p95가 30초에서 150초로 치솟았다. io_uring은 major fault를 35배 줄였지만 minor fault가 8배로 늘고 쿼리 시간이 13.6초에서 21.8초로 악화됐다.
mmap의 페이지 캐시는 암묵적인 공유 상태다. 호스트의 모든 프로세스가 하나의 캐시, 하나의 락 계층, 하나의 퇴출 정책을 공유한다.
HN 토론
22- jandrewrogers
여기서 문제는 mmap과 io_uring이 성능 맥락에서 근본적으로 다른 소프트웨어 아키텍처를 요구한다는 점입니다. 이 둘을 서로 바꿔 써서는 안 됩니다.
io_uring 같은 API는 O_DIRECT와 결합하면, 워크로드에 특화된 자체적인 유저스페이스 스케줄러를 처음부터 설계할 수 있게 해줍니다. 스케줄링을 런타임에 위임한다면, 그 API들이 제공하도록 설계된 성능상의 이점 대부분을 포기하는 셈입니다. 많은 경우 성능은 더 나빠집니다. 반대로 mmap은 모든 스케줄링 결정을 암묵적으로 위임하는데, 위임이 전략일 경우 런타임에 비해 몇 가지 이점이 있습니다.
io_uring의 이점은 자체 스케줄러를 설계하겠다는 결심 없이는 제한적입니다. 좋은 점은, 숙련된 스케줄러 설계자라면 이 API들을 사용해 mmap 대비 상당한 정수 배의 성능 향상을 얻을 수 있다는 것입니다. 애플리케이션 특화 스케줄러 설계는 쉽지 않고 고도의 기술이 필요한 작업입니다. 하지만 그 보상은 실재합니다.
io_uring을 잘 활용하려면, 그것이 보여줄 수 있는 잠재력을 끌어내기 위해 요구되는 소프트웨어 아키텍처에 모든 것을 걸어야 합니다.
- laserbeam
여기서 진짜 문제는 파트 2(글 끝에 링크됨)가 있다는 점입니다. 거기서는 io_uring 구현이 mmap보다 두 배 빠르게 나옵니다. 그러니까 파트 1을 위한 클릭베이트 제목이고, 파트 2에서 해결되는 셈이죠.
그래서 글을 두 편이나 뽑아냈는데, 그중 하나는 그냥 어그로용입니다. 그리고 둘 다 LLM이 쓴 것처럼 보입니다. 어쩌면 좋은 조언이 있을 수도 있고, 아닐 수도 있지만... 제가 즐겨 읽는 형식은 아닙니다.
- londons_explore
소프트웨어 엔지니어링에는 이런 패턴이 있습니다:
* 프로젝트가 존재한다
* 새 직원들이 효율성 개선 아이디어를 떠올린다
* 구현에 몇 달을 쓴다. 기존 코드 경로는 레거시가 된다.
* 새 것은 개발 중에 추가 기능들이 덧붙여진다.
* 새 것의 효율성은 원래보다 더 나쁘다는 게 밝혀지지만, 이제는 새 기능들과 '기술 부채 감소'가 동력이 된다.
* 새 것이 출시되고, 옛 것은 폐기되지만, 그 몇 달간의 작업에 실질적인 이득은 거의 없다.