- 도커 desktop 설치
- 루트 폴더의 run.sh 실행
- 멀티 모듈로 프로젝트를 구성해주세요.
- Gradle을 사용하여 빌드 환경을 구성해주세요.
- 사용자 등록, 로그인, 정보 수정 API를 구현해주세요.
- Spring Security를 활용해 인증 로직을 구현해주세요.
- 게시글 작성, 조회, 수정, 삭제 API를 구현해주세요.
- 게시글에는 조회수 정보가 포함되어야 합니다.
- 게시글 목록 조회 API를 구현해주세요.
- 게시글 검색 API를 구현해주세요.
- 특정 게시글에서 잦은 조회가 발생하더라도 조회수의 정확한 업데이트 처리를 구현해주세요.
- API 엔드포인트는 Openapi를 통해 Swagger UI로 제공합니다.
- 프로젝트 실행후 아래의 엔드포인트를 통해 API 목록을 확인할 수 있습니다.
- http://localhost:8080/swagger-ui/index.html
- api/mind-share-api/http 경로에 있는 http 파일을 통해서 실행할 수 있습니다.
처음에는 전문적인 검색 기능을 제공하기 위해 검색 엔진의 도입을 고려했습니다. 그러나 검색 엔진에 대한 지식이 부족하고, 7일이라는 제한된 기간 내에 검색 엔진을 학습하고 적용하는 것은 현실적으로 어렵다고 판단했습니다.
대안으로 MySQL의 Full-Text Index를 활용하기로 결정했습니다. MySQL은 기본적으로 Full-Text Search 기능을 제공하며, 이를 통해 비교적 간단하게 검색 기능을 구현할 수 있을 것으로 예상했습니다. 하지만 구현 과정에서 몇 가지 문제에 직면했습니다:
Native Query의 사용 필요성: MySQL의 Full-Text Search를 사용하려면 MATCH ... AGAINST 구문을 사용해야 하는데, 이는 JPA나 QueryDSL에서 직접 지원하지 않습니다. 따라서 Native Query를 사용해야 했습니다.
동적 쿼리 작성의 복잡성: 게시글 검색에는 페이징 처리가 필수적이었고, 이는 커서 기반 페이징을 통해 구현되었습니다. 하지만 Native Query와 커서 기반 페이징 로직을 함께 사용하려니 동적 쿼리 작성이 복잡해지고, 유지보수성에도 문제가 생길 수 있었습니다.
이러한 이유로 최종적으로 LIKE 연산자를 사용하는 방법을 선택했습니다. LIKE 연산자를 사용하면 QueryDSL에서 간단하게 구현할 수 있고, Native Query를 피할 수 있기 때문입니다. 비록 LIKE 방식이 Full-Text Search에 비해 검색 성능이나 정확도 면에서 떨어질 수 있지만, 현재 프로젝트의 규모와 요구사항을 고려했을 때 적절한 선택이라고 판단했습니다.
결론적으로, 제한된 시간 내에 안정적이고 유지보수 가능한 코드를 작성하기 위해 LIKE 방식을 채택하여 검색 기능을 구현했습니다.
특정 게시글에서 잦은 조회가 발생하더라도 조회수의 정확한 업데이트 처리를 구현하기 위해 다음과 같은 방안을 고려했습니다.
- 조회수 로직을 Redis를 이용해 처리
- Redis는 인메모리 데이터 저장소로서 높은 처리량과 낮은 지연 시간을 제공합니다. 이를 통해 빈번한 조회수 및 증가 요청을 효율적으로 처리할 수 있습니다.
- Redis의 CAS 연산을 활용한 Lock-Free 처리
- Redis의 원자적 연산과 CAS(Compare-And-Set) 기법을 활용하여 조회수 증가를 Lock-Free 방식으로 처리했습니다.
- 여러 클라이언트에서 동시에 조회수 증가 요청이 발생하더라도 데이터의 정합성을 보장했습니다.
- 락을 사용하지 않음으로써 발생할 수 있는 병목 현상을 제거하고, 높은 동시성 환경에서도 안정적인 성능을 유지했습니다.
- Write-Back 방식으로 주기적인 DB 반영
- Redis에 저장된 조회수 캐시를 일정한 주기로 데이터베이스에 반영했습니다. 이를 통해 데이터의 영속성과 정확성을 확보했습니다.
- 실시간으로 데이터베이스에 쓰는 대신 주기적으로 일괄 처리함으로써 데이터베이스에 가해지는 쓰기 부하를 감소시켰습니다.
- 시스템 장애나 Redis 데이터 손실 시에도 데이터베이스에 저장된 최신 조회수를 활용할 수 있도록 했습니다.
이러한 접근 방식을 통해 성능과 정확성 두 가지 측면을 모두 만족시킬 수 있었습니다. Redis를 활용한 고속의 조회수 처리와 CAS 연산을 통한 동시성 문제 해결로 시스템의 효율성을 높였고, Write-Back 방식을 통해 데이터의 일관성과 영속성을 보장했습니다. 따라서 특정 게시글에 대한 빈번한 조회가 발생하더라도 조회수의 정확한 업데이트를 안정적으로 처리할 수 있었습니다.