PHP 미드레벨 시스템 설계 면접
새 면접Q. 대용량 파일 업로드 시스템을 설계할 때, 청크(Chunk) 기반 업로드 방식의 장점과 구현 시 고려해야 할 사항들을 설명해주세요. 특히 업로드 중단 후 재개(Resume), 청크 검증, 최종 파일 병합 과정에서의 데이터 무결성 보장 방법을 포함해주세요.
청크 기반 업로드는 대용량 파일을 작은 조각으로 나누어 전송하는 방식으로, PHP의 메모리 제한을 우회하고 네트워크 불안정 시 전체 재전송을 방지합니다. 각 청크마다 고유 식별자와 순서 번호를 부여하고, Redis나 DB에 업로드 진행 상태를 저장하여 재개를 지원합니다. 각 청크의 해시값(MD5/SHA-256)을 계산하여 전송 오류를 검증하고, 모든 청크 수신 후 순서대로 병합하며 최종 파일의 해시값을 원본과 비교하여 무결성을 확인합니다. 임시 저장소에서 청크를 관리하고 병합 완료 후 정리하는 가비지 컬렉션 전략이 필요하며, 동시 업로드 시 파일 잠금과 원자적 병합 연산을 보장해야 합니다.
- • 청크별 해시값 검증으로 데이터 무결성 보장
- • Redis/DB에 업로드 진행 상태 저장으로 재개 지원
- • 원자적 파일 병합과 최종 해시 검증
- • 임시 청크 정리를 위한 가비지 컬렉션 전략
- • 동시성 제어를 위한 파일 잠금 메커니즘
멀티파트 업로드 중 일부 청크가 손상되었을 때, 손상된 청크만 재전송하도록 구현하는 방법을 설명해주세요.
Q. 전자상거래 사이트에서 상품 검색 기능을 구현할 때, 전체 텍스트 검색(Full-Text Search)을 MySQL과 Elasticsearch 중 어떤 것을 선택할지 결정하는 기준을 설명해주세요. 각각의 장단점과 함께, 검색 결과의 정확도를 높이기 위한 검색어 정규화, 동의어 처리, 가중치 부여 전략도 포함해주세요.
MySQL Full-Text Search는 소규모 데이터셋과 간단한 검색에 적합하며 추가 인프라 없이 사용 가능하지만, 복잡한 검색 로직과 대용량 데이터에서는 성능이 제한적입니다. Elasticsearch는 역색인 구조로 빠른 검색 속도와 다국어 분석기, 퍼지 매칭, 복합 쿼리를 제공하지만 별도 서버 운영과 데이터 동기화가 필요합니다. 검색어 정규화는 형태소 분석과 스테밍을 통해 '신발'과 '신발들'을 동일하게 처리하고, 동의어 사전을 구축하여 '운동화'와 '스니커즈'를 매핑합니다. 상품명, 브랜드, 카테고리에 차등 가중치를 부여하여 관련성 점수를 계산하고, 사용자 행동 데이터를 활용한 개인화 랭킹을 적용합니다. MySQL과 Elasticsearch를 하이브리드로 사용하여 정확한 필터링은 MySQL, 텍스트 검색은 Elasticsearch로 분리하는 방식도 고려할 수 있습니다.
- • 데이터 규모와 검색 복잡도에 따른 기술 선택
- • 형태소 분석과 스테밍을 통한 검색어 정규화
- • 동의어 사전 구축 및 매핑 전략
- • 필드별 가중치 부여로 관련성 점수 최적화
- • MySQL과 Elasticsearch 하이브리드 아키텍처
실시간 검색어 자동완성 기능을 구현할 때, Trie 자료구조와 Elasticsearch의 Completion Suggester 중 어떤 것을 선택하시겠습니까?
Q. PHP 애플리케이션에서 MySQL Master-Slave 복제 구조를 사용할 때, 쓰기는 Master로, 읽기는 Slave로 분산하는 전략을 구현하는 방법을 설명해주세요. 특히 복제 지연(Replication Lag)으로 인한 데이터 불일치 문제와 해결 방법, 그리고 Slave 장애 시 폴백 전략을 포함해주세요.
PHP에서 데이터베이스 추상화 계층을 구현하여 쓰기 쿼리는 자동으로 Master로, 읽기 쿼리는 여러 Slave 중 하나로 라우팅합니다. Laravel의 경우 database.php에서 read/write 연결을 분리 설정하고, PDO를 직접 사용할 경우 커넥션 매니저 클래스를 구현합니다. 복제 지연 문제는 쓰기 직후 읽기가 필요한 경우 명시적으로 Master에서 읽도록 하는 Read-Your-Writes 일관성을 보장하고, 세션에 마지막 쓰기 타임스탬프를 저장하여 Slave의 복제 위치와 비교합니다. Slave 서버의 health check를 주기적으로 수행하고, 장애 감지 시 해당 Slave를 연결 풀에서 제거하며, 모든 Slave 장애 시 Master로 자동 폴백하도록 구현합니다. 복제 지연 모니터링을 위해 SHOW SLAVE STATUS의 Seconds_Behind_Master 값을 추적하고 임계값 초과 시 알림을 발송합니다.
- • 쿼리 타입에 따른 자동 라우팅 구현
- • Read-Your-Writes 일관성 보장
- • 복제 지연 모니터링 및 임계값 관리
- • Slave health check와 동적 연결 풀 관리
- • 장애 시 Master로 자동 폴백 전략
다중 Slave 환경에서 읽기 부하를 분산할 때, 라운드 로빈과 가중치 기반 분산의 차이점과 각각의 적용 시나리오를 설명해주세요.
Q. 외부 서비스로 이벤트를 전송하는 웹훅(Webhook) 시스템을 설계할 때, 전송 실패 시 재시도 로직, 순서 보장, 중복 전송 방지를 어떻게 구현하시겠습니까? 특히 수신 측 서버가 장시간 다운되었을 때의 처리 전략도 포함해주세요.
웹훅 이벤트를 먼저 데이터베이스에 저장하고 비동기 큐(Redis Queue, RabbitMQ)를 통해 전송하여 메인 애플리케이션과 분리합니다. 재시도는 지수 백오프(Exponential Backoff) 전략을 사용하여 1분, 5분, 30분, 2시간 간격으로 최대 5회 시도하고, 최종 실패 시 Dead Letter Queue로 이동시켜 수동 처리합니다. 각 이벤트에 고유 UUID를 부여하고 수신 측이 멱등성 키로 사용하도록 하여 중복 처리를 방지하며, 이벤트 순서는 타임스탬프와 시퀀스 번호를 함께 전송합니다. 수신 측 장기 다운 시 일정 기간(예: 7일) 동안 이벤트를 보관하고, 복구 후 배치 전송 API를 제공하여 누락된 이벤트를 조회하도록 합니다. HMAC 서명을 통해 웹훅 요청의 진위를 검증하고, 전송 상태와 응답을 로깅하여 디버깅과 모니터링을 지원합니다.
- • 비동기 큐를 통한 전송 처리 분리
- • 지수 백오프 재시도 전략 및 Dead Letter Queue
- • UUID 기반 멱등성 보장
- • 타임스탬프와 시퀀스 번호로 순서 추적
- • HMAC 서명을 통한 보안 검증
웹훅 수신 측에서 처리 시간이 오래 걸려 타임아웃이 발생하는 경우, 어떤 아키텍처 패턴을 권장하시겠습니까?
Q. 글로벌 서비스를 위해 여러 지역에 데이터센터를 구축할 때, PHP 애플리케이션의 데이터 동기화 전략을 설계해주세요. Active-Active와 Active-Passive 구성의 차이점, 지역 간 데이터 일관성 보장 방법, 그리고 지역 간 장애 발생 시 트래픽 라우팅 전략을 설명해주세요.
Active-Passive 구성은 주 데이터센터에서 모든 쓰기를 처리하고 보조 센터는 대기 상태로 장애 시에만 활성화되어 구현이 단순하지만 리소스 활용이 비효율적입니다. Active-Active 구성은 모든 데이터센터가 읽기와 쓰기를 처리하여 성능과 가용성이 높지만 데이터 충돌 해결이 복잡합니다. 지역 간 데이터 동기화는 MySQL의 멀티 마스터 복제나 Galera Cluster를 사용하거나, 애플리케이션 레벨에서 이벤트 소싱과 CRDT(Conflict-free Replicated Data Types)를 활용합니다. 강한 일관성이 필요한 데이터는 단일 지역에서만 쓰기를 허용하고, 최종 일관성으로 충분한 데이터는 지역별로 분산 처리합니다. DNS 기반 지리적 라우팅과 헬스체크를 통해 사용자를 가장 가까운 정상 데이터센터로 연결하고, 데이터센터 장애 시 자동으로 다른 지역으로 페일오버합니다. CDN을 활용하여 정적 리소스는 엣지 로케이션에서 제공하고, 세션 데이터는 글로벌 Redis 클러스터나 JWT를 사용하여 지역 간 공유합니다.
- • Active-Active vs Active-Passive 구성의 트레이드오프
- • 멀티 마스터 복제와 충돌 해결 전략
- • 데이터 특성에 따른 일관성 수준 차별화
- • DNS 기반 지리적 라우팅과 자동 페일오버
- • CDN과 글로벌 세션 스토어 활용
지역 간 네트워크 지연이 수백 밀리초일 때, 사용자 경험을 해치지 않으면서 데이터 일관성을 유지하는 방법을 제시해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!