티스토리 뷰

1. 캐시란?

서버는 많은 리소스들을 저장하고 있다. 개중에는 엄청나게 큰 파일을 요청하는 경우가 있는데, 이럴 경우 여러번 같은 파일을 요청할 경우 서버는 많은 사용자가 사용 중이 아니어도 과부하 상태 빠질 것이다.

 

 

위와 같은 경우를 대비해서 서버-클라이언트 서비스 간에 캐시(Cahce)를 둬서 리소스에 대한 좀더 빠른 접근할 수 있도록 한다.

캐시의 위치는 구현법과 솔루션에 따라 나뉘는데,

 

1. 인 메모리 캐싱(In-memory caching): 서버의 RAM에 데이터를 저장해 캐싱된 데이터에 빠르게 접근할 수 있도록 한다. Java 라이브러리 ehcache가 대표적인 예이고, 스프링 내부적으로도 제공하는 @Cacheable도 인메모리 캐싱이다.

 

2. 디스크 캐싱(Disk caching): 데이터를 RAM이 아닌 디스크에 저장하는 방식이다. 디스크 캐싱은 일반적으로 메모리 내 캐싱보다 느리지만 캐싱해야 하는 데이터 양이 너무 커서 메모리에 담을 수 없을 때 유용하다. 대표적으로 자바 라이브러리인 Hazelcast가 있다.

 

3. 분산 캐싱(Distributed caching): 데이터를 분산 캐시 프로토콜을 사용하여 여러 서버에 복제해 모든 서버에서 캐시에 액세스할 수 있도록 하는 방식이다. 분산 캐싱의 예로는 Redis가 있다. Redis는 분산 용 뿐만 아니라 인 메모리 캐시로도 사용 가능하다.

 

4. 리버스 프록시 캐싱(Reverse proxy caching): 클라이언트가 동일한 요청을 하면 원본 서버에 도달하지 않고 프록시 캐시에서 제공하는 방법이다. 이러한 유형의 캐싱은 일반적으로 Varnish 또는 Nginx와 같은 리버스 프록시 서버에서 수행된다.

 

5. 클라이언트 측 캐싱(Client-side caching): 데이터가 브라우저의 캐시에 저장되는 방식. 브라우저에서 일반적으로 처리해주며, 리소스를 업데이트해도 바로 반영이 되지 않는 경우가 대표적인 예이다. 이 때 Ctrl + F5 또는 Ctrl + Shift + R로 강력 새로고침을 해주는데, 강력 새로 고침 기능이 캐시 제거 후 새로고침 이다.

 

우선, 관심있는 인메모리 캐싱만 정리하려 한다.

 

2. 인 메모리 캐싱(In-memory caching)

2.1 @Cacheable

Spring에서 제공하는 기본 캐싱 어노테이션이다. 일반적으로 특정 메서드의 결과를 캐시하는 데 사용된다.

@Service
public class MyService {

    @Cacheable(value = "myCache", key = "#id")
    public MyObject findById(long id) {
        // Code to retrieve the object from the database
        // This code will only be executed if the object is not already in the cache
        MyObject obj = ...;
        return obj;
    }
}

이 메서드가 호출되면 Spring Framework는 동일한 키(이 경우 동일한 ID)를 가진 메서드의 결과가 이미 캐시에 있는지 확인하고, 존재 한다면 캐시된 결과가 반환된다.

 

그렇지 않으면 메서드가 실행되고 결과는 id를 키로 사용하여 캐시에 저장된다.

 

@Cacheable는 캐싱 메커니즘이 아니라 메소드의 결과가 캐싱되어야 함을 Spring Framework에 알리는 방법이라는 데에 유의해야한다. 일반적으로 알려진 캐싱 매커니즘을 사용하고, 캐시된 데이터를 실제로 저장하기 위해 Ehcache 같은 외부 라이브러리를 사용해야한다.

2.2 ehcache

ehcache는 Spring에서 간단하게 사용할 수 있는 Java 기반 오픈소스 캐시 라이브러리다. ehcache의 가장 큰 장점은 3.x 버전부터 자바 표준을 따라 개발되어, javax.cache API (JSR-107)와의 호환성을 제공한다는 점이다.

 

Java에서만 사용할 수 있다는 것이 장점이자 단점이고, 어쩌면 당연한 이야기지만 DB의 역할까지 담당하지 않기 때문에 트랜잭션이나 고급 쿼리까지는 지원하지 못한다.

 

또, 캐싱할 데이터를 외부에 저장하기 위해서는 저장할 데이터(객체 혹은 인스턴스)가 Serializable이 구현 되어 있어야 하는 단점도 있다.

2.2.1 gradle 설정

dependencies {
    implementation 'org.ehcache:ehcache:3.8.1'
}

2.2.2 ehcache.xml 설정

<ehcache>
  <cache name="myCache"
         maxEntriesLocalHeap="1000"
         eternal="false"
         timeToIdleSeconds="120"
         timeToLiveSeconds="120"
         diskSpoolBufferSizeMB="30"
         maxEntriesLocalDisk="10000000"
         diskExpiryThreadIntervalSeconds="120"
         memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
  </cache>
</ehcache>

2.2.3 java 구현

- CacheManager 구현

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .withCache("myCache", 
                CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, 
                ResourcePoolsBuilder.heap(10))
                .build())
                .build(true);
Cache<String, Object> myCache = cacheManager.getCache("myCache", String.class, Object.class);

- 캐시를 이용한 데이터 저장 및 조회

public Object findById(long id) {
    Object obj = myCache.get(Long.toString(id));
    if (obj == null) {
        // Code to retrieve the object from the database
        obj = ...;
        myCache.put(Long.toString(id), obj);
    }
    return obj;
}

추가적인 구현 및 설정 방법은 홈페이지 에서 확인.

 

2024.01.16 수정 - 위 방법보다는 스프링부트에 내장하고 있는 cache를 사용하는게 조금 더 낫다.

2023.04.26 - [개발/SPRING] - 스프링 부트에서 캐시(Cache) 초간단 사용하기

2.3 Redis를 이용한 캐싱

별도의 서버에 Redis를 띄워서 캐시 서버로 사용하는 방법이다.

 

이 내용은 Redis와 함께 좀 더 큰 꼭지로 따서 다뤄야할 것 같다.

 

2024.01.16 수정 - 2023.08.02 - [개발/Redis] - Windows 환경에서 스프링부트 + Redis 사용하기

3. CDN(Content Delivery Networks)

사실 캐싱을 알아보게 된 근본적인 이유이며, 본 포스팅의 주제나 다름 없다.

 

CDN은 지리적 위치에 따라 사용자에게 콘텐츠를 전달하는 데 사용되는 분산 서버 시스템이다. CDN을 사용하는 궁극적인 이유는 콘텐츠를 요청하는 사용자에게 더 가깝게 캐싱하여 대기 시간을 줄이는 것이다.

 

CDN은 일반적으로 전 세계 여러 위치에 있는 에지(edge) 서버라고 하는 서버 네트워크로 구성된다. 사용자가 콘텐츠를 요청하면 CDN은 사용자와 가장 가까운 에지 서버에서 캐시된 복사본을 제공하여 콘텐츠를 전달하는 데 걸리는 시간을 줄인다.

CDN은 많은 웹사이트와 애플리케이션, 특히 사용자가 많거나 트래픽이 많은 애플리케이션에서 널리 사용된다. CDN을 사용하면 웹 사이트 또는 애플리케이션의 성능을 향상시키고 원본 서버의 부하를 줄이며 가용성을 높일 수 있다.

 

대표적으로 CDN 서비스를 제공하는 회사로 Akamai Technologies가 있는데, 홈페이지에 가면 CDN에 대해 조금 더 자세히 소개되어있다.

 

2024.01.16 수정 - AWS 관리를 하게 되면서 CDN도 적용하게 되었다.

2024.01.05 - [개발/AWS] - AWS S3와 CloudFront 연동 끝까지 가보기

4. 마치며

앱에서 서버로 이미지를 반복적으로 요청하는 경우가 발생해, 앱쪽에서 캐시 처리에 대한 이야기가 나와 알아보게 되었다.

 

캐시에 대해 공부하면서, CDN도 알게되었는데 이번에 클라우드로 서버를 옮기게 되면 다시한번 볼일이 생길 것 같다.


참고 사이트

https://medium.com/finda-tech/spring-%EB%A1%9C%EC%BB%AC-%EC%BA%90%EC%8B%9C-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-ehcache-4b5cba8697e0
https://www.geeksforgeeks.org/spring-boot-caching/
https://www.akamai.com/ko/our-thinking/cdn/what-is-a-cdn

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함