전체 글 37

[데이터 중심 애플리케이션 설계] 확장성과 부하

시스템 디자인에서 확장성은 "증가한 부하에 대처하는 시스템 능력을" 설명하는 데 사용하는 용어라고 한다. 그럼 확장성을 고려한 설계는 다양한 부하(load)를 고민해 보는 설계가 필요하다. 그럼 이 부하는 어떻게 표현할까? 부하 매개변수와 측정 방법부하는 부하 매개변수(load parameter)라고 부르는 몇 개의 숫자로 나타낼 수 있는데, 이러한 부하 매개변수에 대한 선택은 시스템 디자인에 따라 달라진다고 한다. 예를 들어, 웹 서버의 초당 요청 수, 데이터베이스의 읽기 대 쓰기 비율, 대화방의 동시 활성 사용자, 캐시 적중률 등이 될 수 있다. 그럼 부하가 생겼을 때, 시스템의 성능을 어떻게 검증할 수 있는 지도 알아봐야한다. 온라인 시스템에서 대표적인 부하 관련 지표로는 응답 시간(response..

시스템 디자인 2026.07.26

서로소 집합 자료 구조 (Union-Find Data Structure)

지난주 Leetcode Daily Problem의 테마는 Disjoint Set을 사용하는 문제가 많이 나왔었다. 그래서 이번에 개념을 확실히 정리해두려고 . Disjoint Set두 개의 겹치치 않는 집합(Set) 이 있다. 이런 집합을 Disjoint set이라고 부른다. 즉 공통 원소(Common Element)가 존재하지 않는 부분 집합(Subset)의 집합을 말한다. 그리고 Disjoint Set을 표현하기 가장 좋은 자료구조 중 하나가 Union-Find 자료구조다. Union-Find그럼 Union-Find 자료구조는 어떻게 Disjoint Set을 표현할까요? 제일 먼저 Union-Find는 보통 Tree 방식으로 표현이 됩니다. 그리고 세 가지 연산을 이용해서 Disjoint Set을 만..

Algorithm 2026.07.19

[Docker] 컨테이너와 이미지

개발을 하다보면 도커를 직·간접적으로 자주 사용할 일이 많았다. 이미 구축된 파이프라인에 코드를 푸시해 빌드할 때나, 로컬 환경을 프로덕션 환경과 똑같이 세팅하는 등 다양한 용도로 도커를 썼다. 예전에 도커에 대해 잠깐 공부 했을 때 '격리된 환경을 만들어서 버전 관리를 쉽게 해준다'는 것만 알고 있었지 어떤 원리로 작동 되는지는 잘 몰랐다. 그래서 이번 기회에 한 번 공부해봤다. 컨테이너 (Container)컨테이너에 대해 이해 하려면 리눅스 커널이 가지고 있는 격리 기능들에 대해서 먼저 살펴봐야 한다. 결국 컨테이너는 이 격리 기능들을 기반으로 만들어진 공간이기 때문이다. 대표적인 격리 기능은 Namespaces와 Control Groups (cgroups)가 있다.Namespaces: 각 시스템의 ..

백엔드 2026.07.12

DB 격리 수준(Isolation Level): Read Committed

DB 격리 수준(Isolation Level)은 크게 4가지로 나뉩니다. 오늘은 그중 하나인 "Read Committed"에 대해서 알아볼까 합니다. Multithreading많은 데이터베이스가 멀티스레딩 기반으로 이루어져있습니다. 아마 2026년 기준으로 PostgreSQL은 싱글 스레드로 알고 있지만, 유명한 DB 시스템인 MySQL, MS SQL, Oracle 등 멀티스레드 기반으로 만들어졌습니다. 그 말은 즉 Race Condtion이 발생할 수 있는 환경에 놓여있다는 거죠. Race Condition 종류와 SolutionDirty WritesDirty Writes는 아직 Commit 되지 않은 데이터에 쓰기(Write)을 하려고 할 때 발생합니다. 예를 들어서 Transaction A와 Tr..

자료구조 최적화: 해시맵과 배열

알고리즘 해답 중에 해시맵을 배열로 속도가 빨라지는 경우가 있어서, 그 부분을 기록으로 남길까 합니다. 왜 배열로 바꿨을 때 빨라질까?배열이나 해시맵이나 원소(Element)에 접근할 때의 시간 복잡도는 O(1)로 같습니다. 하지만 해시맵은 내부적으로 해시 함수를 거쳐야 하는 등 여러 오버헤드가 발생하기 때문에, 실제 연산 속도는 배열이 훨씬 빠릅니다.두 구조의 내부 접근 순서를 비교해 보면 다음과 같습니다.배열: Arr[Index] => 인덱스를 통한 메모리 주소 접근 => 원소 반환해시맵: Map.get(key) => 해시 함수(Hash Function) 연산 => 해시 값을 버킷 인덱스로 변환 => 해당 버킷 접근 => Collision 있을 시 연결 리스트나 트리 탐색 및 Key 동등성 비교 =>..

Algorithm 2026.06.08

자릿수 동적 계획법 (Digit Dynamic Programming)

최근 Leetcode Daily Problem에서 Dynamic Progrmming을 사용해야 되는 문제가 나왔습니다. Total Waviness of Numbers in Range II라는 문제로, 정해진 범위 내에 조건에 맞는 숫자가 몇 개가 있는지 찾아보는 문제였습니다. Brute Force로 쉽게 풀 수 있지만 범위가 너무 커지면 TLE (Time Limit Exceeded) 오류를 받게 되죠. 그래서 오늘은 이러한 범위 내에 특정 숫자들을 찾을 수 있는 알고리즘인 Digit Dynamic Programming을 소개합니다.Digit Dynamic ProgrammingDigit Dynamic Programming은 숫자의 가장 큰 자릿수(왼쪽)부터 작은 자릿수(오른쪽)로 순회하면서, 특정 조건을 ..

Algorithm 2026.06.06

데이터베이스: 트랜잭션과 ACID 원칙

트랜잭션(Transaction)트랜잭션은 DB에서 하나의 논리적 작업 단위(a unit of work)를 얘기합니다. 이 단위 안에는 한 가지의 요청(INSERT, UPDATE, DELETE 등)만 있을 수 있고, 여러가지 요청이 포함되어 있을 수 있죠. 이런 트랜잭션은 데이터의 무결성(Integrity)을 보장하기 위해서 ACID라는 특성을 가지고 있는데요. 오늘은 이 네 가지 특성에 대해서 알아볼까합니다. 원자성(Atomicity)원자성(Atomicity)은 한마디로 '전부 성공하거나, 아니면 아예 실행되지 않거나(All or Nothing)'로 정리할 수 있습니다. 예를 들어, 한 트랜잭션에서 100가지 종류의 음식을 저장한다고 가정해 봅시다. 99가지는 저장되었지만, 마지막 딱 1가지에서 오류가 ..

인덱싱(Indexing)은 DB를 어떻게 바꿀까?

"인덱싱(Indexing)은 DB 성능을 무조건 향상시킨다?" 이는 절반만 맞는 말입니다. 인덱스는 쓰기(Write) 작업 시 성능 저하를 야기하지만, 읽기(Read) 속도는 빠르게 만들어주기 때문입니다. 그렇다면 왜 이런 성능의 트레이드오프가 발생하는 걸까요? 이번 글에서는 인덱스의 작동 원리와 함께, 내 애플리케이션의 맞는 인덱싱 기법을 알아보겠습니다. 인덱싱(Indexing) 먼저 인덱싱은 왜 쓰는 걸까요? 인덱싱이 없는 DB에서 특정 데이터를 찾으려면 처음부터 끝까지 다 뒤져야 합니다. 이를 Full Table Scan이라고 하며, 보통 O(N)의 시간이 걸리죠. 인스타그램이나 구글처럼 데이터가 어마어마하게 많은 애플리케이션에서 매번 O(N)으로 데이터를 찾으려면 너무 느려질 겁니다.반면, 인덱스..

LLM 서버 만들기: Thread와 Process

개발자들은 고성능 서버를 구축할 때, 성능을 최적화 위해 멀티스레딩(Multi-threading)을 도입하거나 프로세스 간 통신(Inter-Process Communication)을 통해 속도를 최적화하기도 합니다. 전통적인 웹 서비스에서는 이것이 정답이었습니다. 하지만 LLM(거대 언어 모델) 연산을 위한 서버를 직접 만들 때도 이 법칙이 통할까요? 놀랍게도 전통적인 멀티스레딩과 IPC는 LLM 서빙 환경에서 심각한 병목을 일으키는 주범이 됩니다. 이번 포스트에서는 그 이유를 한 번 알아볼까합니다. 스레드의 컨텍스트 스위칭(Context Switching)보통 서버는 요청이 올 때마다 스레드를 할당하는 'Thread-per-Request' 모델을 자주 씁니다. 하지만 CPU와 GPU를 100% 풀 가동..

백엔드 2026.05.31

Race Condition과 Deadlock

개발을 하다보면 멀티쓰레딩을 쓰고 싶은 마음이 굴뚝 같은데, 경쟁 상태(Race Condition)이나 데드락(Deadlock) 등 여러 장애 때문에 조심하게 됩니다. 이번 포스트에서는 Race Condition과 Deadlock이 왜 발생하는지, 어떻게 하면 해결할 수 있는지 한 번 알아보겠습니다. 스레드 안전 (Thread Safety)Race Condition과 Deadlock에 대해 이야기 하기 전에 스레드 안전에 대해서 알아보겠습니다. 스레드 안전이란 "어떤 코드가 주어졌을 때, 그 코드가 스레드 몇 개에서 호출되든 이 스레드들이 어떤 순서로 호출되든 간에 상관없이 올바른 결과가 나오는 것"을 스레드 안전이라고 합니다. 간단히 말해서 항상 싱글 스레드이든 멀티 스레딩이든 항상 올바른 결과가 나와..

백엔드 2026.05.30