스타트업에서 테크리더 1년을 회고하며
·
탐구 생활
스타트업에 테크리도로 합류한지 1년이 조금 지났습니다. 그곳에서 정말 멋진 사람들을 만났고 저에게 처음으로 대용량 트래픽에 대한 경험과 AI 프로젝트에 대한 경험을 할 수 있게 해주었습니다. 하지만 그것과는 별개로 처음으로 8명으로 이루어진 팀의 '리더' 역할을 소화하는 것과 그중 6명의 개발자들에게 '테크' 가이드 라인을 주는것은 정말 많은 고민과 땀으로 점철된 시간들이었습니다. 저의 지난 1년동안 기억에 남는 주요 이벤트 위주로 저의 고민과 행동을 작성해보았습니다. 테크리더라는 직무에 도전하시는 분, 그리고 새로운 테크리더를 맞이하시는 분들에게 조금이라도 도움이 되었으면 하는 마음으로 글을 적습니다.어떻게 테크리더라는 직무를 하게 되었나?제 경력은 조금 특이합니다.경제학과 4학년 1학기에 나름 데이터..
Python 과 Rust 를 이용해 1.8억건의 트래픽을 견디는법
·
탐구 생활/Python
지금까지 알던 기술 스택으로는 감당되지 않는 대규모 트래픽을 안정적으로 처리하는 것은 어려운 도전이지만, 동시에 개발자로서 가장 가슴 뛰는 경험이기도 합니다. 알파리뷰는 기존의 순수 Python 서버 환경에 Rust 생태계를 전략적으로 도입함으로써, 일평균 1.8억 건의 HTTP 요청을 처리하는 API 서버의 개수는 줄이면서도 시스템 안정성은 비약적으로 높이는 성과를 만들어냈습니다.이 글에서는 대규모 트래픽 환경에서 마주한 문제를 구조화하고, 병목의 근본 원인을 파악하기 위한 실험 과정, 그리고 새로운 아키텍처 도입에 따른 최종 성과까지의 전 과정을 공유하고자 합니다.1. 대규모 트래픽 문제 구조화하기프로덕트 마켓 핏(PMF)을 찾는 과정에서 민첩하게 개발된 시스템은, 트래픽이 급증하는 성장 궤도에 오르..
Django WSGI 최적화 - Granian 과 ARM64(Graviton)
·
탐구 생활/개발 탐구
이 글은 최근 Django WSGI 를 다루게 된 백엔드 개발자가 문제를 인식하는 과정, 실험을 통해 데이터를 확보하고 실제 성능과 비용을 최적화한 경험을 다룹니다. TL;DR공식문서를 따르는게 아닌 실제 운영 환경에 맞춰 파라미터를 튜닝하고, linux/amd64 를 linux/arm64 로 교체하여 Req/s 지표를 2배 높일 수 있었습니다.Gunicorn, gthread 기반 HTTP 서버를 Granian 으로 교체하여 부하 상황에서 발생하던 502 에러를 방지했습니다.1. 문제 정의 및 가설 수립"왜 우리 서비스만 Task가 70%나 더 많을까?" AWS 콘솔을 모니터링하던 중, 타 프로덕트 대비 비정상적으로 높은 ECS Task 수와 일일 최대 6만 건에 달하는 502 Bad Gateway 에러..
ORM의 편리함 속 함정 - SELECT *와 수직 분할의 중요성
·
탐구 생활
현대의 백엔드 개발자들(심지어 DB를 다루는 프론트엔드 개발까지)은 기본적으로 ORM(Object-Relational Mapper) 사용을 널리 받아들이고 있습니다. Python 생태계에서도 금쪽같은 Django의 ORM, 혹은 SQLAlchemy 가 있어서 Python 개발자들에게 정말 많은 편리함을 제공하고 있습니다. 하지만 "지옥으로 가는 길은 선의로 포장되어 있다" 라는 유명한 격언처럼, ORM 이 제공하는 편리함 속에는 함정이 숨어있습니다. 대표적인 문제인 N+1 현상은 널리 알려져있는 반면, 무심코 날리고 있는 SELECT * 쿼리와 Fat Model 문제가 성능에도 영향을 끼친다는 사실은 종종 무시 당하는것 같습니다. 성능에 집착하는 개발자 중 한명으로서 ORM 의 또다른 함정을 명확히 정리..
Python 과 zstd - middleware 적용하기
·
탐구 생활/Python 과 zstd
이 시리즈 첫글에서 Python 3.14 정식 배포 버전에서 zstd 알고리즘 native 지원에 더 눈길이 갔던 이유가 I/O Bounded API Server 의 응답속도 개선에 주의를 기울이고 있기 때문이라고 말했었습니다. 특히 지금 맡은 업무가 웹 브라우저와 직접적으로 상호작용하는 그렇다면 Python 으로 작성된 Web Server (FastAPI, Django) 에서 zstd 를 어떻게 사용할 수 있을지 공유하고자 합니다.전체 흐름 점검하기우선 가장먼저 드는 의문점은 누가 언제 무엇을 인코딩하고 디코딩하냐는 겁니다. 정말 다양한 기준이 있겟지만 웹서버를 기준으로만 정리해보겠습니다. 이제부터 말하는 클라이언트는 웹브라우저(PC / Mobile) 이며 서버는 웹 서버입니다. 그리고 주된 "흐름"..
Python 과 zstd - LZ77 과 허프만 코딩
·
탐구 생활/Python 과 zstd
25년 10월 7일, 추석 연휴가 한창일때, Python 3.14 정식 버전 (3.14.0) 이 배포되었습니다. 많은 Python 사용자들이 Free-Threaded 에 대해 이야기했습니다. 하지만 저는 Python Native zstd 압축이 지원된다는 사실에 더 관심이 갔습니다. 최근 I/O Bounded API Server 의 응답속도 개선에 관심을 기울이고 있었기 때문입니다. 이번 글에서는 본격적으로 zstd 압축 알고리즘을 알아보고 활용법을 탐구하기 전에 대표적인 무손실 압축 알고리즘인 LZ77과 허프만 코딩을 알아보겠습니다.대표적인 무손실 압축 알고리즘zstd 압축에 대해서 이야기하기에 앞서 현대 컴퓨터 시스템에서 압축 알고리즘의 근간이 되는 두 알고리즘을 살펴보겠습니다. 앞으로 설명할 gzi..
하나의 컨테이너에 하나의 프로세스
·
탐구 생활/개발 탐구
종종 하나의 Docker 컨테이너에 2개 이상의 프로세스를 Entrypoint의 Script 를 통해 실행하는 경우를 봅니다. 그리고 이러한 행태가 "전혀 문제 없는 방식" 이라고 말하는 사람도 만납니다. 이런 방식이 본질적으로 잘못된게 맞습니다. 어떤 점에서 잘못됐는지 알아보겠습니다.문제점gRPC 와 FastAPI 를 하나의 컨테이너에서 운영하는 경우를 예시로 들겠습니다.1. 운영 리스크를 키운다.서로 다른 프로세스 두 개를 하나의 컨테이너에서 운영하는 것은 운영 측면에서 리스크를 키웁니다.프로세스 생명주기: Docker는 PID 1 하나만 관리합니다. 추가로 띄운 자식 프로세스가 신호(SIGTERM/SIGINT)를 못 받아 좀비 프로세스가 남거나, graceful-shutdown 없이 강제 종료될 수..
가시성 (1) - 그 개념에 대하여
·
탐구 생활/개발 탐구
백엔드 개발자들끼리 이야기하다보면 "어떻게 모니터링하냐"는 주제는 반드시 등장하는 것 같습니다. 특정 기능을 만들어서 배포하면 마치 자식을 학교에 보내놓은 부모의 마음처럼 가서 친구들하고 잘 지내는지, 급식은 잘 먹었는지 궁금하지 않을 수 없기 때문입니다. 결국 대화는 가시성에 대한 내용으로 옮겨갑니다. 그러다 문득 내가 가시성을 과연 제대로 이해하고 있는게 맞나 궁금해졌습니다. 호기심이 동한김에 가시성에 대한 시리즈를 시작합니다.가시성가시성(observability)이란?가시성(Observability) 은 시스템이 스스로 내보내는 신호만으로 내부 상태를 재구성하고 특정 현상의 원인을 추론할 수 있는 능력을 뜻합니다. 처음엔 제어공학 용어였지만, 오늘날 소프트웨어, 클라우드 세계에서는 그 아래와 같은 ..