리뷰 퀄리티 판단 엔진을 만든 과정
·
탐구 생활/LLM
지금 우리는 파운데이션 모델의 API 를 이용하는것만으로 AI를 이용할 수 있습니다. 이처럼 AI에 대한 접근성이 정말 높아졌는데요, 이런 흐름은 자연스럽게 제품에 놓아득어서 회사에서도 LLM 을 이용한 다양한 Feature 를 개발하게 되었습니다. AI를 이용해 리뷰를 요약하는 기능을 만들고, 리뷰의 감정을 분류하는 기능을 만들고, 그리고 이번 글의 주제가 되는 리뷰의 퀄리티를 판단 엔진을 만들었습니다. LLM을 이용하기 너무 편한 시대이다 보니 구현보다 중요해지는 요소는 LLM 판단 퀄리티에 대한 제어와 고객이 느끼는 가치입니다. 이번 글에서는 리뷰 퀄리티 판단 엔진을 만들면서 어떻게 LLM 판단 결과를 제어하고 고객이 느끼는 가치를 평가했는지에 대해서 다룹니다.도움이 되는 리뷰란?이커머스에서 리뷰에..
MySQL vs PostgreSQL 2편: UPDATE의 나비효과
·
탐구 생활/데이터베이스
MySQL vs PostgreSQL 1편에서는 MySQL의 Index-Organized Table(IOT)과 PostgreSQL의 Heap Table 구조를 비교하며, 데이터를 저장하고 읽는(Read) 방식의 근본적인 차이를 알아보았습니다. PostgreSQL은 무거운 데이터를 억지로 정렬하지 않고 힙(Heap) 공간에 마구잡이로 던져 넣은 뒤, 인덱스에서 물리적 주소(TID)로 다이렉트로 꽂아버리는 방식을 택했습니다. 읽기(Read) 관점에서는 트리를 두 번 타야 하는 MySQL보다 구조적으로 훨씬 명쾌하고 빨라 보였죠. 하지만 데이터베이스의 진짜 숙명은 조회가 아니라 끊임없는 '변경(UPDATE)'에 있습니다. 오늘은 데이터가 변경되는 순간, 평화롭던 PostgreSQL의 힙 구조에 어떤 거대한 나비..
MySQL vs PostgreSQL 1편: 데이터는 어떻게 저장되는가?
·
탐구 생활/데이터베이스
지난 글에서는 B+Tree의 원리를 통해 데이터베이스 인덱스가 디스크 I/O를 어떻게 획기적으로 줄여내는지 깊이 파헤쳐 보았습니다. 전 세계에서 가장 널리 쓰이는 RDBMS인 MySQL(InnoDB)을 기준으로 설명했었는데, 제가 실무에서 주로 다루는 PostgreSQL에 대한 설명이 부족해서 개인적으로 못내 아쉬웠습니다. 사실 MySQL InnoDB에 존재하는 클러스터링 인덱스(PK로 만들어진 B+Tree의 리프 노드에 실제 데이터가 예쁘게 정렬되어 저장되는 구조)는 PostgreSQL에는 존재하지 않습니다. 오늘은 PostgreSQL의 구루 히로노부 스즈키(Hironobu Suzuki)의 The Internals of PostgreSQL를 길잡이 삼아, 두 DB의 근본적인 저장 구조 차이와 읽기(Re..
B+Tree 구조와 데이터베이스 인덱스
·
탐구 생활/데이터베이스
스타트업에서 백엔드 엔지니어 실무를 하다보면 웹, 인프라/클라우드, 데이터베이스까지 폭 넓게 지식과 실무 경험을 쌓을 수 있다는 장점이 있습니다. 하지만 이렇게 일하다보면 "이건 왜 이렇게 돌아가는거지?" 하고 의문이 들 때가 있는데요, 오늘은 데이터베이스 그 중에서 인덱스가 왜 빠른지에 대해서 조금 깊이 알아보고자 합니다.그 유명한 B+Tree 구조에 대해서데이터베이스 인덱스에 대해서 이야기할때 가장 기본적이고 추상적인 설명은 이름 그대로 "데이터를 빠르게 찾기 위한 색인을 넣는 과정" 입니다. 하지만 실무를 어느정도 해본, 혹은 전공서적을 공부중인 학생이라면 이정도 설명으로는 충분하지 않습니다. 이 글의 조금더 깊이 알아본다는 주제를 충족하기 위해서는 우리는 대표적인 RDBMS 의 인덱스인 B+Tre..
스타트업에서 테크리더 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 의 또다른 함정을 명확히 정리..