지루한 코드로 10억 웹 요청 처리 - 만다라트 뷰
페이지 정보

본문
이 만다라트는 "지루한 코드로 10억 웹 요청 처리"에 대한 분석을 담고 있습니다.
만다라트 정보:
- 제목: 지루한 코드로 10억 웹 요청 처리
- 주제: Serving a billion web requests with boring code High level 2년 반에 걸쳐 미국 정부의 메디케어 플랜 비교·구매 웹사이트를 리드 개발함 일 평균 500만 API 요청을 처리, 평균 응답 속도는 10ms 미만, 95% 요청은 100ms 이하로 유지 장애 발생률이 매우 낮아 실제 엔지니어가 새벽에 호출된 사례는 한 손에 꼽을 정도 Postgres, golang, React 등 누구나 이해할 수 있는 검증된 기술로만 구성해, 꾸준히 안정적인 시스템을 구축함 Boring über alles 최우선 원칙은 '지루하고 검증된 기술' 만을 우선하는 것(** Choose Boring Technology**) 혁신 시도는 꼭 필요한 곳에서만 innovation token을 아껴서 사용 복잡하고 화려한 솔루션보다 안정적이고 명확한 기술과 프로세스를 선호 The boring bits Postgres: 데이터 저장의 핵심, 신뢰성과 확장성을 모두 만족. 복잡한 검색(페이시티드 검색 등)도 Postgres로 해결 golang: 빌드와 배포가 빠르고, 바이너리 산출물이 명확함. 에러 핸들링이 직관적이고, 새로운 팀원도 쉽게 적응 가능 React: SPA 프레임워크 중 가장 검증되어 있고, 팀원들이 이미 익숙했음. 접근성과 다양한 기기 지원도 중요한 고려 요소였음 장기적으로는 번들 크기와 속도 저하 이슈가 발생했지만, 당시 상황에서는 시간 내에 결과를 내기 위한 최적의 선택이었음 The innovation tokens Modular backend: 전체 백엔드를 마이크로서비스도, 모놀리식도 아닌 3개의 대형 모듈(druginfo, planinfo, beneinfo)로 구성 각 모듈은 별도의 Postgres DB를 사용하고, 데이터 공유는 오직 gRPC를 통해서만 이뤄짐 druginfo: 약국, 보험, 포장 등 조합이 기하급수적으로 늘어나는 약가 정보를 매우 정교하게 인덱싱하고, 복잡한 사전처리와 성능 최적화가 필요 planinfo: 매일 새로운 CMS 데이터를 수신해, DB 전체를 새로 만들어 사용함(불변성 유지) beneinfo: 실제 가입자 정보를 보관하는 유일한 부분으로, 민감한 PII(개인정보)는 최소한만 저장. 데이터 유출 리스크 최소화를 위해 설계와 운영에 신경 씀 gRPC: 모듈간 통신 인터페이스를 코드로 명확히 정의할 수 있는 장점. 자동화 도구와 연동성이 뛰어남 단, 빌드·툴링·디버깅은 복잡하고, JSON API 대비 직관성이 떨어지는 단점도 경험 grpc-gateway를 통해 웹클라이언트 지원 및 대량 트래픽을 무리 없이 처리함 Strict backwards compatibility API 및 데이터베이스의 하위 호환성 유지를 엄격하게 지킴 공개 API의 필드는 절대 삭제하지 않고, 보안 문제가 있지 않는 한 평생 유지 DB 컬럼도 추가는 자유롭지만 삭제는 여러 단계 검증(참조 제거→몇 주 대기→실제 삭제) 절차를 거침 이 규율이 높은 변화 속도와 안정적인 배포·운영의 핵심 기반이 됨 Faceted search ElasticSearch 대신 Postgres만으로 페이시티드 검색 구현 well-indexed plan 테이블에 조건을 조합하는 250줄 함수 하나로 모든 검색 로직을 처리 비즈니스 요구에 집중, 불필요한 복잡성 없이 단순하게 해결함 Database creation DB 스키마를 숫자가 붙은 .sql 파일로 관리, 순서대로 로딩하여 신뢰성 보장 planinfo/beneinfo DB는 매일 재생성, 마이그레이션 필요 없음. 버전 불일치 등 설정 오류 시 앱 자체를 아예 시작하지 않도록 설계 ETL 데이터 소스별 셸 스크립트로 S3에 적재 → cron으로 EC2 인스턴스가 최신 ETL 코드/데이터 가져와 신규 RDS DB 생성 Postgres의 COPY 구문을 적극 활용, INSERT 대신 대량 데이터 적재를 효율적으로 처리 매일 2~4시간이면 수억 행 데이터를 새 DB로 전환 가능 models xo 라이브러리로 DB 모델 자동 생성, 커스텀 템플릿으로 팀에 맞는 코드 생성 testing 가장 큰 실수는 sqlmock을 활용한 테스트를 과하게 만들어 데이터가 자주 바뀌는 상황에서 유지보수가 매우 번거로움 실제 불변 DB라면 실DB에 대한 테스트가 더 효율적이었을 것 Local database for development 각 테이블의 부분 데이터를 자동 생성하는 스크립트로, 개발자별로 작은 로컬 DB로 실제 데이터 기반 테스트와 개발 가능 DB가 커지기 전에 이런 도구를 마련하면 전체 팀 개발 효율이 극대화됨 Miscellaneous tooling 각종 운영·관측 자동화를 위해 CLI 도구를 셸 스크립트로 구현, 모든 유틸리티 기능을 하나로 모아 관리 splunk 로그를 Slack 명령어로 바로 그래프로 시각화하는 등 현장 중심의 도구를 적극 개발·활용 Logging 요청 진입 시점에 request id를 생성, 그 id가 모든 로그 컨텍스트에 붙어서 어디서든 추적 가능 zerolog로 안전하고 체계적인 로깅 설계 시스템 입구·퇴출, 예외 상황 등 중요 시점마다 필수 로그 남기기 Documentation GitHub markdown 문서를 sphinx-book-theme으로 변환해 위키북으로 운영 팀원 모두가 적극적으로 문서화에 기여, 한 곳에서 모든 시스템 문서를 찾을 수 있도록 함 뛰어난 문서화 문화가 팀의 성장과 유지보수, 신입 온보딩 효율을 크게 높임 Runtime integrations 클라이언트의 성능 저하 요청(분석 스크립트 삽입 등)은 최대한 설득해 최소화 쿼리도 브라우저 런타임이 아닌 빌드타임 처리로 전환해, 서비스 성능을 유지 실제론 고객 요청을 모두 막지는 못해, 일부는 성능 저하로 이어졌음 And more 기술 이외에도 긍정적이고 협력적인 팀 분위기와 강한 동기 부여가 대규모 시스템 성공의 진짜 원동력임을 강조 사소하지만 중요한 실무적 선택과 꾸준한 품질 관리의 힘을 실감한 사례였음
- 생성일: 2025. 7. 10.
만다라트 보기: /view/f473d0f283e52033
이 만다라트에 대한 의견이나 토론을 자유롭게 남겨주세요!
만다라트 정보:
- 제목: 지루한 코드로 10억 웹 요청 처리
- 주제: Serving a billion web requests with boring code High level 2년 반에 걸쳐 미국 정부의 메디케어 플랜 비교·구매 웹사이트를 리드 개발함 일 평균 500만 API 요청을 처리, 평균 응답 속도는 10ms 미만, 95% 요청은 100ms 이하로 유지 장애 발생률이 매우 낮아 실제 엔지니어가 새벽에 호출된 사례는 한 손에 꼽을 정도 Postgres, golang, React 등 누구나 이해할 수 있는 검증된 기술로만 구성해, 꾸준히 안정적인 시스템을 구축함 Boring über alles 최우선 원칙은 '지루하고 검증된 기술' 만을 우선하는 것(** Choose Boring Technology**) 혁신 시도는 꼭 필요한 곳에서만 innovation token을 아껴서 사용 복잡하고 화려한 솔루션보다 안정적이고 명확한 기술과 프로세스를 선호 The boring bits Postgres: 데이터 저장의 핵심, 신뢰성과 확장성을 모두 만족. 복잡한 검색(페이시티드 검색 등)도 Postgres로 해결 golang: 빌드와 배포가 빠르고, 바이너리 산출물이 명확함. 에러 핸들링이 직관적이고, 새로운 팀원도 쉽게 적응 가능 React: SPA 프레임워크 중 가장 검증되어 있고, 팀원들이 이미 익숙했음. 접근성과 다양한 기기 지원도 중요한 고려 요소였음 장기적으로는 번들 크기와 속도 저하 이슈가 발생했지만, 당시 상황에서는 시간 내에 결과를 내기 위한 최적의 선택이었음 The innovation tokens Modular backend: 전체 백엔드를 마이크로서비스도, 모놀리식도 아닌 3개의 대형 모듈(druginfo, planinfo, beneinfo)로 구성 각 모듈은 별도의 Postgres DB를 사용하고, 데이터 공유는 오직 gRPC를 통해서만 이뤄짐 druginfo: 약국, 보험, 포장 등 조합이 기하급수적으로 늘어나는 약가 정보를 매우 정교하게 인덱싱하고, 복잡한 사전처리와 성능 최적화가 필요 planinfo: 매일 새로운 CMS 데이터를 수신해, DB 전체를 새로 만들어 사용함(불변성 유지) beneinfo: 실제 가입자 정보를 보관하는 유일한 부분으로, 민감한 PII(개인정보)는 최소한만 저장. 데이터 유출 리스크 최소화를 위해 설계와 운영에 신경 씀 gRPC: 모듈간 통신 인터페이스를 코드로 명확히 정의할 수 있는 장점. 자동화 도구와 연동성이 뛰어남 단, 빌드·툴링·디버깅은 복잡하고, JSON API 대비 직관성이 떨어지는 단점도 경험 grpc-gateway를 통해 웹클라이언트 지원 및 대량 트래픽을 무리 없이 처리함 Strict backwards compatibility API 및 데이터베이스의 하위 호환성 유지를 엄격하게 지킴 공개 API의 필드는 절대 삭제하지 않고, 보안 문제가 있지 않는 한 평생 유지 DB 컬럼도 추가는 자유롭지만 삭제는 여러 단계 검증(참조 제거→몇 주 대기→실제 삭제) 절차를 거침 이 규율이 높은 변화 속도와 안정적인 배포·운영의 핵심 기반이 됨 Faceted search ElasticSearch 대신 Postgres만으로 페이시티드 검색 구현 well-indexed plan 테이블에 조건을 조합하는 250줄 함수 하나로 모든 검색 로직을 처리 비즈니스 요구에 집중, 불필요한 복잡성 없이 단순하게 해결함 Database creation DB 스키마를 숫자가 붙은 .sql 파일로 관리, 순서대로 로딩하여 신뢰성 보장 planinfo/beneinfo DB는 매일 재생성, 마이그레이션 필요 없음. 버전 불일치 등 설정 오류 시 앱 자체를 아예 시작하지 않도록 설계 ETL 데이터 소스별 셸 스크립트로 S3에 적재 → cron으로 EC2 인스턴스가 최신 ETL 코드/데이터 가져와 신규 RDS DB 생성 Postgres의 COPY 구문을 적극 활용, INSERT 대신 대량 데이터 적재를 효율적으로 처리 매일 2~4시간이면 수억 행 데이터를 새 DB로 전환 가능 models xo 라이브러리로 DB 모델 자동 생성, 커스텀 템플릿으로 팀에 맞는 코드 생성 testing 가장 큰 실수는 sqlmock을 활용한 테스트를 과하게 만들어 데이터가 자주 바뀌는 상황에서 유지보수가 매우 번거로움 실제 불변 DB라면 실DB에 대한 테스트가 더 효율적이었을 것 Local database for development 각 테이블의 부분 데이터를 자동 생성하는 스크립트로, 개발자별로 작은 로컬 DB로 실제 데이터 기반 테스트와 개발 가능 DB가 커지기 전에 이런 도구를 마련하면 전체 팀 개발 효율이 극대화됨 Miscellaneous tooling 각종 운영·관측 자동화를 위해 CLI 도구를 셸 스크립트로 구현, 모든 유틸리티 기능을 하나로 모아 관리 splunk 로그를 Slack 명령어로 바로 그래프로 시각화하는 등 현장 중심의 도구를 적극 개발·활용 Logging 요청 진입 시점에 request id를 생성, 그 id가 모든 로그 컨텍스트에 붙어서 어디서든 추적 가능 zerolog로 안전하고 체계적인 로깅 설계 시스템 입구·퇴출, 예외 상황 등 중요 시점마다 필수 로그 남기기 Documentation GitHub markdown 문서를 sphinx-book-theme으로 변환해 위키북으로 운영 팀원 모두가 적극적으로 문서화에 기여, 한 곳에서 모든 시스템 문서를 찾을 수 있도록 함 뛰어난 문서화 문화가 팀의 성장과 유지보수, 신입 온보딩 효율을 크게 높임 Runtime integrations 클라이언트의 성능 저하 요청(분석 스크립트 삽입 등)은 최대한 설득해 최소화 쿼리도 브라우저 런타임이 아닌 빌드타임 처리로 전환해, 서비스 성능을 유지 실제론 고객 요청을 모두 막지는 못해, 일부는 성능 저하로 이어졌음 And more 기술 이외에도 긍정적이고 협력적인 팀 분위기와 강한 동기 부여가 대규모 시스템 성공의 진짜 원동력임을 강조 사소하지만 중요한 실무적 선택과 꾸준한 품질 관리의 힘을 실감한 사례였음
- 생성일: 2025. 7. 10.
만다라트 보기: /view/f473d0f283e52033
이 만다라트에 대한 의견이나 토론을 자유롭게 남겨주세요!
- 이전글01. 잡스가 세상에 충격을 주었던 순간을 모은 동영상 10.02.03
댓글목록
등록된 댓글이 없습니다.