
쿼리 캐시
4장. MySQL에서 쿼리 캐시가 사라진 이유에 대해 요약
쿼리 캐시는 SQL의 실행 결과를 메모리에 저장해두었다가, 같은 쿼리가 다시 들어오면 테이블을 읽지 않고 캐시된 결과를 바로 돌려주는 기능이다. 한때 웹 애플리케이션의 응답 속도를 끌어올리는 도구로 자주 쓰였지만, MySQL 8.0에서는 완전히 제거되었다.
동작 방식
캐시 키는 SQL 문장 자체였다. 클라이언트가 보낸 쿼리 문자열이 캐시에 있으면 그 결과를 그대로 반환했고, 없으면 쿼리를 실행한 뒤 결과를 캐시에 저장했다. 키가 SQL 문장 자체이기 때문에 공백이나 대소문자만 달라져도 다른 캐시 항목으로 취급됐다.
핵심 한계는 무효화(invalidation) 정책이다. 어떤 테이블에 INSERT/UPDATE/DELETE가 한 번이라도 발생하면, 그 테이블을 참조하는 모든 캐시 항목을 일괄로 삭제해야 했다. 데이터의 일관성을 보장하려면 다른 선택지가 없었다.
왜 제거됐나
문제는 무효화가 너무 자주, 너무 무겁게 일어났다는 점이다.
- 쓰기가 조금이라도 섞인 워크로드에서는 캐시가 거의 항상 비워졌다. 캐시 적중률이 기대만큼 높지 않았다.
- 캐시를 읽거나 무효화할 때 내부적으로 mutex 락을 잡아야 했고, 이게 동시 처리의 병목이 되었다. 결과적으로 쿼리 캐시를 켜면 오히려 성능이 떨어지는 경우가 많아졌다.
- 멀티코어 환경이 보편화되면서 이 락 경합 비용은 더욱 커졌다.
MySQL은 5.7에서 쿼리 캐시를 기본 비활성화했고, 8.0부터는 관련 시스템 변수(query_cache_size, query_cache_type 등)까지 모두 제거했다.
대안
쿼리 결과 캐싱이 필요하다면 MySQL 외부에서 처리하는 것이 표준이 되었다.
- 애플리케이션 레벨 캐시 — Redis, Memcached
- 프록시 레이어 캐시 — ProxySQL의 query cache
- HTTP/CDN 레이어의 응답 캐시
이쪽은 무효화 정책을 애플리케이션 도메인 지식에 맞게 세밀하게 다룰 수 있어, 내장 캐시처럼 일률적인 전체 무효화를 피할 수 있다.
댓글
아직 댓글이 없습니다.