허재영

Software Engineer — Backend Systems & Domain Architecture

복잡하게 얽힌 도메인을 명시적이고 검증 가능한 구조로 풀어냅니다. 현실의 제약과 판단을 실행 가능한 모델로 옮기고, 기존 의미를 보존한 채 시스템을 바꾸는 일을 해왔습니다.

Backend systems · Domain architecture · Runtime & orchestration · Performance & observability

  1. 다른 사람이 확장할 수 있는 구조를 만듭니다.

    복잡한 규칙을 한 사람의 머릿속에 두지 않습니다. 책임과 경계를 나눠 새 요구가 기존 흐름을 흔들지 않게 만듭니다.

  2. 실행 순서를 코드 위로 드러냅니다.

    암묵적인 콜백보다 스케줄러, DAG, 큐처럼 읽고 검증할 수 있는 흐름을 선호합니다. 같은 입력은 같은 결과를 내야 합니다.

  3. 정확성을 설계 속성으로 다룹니다.

    trial, commit, rollback의 경계를 먼저 세웁니다. 실패한 시도가 중간 상태를 남기지 않도록 구조에서 막습니다.

  4. 도메인의 의미를 타입과 모델에 남깁니다.

    하드코딩된 분기를 정형 구조로 끌어올립니다. 데이터가 실행 단계로 내려가도 원래의 판단 근거와 계보를 잃지 않게 합니다.

  5. 먼저 관찰하고, 측정한 뒤 바꿉니다.

    프로파일과 추적 정보로 병목을 확인합니다. 복잡도를 정당화할 근거가 부족하면 이미 만든 코드도 되돌립니다.

절차형 계산 흐름을 16단계 DAG 엔진으로 전환

이전

계산 규칙과 실행 순서가 여러 절차에 얽혀 있어 일부 단계만 검증하거나 안전하게 교체하기 어려웠습니다.

전환 후

의존성을 명시한 16단계 DAG와 새 실행 모듈을 만들고, 기존 결과를 비교하면서 전체 워크플로를 전환했습니다.

  • 새 123개 파일 규모의 V2 모듈을 처음부터 설계하고 구현했습니다
  • 1,092개 수요 중 비교 가능한 964개 결과가 기존 엔진과 정확히 일치하도록 검증했습니다
  • 스냅샷 복원, 단계별 실행, 결과 비교, 롤백 경계를 함께 두어 전환 자체를 검증 가능한 작업으로 만들었습니다

12개 이벤트 소스를 하나의 결정적 스케줄러로 통합

이전

이벤트 소스마다 다음 실행 시각을 따로 계산했고, 조건문과 부수 효과가 섞여 전체 순서를 추적하기 어려웠습니다.

전환 후

채널 메타데이터와 단일 heap scheduler로 실행 순서를 모으고, 동률 규칙과 시간 단조성을 계약으로 고정했습니다.

  • 동일 시각 이벤트의 우선순위, 오래된 항목 정리, 재스케줄 규칙을 명시했습니다
  • 기존 동작과 테스트 결과를 유지하면서 순 코드 약 940줄을 줄였습니다
  • 스케줄링과 도메인 동작을 분리해 새 이벤트 소스를 같은 경계 안에서 추가할 수 있게 했습니다

God object를 15개 컴포넌트와 Facade로 분해

이전

3,800줄 클래스에 114개 속성과 여러 관심사가 섞였고, 프록시가 실제 상태 소유자를 가리고 있었습니다.

전환 후

상태를 15개 컴포넌트로 옮기고 명시적인 Facade를 통해 접근하게 만들어 소유권과 변경 경로를 드러냈습니다.

  • 한 번에 갈아엎지 않고 상태 회수, 호출부 전환, 프록시 제거 순서로 나눠 이행했습니다
  • ECS도 검토하고 구현했지만 조회 경로가 지나치게 간접적이라 판단해 더 단순한 Facade 경계로 조정했습니다
  • 새 기능이 코어의 내부 상태에 직접 결합하지 않도록 확장 지점을 분리했습니다

다중 자원 예약을 trial·commit·rollback 트랜잭션으로 재구성

이전

경로 중간에서 자원 하나를 잡지 못하면 앞서 바꾼 상태가 남아 다음 계산까지 오염시킬 수 있었습니다.

전환 후

경로 전체를 시험한 뒤 한 번에 확정하고, 실패하면 관련 상태를 모두 복구하는 예약 트랜잭션을 만들었습니다.

  • 자원별 제약과 경로 탐색을 분리하면서도 하나의 commit 경계에서 결과를 확정했습니다
  • 중첩된 경로와 부분 실패에서도 rollback 순서가 보장되도록 체인 단위로 상태를 추적했습니다
  • 이 계약은 이후 V2 엔진의 964/964 결과 동등성을 지키는 기반이 됐습니다

추적 가능한 엔진과 근거 있는 성능 판단

이전

핫패스의 로그 비용은 컸지만, 로그를 없애면 계산이 왜 그렇게 흘렀는지 확인하기 어려웠습니다.

전환 후

구조화된 trace를 엔진 전반에 통일하고, 운영 빌드에서는 컴파일 단계에서 제거되는 관찰 경계를 만들었습니다.

  • Python의 __debug__ 게이팅으로 개발 빌드의 추적성과 운영 핫패스 비용을 분리했습니다
  • 감이 아니라 프로파일 결과를 기준으로 자료구조와 반복 호출 비용을 줄였습니다
  • 효과가 약했던 비동기 로깅과 데이터베이스 병렬화는 복잡도를 남기지 않고 되돌렸습니다

최근 작업과 연구

Rust 결정적 시뮬레이션 엔진 개인 R&D · v0.1.0

정책과 물리 실행을 분리하고, 검증된 컴포넌트를 일반 목적 atom graph로 낮추는 비공개 개인 프로젝트입니다.

  • 정수 시간과 전순서 이벤트 큐로 같은 입력의 전체 event log가 byte 단위로 같도록 만들었습니다
  • 540개 테스트와 200개 생성 네트워크로 결정성, 수량 보존, Little's Law를 검증합니다
  • 준비 단계의 branch plan은 완성했으며 runtime lowering은 다음 단계라서 완료된 제품으로 표현하지 않습니다

Kubernetes 실행 경계와 이미지 공급망 1단계 병합

긴 계산을 웹 서버 프로세스에서 떼어내 실행마다 Kubernetes Job으로 격리하는 구조를 설계하고 실제 클러스터에서 검증했습니다.

  • 서버는 control plane으로 남기고 실행 상태와 산출물의 수명 주기를 분리했습니다
  • k3s 검증 중 12시간 만료 pull secret이 장기 운영을 막는 문제를 찾아 credential 경계를 다시 설계했습니다
  • immutable tag와 OCI label을 적용하고 이미지를 708MB에서 357MB로 줄였으며 후속 단계는 아직 진행 중입니다

도메인 IR과 실행 의미론 실험 단계

복잡한 계산 규칙을 token, action, scheduler로 분해해 더 작은 실행 언어로 표현하는 연구입니다.

  • 생산에 쓰는 V2와 분리해 실험 실패가 현재 시스템의 안정성에 영향을 주지 않게 했습니다
  • 단계별 결과보다 상태 변화의 의미와 검증 경계를 먼저 정의합니다
  • 실행 의미론이 닫히지 않은 부분은 숨기지 않고 blocker로 남깁니다

멘토링과 글쓰기

Python 심화 강좌 — 주니어 엔지니어 온보딩을 위해 쓴 시리즈입니다. 문법보다 객체 모델, 컨테이너, 제너레이터, 디스크립터가 왜 그렇게 동작하는지 설명합니다.

컴파일러, 리눅스, 컴퓨터 구조, Python 내부를 긴 호흡으로 정리합니다. 기술 블로그 보기 →

연락처

백엔드 시스템, 도메인 아키텍처, 런타임, 성능과 관찰 가능성에 관한 대화를 환영합니다.