비동기/ 동기가 뭐길래..
·
CS/OS
백엔드 개발을 하다 보면 동기(synchronous), 비동기(asynchronous)라는 말을 정말 자주 듣게 된다. 멀티플렉싱을 공부할 때도 그렇고, Spring을 쓰다 보면 “이건 동기로 할까, 비동기로 할까?” 같은 이야기를 계속 하게 된다. 그런데 막상 누가 설명해보라고 하면 어딘가 애매해진다. 대충은 아는 것 같은데, 정확히 말로 풀기는 어렵다. 그래서 이번에는 이 개념들을 한 번 제대로 정리해보려고 한다. 프로그래밍 관점에서 시작해서 I/O 관점, 그리고 백엔드 아키텍처 관점까지 이어서 보면서 동기와 비동기를 다시 정렬해보는 게 목표다. 이미 들어본 이야기들이 많겠지만, 이번 글에서는 “왜 이렇게 이해하는 게 맞는지”에 조금 더 집중해보려고 한다. 쉬운코드를 보면서 들었던 내용들을, 내 나름..
I/O Multiplexing: Reactor 와 Proactor (IOCP)
·
CS/OS
앞선 글에서는 select, poll, epoll을 중심으로 Reactor 패턴 기반의 I/O 멀티플렉싱을 살펴보았다. Reactor 모델에서는 커널이 “지금 I/O를 수행할 수 있다”는 준비 상태(ready) 를 알려주고, 실제 read() / write() 호출은 애플리케이션이 직접 수행한다는 특징이 있었다. 하지만 모든 운영체제가 이 방식만을 사용하는 것은 아니다. 특히 Windows 환경에서는 전혀 다른 접근 방식을 취하는데, 바로 Proactor 패턴이다. 이번 글에서는 Reactor와 대비되는 개념으로서 Proactor 패턴, 그리고 그 대표적인 구현체인 IOCP(I/O Completion Port) 에 대해 살펴본다.Proactor 패턴이란?Proactor 패턴의 핵심은 한 문장으로 정리할 ..
I/O Multiplexing: Select, Poll, 그리고 Epoll
·
CS/OS
Select 와 Poll 다시보기I/O 멀티플렉싱을 구현하는 방식에는 여러 가지가 존재한다. 그중 가장 오래된 방식이 select와 poll인데, 이들은 내부적으로 모든 소켓을 순회하며 상태를 확인하는 구조를 가지고 있어 성능상의 한계가 뚜렷하다. 이러한 특성 때문에 현대의 고성능 서버 환경에서는 앞서 설명한 방식들과 함께 잘 사용되지 않는 편이다. 저번에 non-blocking에서 멀티플렉싱 i/o에 대해서 설명할 때 나타낸 그림이다위 그림에서 나타난 방식 역시 엄밀히 따지면 select와 poll이 사용하는 구조를 그대로 따른다. 두 방식의 차이는 본질적인 동작 방식의 차이라기보다는 API 인터페이스와 내부 자료구조의 차이에 가깝다. 즉, 멀티플렉싱이라는 관점에서 보면 select와 poll은 거의 ..
Block I/O vs Non-Block I/O 무슨 차이지..?
·
CS/OS
동기/비동기 처리를 이해하기 위해 먼저 짚고 넘어가야 할 개념인 것 같아 I/O에 대해 정리해본다.I/O 개념 정리동기/비동기 처리를 이해하기 위해 먼저 짚고 넘어가야 할 개념이 바로 I/O다. 이를 정리해보자. I/O란 쉽게 말해 데이터의 입출력(Input/Output)을 의미한다. 우리가 알고 있듯이 운영체제(OS) 환경에서는 CPU가 데이터 연산을 담당하고, RAM은 데이터를 임시로 저장하며, 디스크는 영구 저장소 역할을 하는 등 각 구성 요소가 역할을 나누어 작업을 처리한다. 따라서 특정 작업을 수행하기 위해 데이터가 한 요소에서 다른 요소로 이동하게 되는데, 이때 발생하는 데이터 이동 과정을 I/O라고 한다.Block I/OBlocking I/O에서는 I/O 작업을 요청한 프로세스나 스레드가 해..
NoSQL은 뭐지? SQL을 안 쓰는 걸까
·
CS/DB
기존 RDB(Relational Database)의 한계관계형 데이터베이스(RDB)는 오랫동안 안정적인 데이터 저장소로 사용되어 왔다. 스키마가 명확하고, 트랜잭션과 정합성을 보장한다는 점에서 여전히 많은 시스템의 핵심 구성 요소다. 하지만 서비스 규모가 커질수록, RDB가 가진 구조적인 한계도 점점 분명해진다. 가장 먼저 마주치는 문제는 스키마 변경의 부담이다. 새로운 기능을 추가하면서 컬럼을 하나 더 넣어야 하는 상황이 생기면, RDB에서는 테이블 스키마 자체를 변경해야 한다.ALTER TABLE users ADD COLUMN profile_image_url TEXT; 데이터가 적을 때는 큰 문제가 되지 않지만, 이미 수백만 건 이상의 데이터가 쌓인 테이블이라면 이러한 스키마 변경은 락(lock)을 ..
DB 성능 문제, 구조를 나누는 것부터 시작하기
·
CS/DB
서비스를 운영하다 보면 데이터베이스의 크기는 자연스럽게 커진다. 사용자 수가 늘고, 로그와 이력 데이터가 쌓이며, 하나의 테이블에 수백만 건 이상의 데이터가 들어가게 된다. 이 시점부터는 단순히 “인덱스를 잘 잡으면 된다”는 접근만으로는 성능 문제를 해결하기 어려워진다. 테이블이 커질수록 읽기와 쓰기 비용은 증가하고, 인덱스 역시 함께 커지면서 쿼리 처리 시간이 점점 늘어난다. 이런 상황에서 데이터베이스 구조 자체를 나누는 전략이 필요해지는데, 그 대표적인 방법이 Partitioning, Sharding, 그리고 Replication이다.Vertical PartitioningVertical Partitioning은 컬럼(column) 기준으로 테이블을 분리하는 방식이다. 하나의 테이블에 너무 많은 컬럼이..