2019년에 소개된 io_uring은 Linux 커널을 위한 비동기 I/O 인터페이스입니다. 기존 인터페이스인 epoll/kqueue와 aio 대비하여 뛰어난 성능과 간결하고 직관적인 API 사용성을 제공합니다. io_uring은 비동기 I/O, 시스템 콜의 다중 배치 처리, 유연한 버퍼 관리 등을 통해 Linux I/O 모델의 중요한 발전 중 하나로 인정받고 있습니다.
주요 특징
동작 원리
io_uring은 사용자와 커널 간의 공유 메모리 내에 원형 큐 (queue rings)를 활용합니다. 제출큐 (Submission Queue)와 완료큐 (Completion Queue)로 구성된 이러한 큐를 통해 사용자는 여러 개의 I/O 작업을 스케줄링할 수 있습니다. 커널은 스케줄된 작업을 처리하고 그 결과를 완료큐에 반환하여 사용자가 결과를 처리할 수 있도록 합니다.
우수한 성능
io_uring은 사용자와 커널 간의 공유 메모리를 이용하여 Zero-Copy I/O를 지원합니다. 또한 사용자가 I/O 작업을 스케줄링할 때 필요한 모든 정보를 커널에 전달하고 커널 내에서 작업 완료를 관리함으로써 추가적인 사용자/커널 간 컨텍스트 스위칭(context switching)을 최소화합니다. 이로써 전통적인 동기 I/O에 비해 더 낮은 오버헤드를 가지게 됩니다.
간결한 인터페이스
기존의 epoll에서는 여러 개의 입출력 작업(multiplexing)을 위해 파일 디스크립터의 상태를 필터링해야 했습니다. 반면 io_uring은 더 간결한 사용 방식을 제공합니다. 사용자는 io_uring_enter() 함수를 호출하여 시스템 콜을 커널에 스케줄링하고 결과를 처리합니다. 이러한 방식은 Polling과 Interrupt-driven I/O를 모두 지원합니다.
epoll을 사용한 설정
1 | ... |
io_uring을 사용한 설정
1 |
|
생각
libuv에서도 io uring API를 사용할 수 있게 되었습니다. 현재는 파일 연산에 한정되어 있지만, io_uring을 지원하는 커널의 경우 파일 연산 처리량이 최대 8배까지 증가하는 것으로 확인되었습니다. 파일 연산이 많거나 파일과 네트워크 I/O 워크로드가 혼합된 시스템에서는 io_uring의 사용으로 비약적인 성능 향상이 가능할 것으로 보입니다. 이러한 잠재력을 고려하여 io_uring을 활용하는 것이 유용할 것입니다.