전체 글 195

RAG(Retrieval-Augmented Generation)?

RAG는 질문이 오면 관련 문서 조각을 먼저 찾고, 그 조각을 참고자료로 LLM에게 같이 넘겨서 문서를 근거로 답하게 하는 구조이다.RAG는 오픈북 시험이라 할 수 있다. LLM에 답변을 요청하기 전에 사용자 질문과 관련된 자료를 검색하고, 그 자료를 질문과 함께 전달한다. LLM은 전달받은 내용을 참고해 답변을 생성하게 되고 이 경우 모델이 사전 학습 과정에서 알지 못했던 내용도, 관련 자료가 검색되어 함께 제공되면 답변에 활용이 가능해진다. (이때 중요한 것은 모델에 전달되는 정보가 잘못된 정보가 전달될 경우 모델도 그 정보를 기반으로 답을 생성하여 잘못된 답변을 생성하는 문제가 발생할 수 있다. 때문에 적절한 관련 자료를 제공하는 것이 중요하다.)파이프라인 흐름RAG 파이프라인은 크게 두 가지 흐..

카테고리 없음 2026.09.24

github 계정 여러 개 설정하기

계정마다 SSH 키를 따로 만들고, 저장소 주소에 계정별 별칭을 붙이면 된다.(SSH 인증과 커밋 작성자 정보도 별개라 둘 다 설정해야 함)아래와 같이 설정할 예정. 개인회사SSH 키id_ed25519_personalid_ed25519_company호스트 별칭github-personalgithub-work저장소 주소git@github-personal:개인계정/저장소.gitgit@github-work:회사계정/저장소.git커밋 이메일개인 이메일회사 이메일Git 설정 파일 위치git 설정 파일은 적용 범위에 따라 시스템, 사용자, 저장소 설정으로 나뉜다. 저장소 안에서 설정한 값이 사용자 설정보다 우선하므로 회사 저장소에만 회사 이메일을 적용할 수도 있다.범위위치적용 대상시스템/etc/gitconfig맥의..

카테고리 없음 2026.09.23

MSA와 분산 트랜잭션 — Saga 패턴

MSA와 분산 트랜잭션 - Saga 패턴주문을 받고 결제한 뒤 재고를 차감하는 흐름을 생각해보면. 모놀리식 애플리케이션이라면 하나의 데이터베이스 트랜잭션으로 묶을 수 있지만, MSA에서는 주문·결제·재고를 서로 다른 서비스가 맡고 각자 데이터베이스를 관리하는 경우가 많다.이때 주문과 결제는 성공했는데 재고 차감에 실패하는 경우 앞에서 끝난 결제와 주문을 데이터베이스 롤백처럼 되돌릴 수는 없다. 이미 각 서비스가 자기 트랜잭션을 커밋했기 때문이다. 이러한 상황은 특히나 기존 모놀리식 구조로 짜여진 레거시 프로젝트를 MSA로 전환하는 과정에서 많이 나타난다. 이렇듯 MSA에서 분산 트랜잭션에 대해 어떻게 작업의 일관성을 유지할 지에 대한 부분은 주요하게 고려된다. 실제로 예전에 거대한 레거시 프로젝트를 MS..

JAVA 2026.06.26

데이터베이스 동시성 — 비관적 락과 낙관적 락

데이터베이스 동시성 — 비관적 락과 낙관적 락여러 사용자나 프로세스가 동시에 같은 데이터를 수정하려고 할 때 데이터가 어긋나는 동시성 문제가 발생한다. 이를 막기 위한 대표적인 방어 전략이 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)이다.문제 — 레이스 컨디션과 로스트 업데이트통제되지 않은 레이스 컨디션(경쟁 상태)이라는 환경 때문에, 로스트 업데이트(갱신 손실)라는 데이터 유실 사고가 발생한다. 즉 레이스 컨디션이 원인이고, 로스트 업데이트는 그 결과 중 하나이다.① 레이스 컨디션 (Race Condition, 경쟁 상태)두 개 이상의 스레드나 프로세스가 공유 자원(메모리, 데이터베이스 등)에 동시에 접근하여 값을 변경하려고 할 때 발생하는 문제다. 운영체제의 ..

DATABASE 2026.06.26

동시성 문제

동시성 문제 — 한정판 선착순 판매 시 발생 가능한 문제시스템에서 NFT를 발행하는데 이때 총 발행량을 200개로 고정되어 있었고, 특정 시각에 선착순으로 판매하는 드롭(Drop) 이벤트 형식이였다.이때에 실제 토큰 발행은 블록체인 상에서 이루어졌지만 매 요청마다 온라인 트랜잭션을 보내고, 컴펌을 기다리면 너무 시간이 많이 걸리고, 가스비도 감당하기 어려울 것이라고 판단되어, 선착순에 대한 판정을 백엔드에서 먼저 처리 후 확정된 경우에 민팅 트랜잭션을 수행하도록 했다.예시 코드)@Service@RequiredArgsConstructorpublic class NftDropService { private final NftDropRepository nftDropRepository; @Transact..

JAVA 2026.06.26

ThreadLocal과 OOM (Out of Memory) 발생

ThreadLocal과 OOM (Out of Memory) 발생시스템의 API 서버(Spring Boot 3.x, 내장 Tomcat 사용, Java 17) 환경에서 트래픽이 몰리는 피크 타임에 간헐적으로 서버 응답이 극도로 느려지다가, 결국 java.lang.OutOfMemoryError: Java heap space를 뱉고 컨테이너가 재시작되는 장애가 발생하였다.메모리 누수(Memory Leak)의 주범은 java.lang.ThreadLocal 내부에 쌓여 있는 UserContext 객체들이었다. 해당 UserContext는 사용자의 세션 정보, 권한, 장바구니 메타데이터 등 꽤 무거운 데이터를 담고 있는 객체인데, 이것들이 참조를 잃지 않고 힙 메모리의 70~80%를 점유하고 있었다.메모리 공간 차이..

JAVA 2026.06.26

트랜잭션 격리 수준 4단계

트랜잭션에서 격리 수준이란 여러 트랜잭션이 동시에 같은 데이터를 다룰 때, 한 트랜잭션이 다른 트랜잭션의 작업을 얼마나 볼 수 있는지(=얼마나 격리되는지)를 정하는 단계 설정을 의미한다. 격리 수준은 4단계로 나뉘며높일수록 안전하지만 느리고, 낮출수록 빠르지만 위험하다.트랜잭션 격리 수준이 존재하는 이유여러 트랜잭션을 완벽하게 격리하면(서로 영향을 0으로) 가장 안전하지만 동시 처리량이 바닥난다. 반대로 격리를 풀면 빠르지만 데이터가 꼬인다. 격리 수준은 이 안전성과 성능 사이의 트레이드오프를 조절하는 장치다.즉 격리 수준은 어떤 동시성 문제(이상 현상)를 허용하고 어떤 걸 막을 것인가를 정하는 것이라 할 수 있다. 격리 수준과 관련하여 3가지 타입의 이상 현상이 존재한다.이상 현상Dirty Read (..

DATABASE 2026.06.01

@Transactional 동작 원리 (feat. 롤백이 되지 않는 경우)

@Transactional은 프록시로 동작한다Spring의 @Transactional은 AOP(관점 지향 프로그래밍)를 기반으로 프록시(Proxy) 객체를 통해 동작한다. 해당 어노테이션이 붙은 메서드를 호출하면 원본 객체가 아닌 프록시 객체가 개입하여 트랜잭션을 시작한다. 비즈니스 로직이 정상적으로 완료되면 커밋을 수행하고, 로직 수행 중 RuntimeException 같은 언체크 예외가 발생하면 즉시 롤백 처리를 하여 데이터베이스의 정합성을 보장한다.프록시를 "사장님(본체) 앞에 앉은 비서"라고 생각하면 쉽다. 외부 요청은 일단 비서(프록시)를 거치고, 비서가 "이 일은 트랜잭션으로 묶어야겠네" 하고 앞뒤로 부가 작업(begin / commit·rollback)을 처리한 뒤 사장님에게 실제 일을 넘긴..

JAVA 2026.06.01

CI/CD + 모니터링 스택 구축

사설 이미지 저장소 — Harbor회사 내부에서 이미지를 관리하려면 사설 레지스트리가 필요하다. Harbor는 사용자별 권한 제어, 취약점 스캔 등을 제공하는 CNCF 프로젝트다. Helm으로 설치하며, LoadBalancer 타입으로 노출하고 스토리지는 openebs-hostpath를 연결한다.helm repo add harbor https://helm.goharbor.iohelm pull harbor/harbortar xvfz harbor-1.17.1.tgz && mv harbor harbor-1.17.1 && cd harbor-1.17.1cp values.yaml my-values.yaml# my-values.yaml 주요 수정 항목# expose.type: loadBalancer# expose.l..

기타/Kubernetes 2026.05.31

Helm으로 애플리케이션 배포하기

Deployment, Service, ConfigMap, PVC를 매번 따로 apply 하는 건 번거롭다. Helm은 이 리소스들을 하나의 패키지(차트)로 묶고, 환경별로 달라지는 값만 values.yaml로 관리하게 해주는 쿠버네티스 패키지 매니저다. Helm이 해결하는 문제애플리케이션 하나를 배포하려면 보통 여러 리소스가 한 세트로 필요하다. Helm 차트는 이 리소스들의 YAML 템플릿과, 거기에 끼워 넣을 변수를 담은 values.yaml의 집합이다. 템플릿은 그대로 두고 values만 바꾸면 dev/prod 환경의 DB 주소 같은 차이를 깔끔하게 관리할 수 있다.차트 구조Chart.yaml # 차트 메타 정보values.yaml # 기본 템플릿 변수charts/ #..

기타/Kubernetes 2026.05.31