[java] Ehcache와 캐싱된 데이터의 동시성 관리

캐싱은 많은 애플리케이션에서 성능을 향상시키기 위한 중요한 기술입니다. 데이터베이스나 네트워크 호출 등 비용이 큰 작업을 실행하지 않고 이전에 계산한 결과를 재사용하여 응답 시간을 단축시킬 수 있습니다. 그러나 캐싱을 사용할 때 주의할 점 중 하나는 동시성 문제입니다. 여러 스레드가 동시에 동일한 캐시 데이터에 접근하고 변경하려는 경우 간단한 캐시 문제가 복잡한 동기화 문제로 발전할 수 있습니다.

이 문제를 해결하기 위해 Ehcache는 동시성을 관리하기 위한 다양한 기능을 제공합니다. 이 블로그 게시물에서는 Ehcache를 사용하여 캐시된 데이터의 동시성을 관리하는 방법에 대해 살펴보겠습니다.

1. Ehcache 설정

Ehcache를 사용하려면 먼저 Ehcache 라이브러리를 프로젝트에 추가해야 합니다. Maven을 사용하는 경우 pom.xml 파일에 다음과 같이 의존성을 추가하세요:

<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.8.1</version>
</dependency>

Ehcache를 사용하기 위해선 캐시 구성 파일을 작성해야 합니다. 예를 들어 ehcache.xml 파일을 만들고 다음과 같이 기본적인 캐시 설정을 추가할 수 있습니다:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.ehcache.org/v3"
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.8.xsd">

    <cache alias="myCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.String</value-type>
        <expiry>
            <none/>
        </expiry>
        <resources>
            <heap unit="entries">100</heap>
        </resources>
    </cache>

</config>

위의 설정 파일에서는 myCache라는 이름의 캐시를 정의하고 키와 값을 모두 String 타입으로 설정하고 있습니다. 캐시의 최대 크기는 100개로 제한되어 있습니다.

2. 캐시 생성 및 가져오기

Ehcache에서 캐시를 생성하고 가져오는 것은 매우 간단합니다. 다음과 같이 CacheManager를 사용하여 캐시를 만들고 이를 가져올 수 있습니다:

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.xml.XmlConfiguration;

public class CacheExample {
    public static void main(String[] args) {
        Configuration xmlConfig = new XmlConfiguration(getClass().getResource("/ehcache.xml"));
        CacheManager cacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
        cacheManager.init();

        Cache<String, String> myCache = cacheManager.getCache("myCache", String.class, String.class);
        // 캐시 사용 예제
        myCache.put("key", "value");
        String cachedValue = myCache.get("key");

        cacheManager.close();
    }
}

위의 코드에서는 ehcache.xml 파일로부터 CacheManager를 초기화하고 myCache라는 이름의 캐시를 가져옵니다. 그런 다음 put 메서드를 사용하여 캐시에 데이터를 저장하고 get 메서드를 사용하여 데이터를 검색합니다.

3. 동시성 제어

Ehcache를 사용하는 경우 다중 스레드 환경에서 캐시 데이터에 대한 동시성 제어를 위한 내장 Locking API를 제공합니다. 다음은 동시성을 처리하는 예제입니다:

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.xml.XmlConfiguration;

public class ConcurrentCacheExample {
    public static void main(String[] args) {
        Configuration xmlConfig = new XmlConfiguration(getClass().getResource("/ehcache.xml"));
        CacheManager cacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
        cacheManager.init();

        Cache<String, String> myCache = cacheManager.getCache("myCache", String.class, String.class);

        String key = "key";
        Thread thread1 = new Thread(() -> {
            try {
                myCache.acquireWriteLockOnKey(key);
                myCache.put(key, "value1");
                Thread.sleep(2000);
                myCache.releaseWriteLockOnKey(key);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                myCache.acquireWriteLockOnKey(key);
                myCache.put(key, "value2");
                Thread.sleep(2000);
                myCache.releaseWriteLockOnKey(key);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();

        cacheManager.close();
    }
}

위의 코드에서는 두 개의 스레드를 생성하고 동시에 같은 키("key")에 대한 캐시 값을 수정하려고 합니다. acquireWriteLockOnKey 메서드를 사용하여 키에 대한 쓰기 잠금을 획득하고 releaseWriteLockOnKey 메서드를 사용하여 잠금을 해제합니다. 이렇게 하면 한 스레드가 캐시를 수정하는 동안 다른 스레드는 기다려야 합니다.

결론

Ehcache는 캐싱된 데이터의 동시성을 관리하기 위해 다양한 기능을 제공합니다. 위에서는 기본적인 캐시 설정, 캐시 생성 및 가져오기, 그리고 동시성 제어에 대한 예제 코드를 살펴보았습니다. Ehcache를 사용하여 애플리케이션의 성능을 향상시키고 동시성 문제를 효과적으로 해결할 수 있습니다.

참고 자료