개발

라라벨 캐시 파일 드라이버 구현 및 응용 사례

캐시(Cache)라고 모두들 알고 있을 것이다.
자주 보는 데이터를 어디다가 보관해두고 필요할때마다 새 데이터를 받아쓰는게 아니라 보관해둔 캐시 데이터를 가져다 쓰는걸 말한다.

이런 캐시에 관련된 이야기는 여러 기술에서도 접목을 해서 각자 나름대로의 캐싱 전략을 통해 최적의 속도와 맞춤 서비스를 제공하고있다.


캐시가 뭐임?

당장 우리 브라우저만 하더라도 한번 들린 사이트의 정적 데이터(이미지 등)는 브라우저 단에서 미리 저장해두고, 다음에 그 사이트를 들리면 서버에 요청하는게 아니라 브라우저에서 꺼내쓰기 때문이다.

본문 이미지우걱우걱

이런 캐싱전략은 비단 클라이언트에서만 진행되지는 않는다.
서버입장에서도 자주 요청되는 페이지는 매번 리소스를 조립해서 만들지 않고 미리 만들어두고 서버 캐시에 저장해두고 필요할때 그 캐시데이터를 반환하곤한다.

알게모르게 최적화를 위해서 서버든 클라이언트든 각자 나름의 캐싱전략을 가지고 있다는 말이다.


더불어 우리가 실제로 어떤 시스템을 만들때 이런 방식의 추가 캐싱전략을 구상하는법도 필요하다.

일례를 알아보자.


캐싱 예시

쉽게 현재 이 사이트를 예시로 들어보겠다.

본문 이미지사이드바 데이터

내 사이트에서는 피시로 접속했을 경우 우측, 모바일로 접속했을경우 하단에 내 사이트의 게시글과 접속자에 대한 정보를 위와 같이 제공해주는 데이터 공간이 배정되어있다.

각각의 데이터는 내 사이트 글의 카테고리에 포함된 게시글, 콜렉션에 포함된 게시글, 최근 게시글, 최근 댓글등의 정보가 보여진다.
이런 부분에 대해 매번 페이지 요청 시 데이터베이스에 쿼리를 보내 해당 데이터를 가져와 서버가 반환하는 방식의 코드를 가지고있다.

이상한 플로우는 아니다.
반대로 너무 정석적인 방법이다.
사용자가 페이지에 와서 해당 사이드바의 데이터가 필요하면 서버는 데이터베이스에서 실시간으로 그정보를 뽑아서 주면되는것이다.

근데 여기는 커뮤니티 사이트가 아니다.
나도 하루에 글을 써봣자 한두개 정도쓰고 말고 댓글도 적게달리다보니까 저 사이드바의 정보는 대부분 불변의 데이터로써 작용을한다.

본문 이미지서버: 녜녜 요청했으니 드려야죠

하지만 서버가 이런걸 알까?
서버는 그냥 우직하게 클라이언트가 페이지를 요청하면 그때그때 저 데이터를 디비에서 가져와 보여주게된다.
왜냐하면 그게 저런 카테고리성 데이터의 역할이니까 말이다.

더군다나 접속자가 많으면 많을수록 데이터베이스에 매번 해당 데이터를 요청하고 그걸 서버는 조립해서 줘야한다.
쉽게말해 여기서 서버의 연산성능이 낭비되고 과도한 페이지 요청이 반복되면 결국 사이트는 느려지는것이다.


그럼 우리가 시도해볼만한건 뭘까?
사실 생각보다 서버는 빠르다.
하지만 웹서버와 디비서버간의 데이터 플로우처리는 서버내부의 연산보다 빠르지않다.
서버간 I/O에는 그에따른 처리시간이 소모되기 때문이다.

여기서 우리는 라라벨의 캐시 파사드를 이용해 캐싱전략을 이용할 수 있는것이다.
일정시간동안 카테고리 데이터 리스트를 캐시에 저장해두고 새로 요청이될때 디비에서 데이터를 가져오는게 아니라 캐시 파일에서 데이터를 가져오는 것이다.


라라벨 캐싱 구현

기본적으로 라라벨은 별도의 설정이 없으면 '파일 드라이버'형식으로 캐싱 기능을 자동 제공한다.

본문 이미지이 파일(pile) 말고 그 파일(file)


$asideCategories = Cache::remember('aside_categories', 43200, function () {
    return \App\Models\Post::getCategoriesWithCount();
});Copy

캐싱은 위에처럼 정말 간단하게 구현할 수있다.
Cache 클래스는 파사드로 이미 선언되어있으므로 네임스페이스를 길게 쓸 필요도 없고, remember 메소드를 통해 쉽게 key => value 형식으로 캐시 데이터를 기억하게 할 수 있다.

첫번째두번째세번째
Cache keyTimeout (second)value (function)

파라미터는 순서대로 키, 시간, 밸류를 지정할 수 있으며 나는 단순 텍스트 데이터가 아닌 모델의 카테고리 데이터 collection을 기억시켜둘꺼라서 위와같이 함수 반환방식의 형식을 취했다.

이렇게 기억된 캐시는 storage/framework/cache/data 경로에 저장이 되고 타임아웃 시간만큼의 유효 기간을 가지게된다.

위의 코드처럼 구현을 해두면 캐시데이터가 없는 초회 작동시 함수 반환데이터를 캐시에 '기억'시키고 변수에 그 데이터를 할당시킨다.
두번째 저 코드가 실행된다면 먼저 캐시데이터에서 해당 키값으로 데이터가 있으면 그 데이터가 즉시 캐시 파사드에서 반환된다.
즉 두번째 실행부터는 \App\Models\Post::getCategoriesWithCount(); 이 라인을 실행시키지 않는다는 것이다.

캐싱 시간은 초로 선언해둘 수 있다.
위의 경우에는 43200초, 그러니까 12시간을 지정하고있다.

시간
1분60
5분300
10분600
30분1800
1시간3600
3시간10800
6시간21600
12시간43200
24시간 (1일)86400
7일604800
30일2592000

얼추 시간을 초로 변환한 값은 위와 같다.
캐싱전략에서 자주 바뀌는 데이터는 캐시를 취하지않는게 좋고 자주바뀌지않는거는 캐싱기간을 길게해서 잡아주는게 중요하다.



캐싱 전략 응용

그럼 나처럼 하루에 글을 1-2개를 쓸수도 있고 안쓸수도있는 상황에서의 캐싱 시간 전략은 어떻게 짜야할까?
단순히 생각한다면 이런 모든 경우의수를 기반해 하루에 2개를쓴다하면 1시간이나 3시간의 사이클로 캐시를 초기화하는것이 가장 취하기 쉬운 전략일것이다.


본문 이미지잘래 부꺼조


하지만 나도 인간인지라 매일 그렇게 글쓸리는없고 주말에는 좀 쉬고싶을때도 있을것이다.
하지만 1시간마다 캐시데이터가 비워진다면 주말에는 참 의미없게 계속 캐싱데이터가 초기화되는 웃긴상황이 발생한다는 것이다.

그렇다고 캐싱 초기화 시간을 12시간 이렇게 길게해버리면 글을 바짝 쓰고싶을때 글을열심히 써도 우측 카테고리 숫자는 전혀 안올라가는 웃긴상황이 발생하는것이다.

이럴땐 자동 갱신기간은 늘려놓고 내가 수동으로 캐시데이터를 초기화하는 방법이 존재한다.


Cache::forget('aside_categories');Copy

어려운 접근방법이 아니다.
여긴 나혼자 글쓰는 장소니까 내가 글을쓸때마다 (addPost) 위의 코드가 실행되게 추가해두면 되는것이다.

위에서 했던걸 잠시 리마인드해보자면 Cache::remember()는 캐시데이터가 '없을 경우' 데이터를 생성함과 동시에 원래 처리해야했던 밸류 펑션작업을 실행시킨다.
쉽게말해서 우리가 강제로 캐시값을 갱신, 재부여 시키고싶으면 그냥 기억해둔 캐시를 수동으로 지워버리면 그만인 것이다.


이렇게 적당한 갱신시간(12시간)과 수동 삭제 전략을 이용하면 나름 최신 데이터도 바로바로 제공하면서 최적화도 달성가능한 전략을 짜볼 수 있는것이다.


본문 이미지



이렇게 간단하게 라라벨에서 기본적으로 제공하는 캐싱기능을 이용해 최적화 전략에 대해 알아보았다.
정말 캐싱은 응용하기 나름이라 무궁무진하게 쓸 수있는 만큼 제대로 쓰는법만 안다면 모두 웹서버 최적화의 고수가 될 수 있을거라 생각한다!

#Laravel #php
0 개의 댓글
×