iBetter Books
수정

io_uring — 리눅스 비동기 I/O의 현재

epoll은 오랫동안 리눅스 고성능 서버의 왕좌를 지켰습니다. 하지만 기술은 멈추지 않습니다. 2019년 리눅스에 등장한 io_uring은 epoll의 한계마저 넘어서려는 새로운 시도입니다. 이 장은 io_uring의 발상을 개념 수준에서 소개합니다. 깊은 코드까지 들어가지는 않습니다. 이 기술이 왜 등장했고 무엇이 다른지를 이해하는 것만으로도, 고성능의 미래를 보는 눈이 열립니다.

io_uring은 리눅스 고유의 최신 기능이며 직접 다루려면 전용 라이브러리가 필요합니다. 이 장은 그 사용법을 가르치기보다 발상을 전하는 데 목적이 있으므로, 코드보다 그림과 비유로 설명합니다.

epoll에도 남은 아쉬움

epoll은 준비된 소켓만 알려 주어 C10K를 풀었습니다. 그런데 epoll에도 아쉬움이 남아 있습니다. epoll은 어디까지나 "준비됐는지"를 알려 줄 뿐, 실제로 읽고 쓰는 일은 우리가 따로 해야 합니다. epoll이 "이 소켓에 데이터가 있다"고 알려 주면, 우리가 recv를 불러 가져옵니다. 알림과 실제 작업이 분리되어 있는 것입니다.

이 분리에는 비용이 있습니다. 알림을 받는 것도, recv를 부르는 것도 각각 운영체제에 요청을 보내는 일입니다. 연결이 수십만 개에 이르면 이 요청을 주고받는 횟수 자체가 부담이 됩니다. 게다가 매번 데이터를 운영체제 영역에서 우리 프로그램 영역으로 복사하는 비용도 쌓입니다.

io_uring의 발상, 요청을 미리 쌓아 두기

io_uring의 발상은 신선합니다. 알림과 작업을 따로 하지 말고, 작업 자체를 미리 운영체제에 맡겨 두자는 것입니다.

이름에 담긴 링이 핵심입니다. 우리 프로그램과 운영체제가 두 개의 고리 모양 대기열을 공유합니다. 하나는 우리가 "이 일들을 해 달라"고 요청을 쌓아 두는 제출 대기열이고, 다른 하나는 운영체제가 "이 일들을 마쳤다"고 결과를 쌓아 두는 완료 대기열입니다. 식당에 빗대면, 주문서를 한 장씩 들고 가 알리는 대신, 주문서 묶음을 공유 선반에 올려 두면 주방이 알아서 가져가 처리하고 완성된 음식을 다른 선반에 올려 두는 방식입니다.

이 구조의 힘은 두 가지입니다. 첫째, 여러 작업을 한꺼번에 맡길 수 있어 운영체제에 요청을 보내는 횟수가 크게 줄어듭니다. 둘째, "준비됐는지 알려 달라"가 아니라 "읽어 달라"를 통째로 맡기므로, 알림과 작업의 분리가 사라집니다. 운영체제가 읽기까지 마쳐서 결과를 완료 대기열에 올려 주면, 우리는 그것을 가져가기만 하면 됩니다.

무엇이 달라지는가

io_uring은 소켓뿐 아니라 파일을 비롯한 거의 모든 입출력을 같은 방식으로 다룹니다. 그래서 단순한 epoll 대체를 넘어, 리눅스의 입출력 전체를 새로 그리는 시도로 평가받습니다. 잘 활용하면 epoll보다 더 적은 요청으로 더 많은 일을 처리할 수 있어, 극한의 성능이 필요한 곳에서 주목받고 있습니다.

물론 io_uring이 모든 것을 대체하는 것은 아닙니다. 비교적 새로운 기술이라 다루기가 까다롭고, 오래된 리눅스에서는 쓸 수 없으며, epoll로 충분한 경우도 많습니다. 다만 데이터베이스나 초고성능 네트워크 시스템처럼 마지막 한 방울의 성능까지 짜내야 하는 곳에서 점점 자리를 넓혀 가고 있습니다.

흐름을 읽는 눈

io_uring을 당장 쓸 일은 없을지 모릅니다. 하지만 그 발상을 아는 것은 중요합니다. select에서 poll로, poll에서 epoll로, 그리고 epoll에서 io_uring으로. 이 흐름을 따라가 보면 하나의 방향이 보입니다. 운영체제와 주고받는 횟수를 줄이고, 헛수고를 없애고, 작업을 더 크게 묶어 한 번에 처리하려는 끊임없는 노력입니다.

기술의 이름은 계속 바뀌겠지만, 이 방향은 변하지 않습니다. 그 방향을 읽을 줄 알면, 앞으로 어떤 새로운 도구가 등장해도 그것이 무엇을 풀려는 시도인지 금세 알아볼 수 있습니다. 그것이 저수준을 깊이 파 본 사람만이 가지는 안목입니다.

마지막으로 다음 장에서는 Python을 넘어 다른 언어들이 이 동시성 문제를 어떻게 풀었는지, 비동기 런타임의 지형도를 한눈에 그려 보겠습니다.