프로젝트 진행에 앞서 굉장히 고민이 많이 되는 부분이었습니다.
프로젝트에서 캐시 데이터를 언제 사용하면 좋을지와 캐시 저장소와 실제 DB 저장소 간의 일관성을 어떤 시점에 어떤 방식으로 맞춰줄 수 있는지에 대한 고민을 정리하게 위해 해당 글을 작성하게 되었습니다.
일반적으로 캐시는 데이터 접근 속도를 향상시켜주기 위해 사용합니다.
하지만 모든 상황에 적합한 것은 아니며, 캐시를 사용하기 적합한 환경을 찾아 적용하는 것이 중요합니다.
데이터 접근 빈도가 높은 경우: 동일한 데이터에 대한 반복적인 조회가 많은 경우, 캐시를 사용하면 디스크 접근을 줄이고 데이터를 빠르게 제공할 수 있습니다.
읽기 작업이 많은 경우: 읽기 작업이 많고 쓰기 작업이 상대적으로 적은 경우, 데이터 일관성을 유지하기 쉬우므로 캐시의 이점이 큽니다.
응답 시간이 중요한 경우: 웹사이트나 애플리케이션에서 사용자 경험 향상을 위해 빠른 응답 시간이 필요한 경우, 캐시를 사용하여 처리 성능을 개선할 수 있습니다.
복잡한 계산이 필요한 데이터: 데이터를 생성하거나 처리하는데 많은 자원이 소모되는 경우, 한 번 계산된 결과를 캐시에 저장하여 재사용함으로써 성능을 개선할 수 있습니다.
외부 시스템 의존성 감소: 외부 API 호출이나 외부 데이터베이스 접근 등 외부 시스템에 의존적인 데이터를 캐시하면, 외부 시스템의 장애나 지연이 내부 시스템에 미치는 영향을 줄일 수 있습니다.
데이터 일관성이 매우 중요한 경우: 데이터의 갱신이 자주 발생하고, 각각의 데이터 업데이트가 반드시 실시간으로 반영되어야 하는 경우, 캐시로 인해 발생할 수 있는 일관성 문제로 인해 캐시 사용이 부적합할 수 있습니다.
쓰기 작업이 많은 경우: 데이터가 자주 변경되는 환경에서는 캐시 일관성 유지가 어렵고, 캐시를 자주 업데이트하거나 무효화해야 하므로 관리 비용이 높아질 수 있습니다.
데이터 양이 너무 많아서 캐시로 관리하기 힘든 경우: 캐시할 수 있는 메모리 크기에 비해 데이터 양이 매우 많은 경우, 효과적인 캐시 전략을 수립하기 어렵습니다.
사용자별로 맞춤화된 데이터가 필요한 경우: 사용자 개인별로 맞춤화된 데이터를 제공해야 하는 경우, 개별 사용자 데이터를 캐시하는 것은 메모리를 비효율적으로 사용할 수 있으며, 보안 문제도 발생할 수 있습니다.
조회수는 게시글을 방문했을 때 조회 가능하며 게시글을 처음 방문했을 시 증가할 수 있도록 구현할 예정입니다.
게시글 방문시 DB에 게시글 테이블에서 조회수를 들고 오는 것이 아니라 캐시 저장소에서 조회할 수 있도록 구현하며 해당 사용자가 방문한 게시글 목록을 캐시 저장소에 저장하여 해당 사용자가 처음 방문한 게시글일 시 조회수를 증가시키도록 구현할 예정입니다.
게시글 조회수는 빈번하게 수정이 일어나고 실제 DB와의 데이터 일관성이 중요하기 때문에 캐시를 사용하는 것이 성능을 더 저하시킬 수 있지만 위와 같이 캐시 저장소에서 수정 작업을 진행하고 이후 일정 주기를 통해 실제 DB에 반영하는 식으로 해결할 예정입니다.
게시글은 수정 작업보다는 읽기 작업의 빈도가 높은 편에 속하고 많은 사용자가 동일한 게시글 정보를 조회하기 때문에 캐싱을 사용하여 서버 부하 감소 및 응답 속도를 높이고 성능적 이점, 사용자 경험을 향상시킬 수 있다 판단하였습니다.
게시글의 수정이 일어날 경우 실제 DB에 수정 내용을 반영한 후 Redis에 저장된 해당 게시글의 정보를 새로운 수정 내용으로 갱신시켜주는 방식으로 데이터 일관성을 맞춰주기로 하였습니다.
게시글을 조회하는 페이지에서 댓글을 조회할 수 있지만 댓글은 게시글에 비해 사용자 간의 교류가 빈번하게 일어나 수정 작업이 많이 발생하기 때문에 캐싱을 사용하지 않기로 하였습니다.
✔️ 조회수 및 게시글 정보에 대한 캐시 저장소의 데이터 갱신은 Spring Cache를 이용하여 해결하기로 하였습니다. Spring Cache에 대한 내용은 아래 글을 참고하시면 됩니다.
프로젝트에서 게시글 작성자는 본인이 작성한 게시글에서 발생할 수 있는 각종 이벤트(댓글 작성, 좋아요 클릭, 스크롤 깊이 등등)를 조회할 수 있는 페이지를 제공받습니다.
게시글에서 발생할 수 있는 이벤트들은 매우 빈번하게 발생하기 때문에 이벤트 발생 시마다 서버에 해당 이벤트를 전송한다면 트래픽이 매우 급증하는 문제가 발생하게 됩니다.
이러한 문제를 해결하기 위한 방법으로 메시지 큐와 Spring Batch를 사용하기로 하였습니다.
게시글에서 이벤트가 발생할 시 메시지 큐에 해당 이벤트를 전달하게 되고 메시지 큐에서는 이벤트들을 모아서 일정 주기 혹은 이벤트 사이즈에 따라 서버에 한꺼번에 전송하게 됩니다.
이후 서버에서는 해당 이벤트들을 Batch 작업을 통해 실제 DB에 반영하도록 구성할 예정입니다.
메시지 큐는 간단하게 구현이 가능한 AWS SQS 서비스를 이용할 생각입니다. SQS는 기본적으로 메시지 큐잉 서비스로서, 메시지들을 모아두었다가 서버가 요청할 때 메시지를 전달합니다. 또한 SQS에서 메시지를 배치로 수신하는 것이 가능합니다.