만약 인증을 담당하는 인증 서버가 여러대일때, 우리는 어떻게 세션 공유를 할 수 있을까요?
저희 팀은 이를 위해 EHcache의 RMI Replication을 이용하고 있어요.
1. 클라이언트가 로그인 하면 인증토큰을 발급
2. Ehcache에 인증 토큰을 저장
3. Ehcache Replication을 사용하여 다른 서버에도 자동으로 복제
4. 이후 사용자가 다른 서버로 접속해도 동일한 인증토큰으로 인증 상태를 유지
이런 흐름으로 세션이 공유되고 있습니다.
그럼 지금부터 Ehcache에 대해 알아보고 어떻게 사용하는지 정리해볼게요.
#1. Ehcache가 뭐야?
Ehcache는 Java 기반의 인메모리 캐시 라이브러리입니다.
캐시를 저장할 때 Java의 Heap Memory를 사용하기 때문에
Ehcache를 사용하려면 Java 애플리케이션 내부에 포함이 되어 있어야 합니다.
(Ehcache3에서는 Off-heap memory를 사용하지만 안타깝게도 우리팀은 Ehcache2를 사용...)
- 장점 : 로컬 메모리 기반 접근으로 매우 빠른 읽기, 쓰기 성능
- 단점 : 애플리케이션 인스턴스와 함께 동작하므로, 애플리케이션 인스턴스 장애 시 캐시 데이터도 손실 가능
Redis 와 EHCache 차이점
Redis | EHcache |
별도의 서버를 설치하고 관리하여야 함 | 별로의 서버 관리 없이 JVM 내에서 캐시를 사용할 수 있음 |
다양한 데이터 구조를 지원 | Key,Value 형태의 Map 구조 지원 |
분산 캐시로 여러 애플리케이션 인스턴스 간 캐시 데이터 공유가 필요한 경우 적합 | JVM 내에서의 빠른 로컬 캐시가 필요한 경우 적합 |
EHCache의 Storage Tier
EHCache에는 Storage Tier가 존재하며, 상위 단계일수록 빠릅니다
- Memory Tier : In - Memory
- OffHeap Tier : Memory Heap 외부에 저장. java GC가 적용되지 않음. 바이트 단위의 매우 큰 캐시를 생성.
- Disk Tier : File 캐시와 유사. CacheManager를 이용하여 여러 디스크 저장소 경로를 구성 가능
#2. 어떻게 사용해?
[Cache 설정 속성]
- timeToIdleSecond를 Cache에 설정하게 되면 모든 요소에 기본값으로 제공됩니다.
- 만약 개별 Element에 timeToIdle 설정을 하는 경우 Element 수준의 설정이 더 우선적으로 적용됩니다.
Element element = new Element( member.getId(), member );
element.setTimeToIdle(14400); // 14400초 내에 캐시가 호출되지 않으면 삭제됨
cache.put(element);
[Cache 작업 수행]
net.sf.ehcache.CacheManager인스턴스 생성 후 CacheManager 인스턴스로부터 Cache 인스턴스를 구하고,
Cache 인스턴스를 사용하여 객체에 대한 캐시 작업을 수행할 수 있습니다.
Cache 가져오기
net.sf.ehcache.Cache 인스턴스는 CacheManager.getCache() 메소드를 사용하여 구할 수 있습니다.
파라미터로 Cache 설정에 들어간 캐시 이름을 전달합니다.
만약 지정한 이름의 Cache 인스턴스가 존재하지 않을 경우 null을 리턴합니다.
CacheManager cacheManager = new CacheManager( configFileURL ); // 다양한 방법 존재
Cache cache = cacheManager.getCache( <cache이름> );
Cache cache = cacheManager.getCache( "testBeanCache" );
Create/Update 작업
EHCache는 캐시에 저장될 각각의 객체들을 키를 사용하여 구분하고 있습니다.
net.sf.ehcache.Element 객체를 생성할 때 첫번째 파라미터가 바로 원소의 키를 의미하고, 두 번째 파라미터는 원소의 값을 의미합니다.
따라서 Cache에 객체를 저장하는 경우 Element 객체를 이용하여 Cache.put() 메서드를 사용합니다.
만약 기존에 캐시에 저장된 객체를 수정하길 원한다면 동일한 키를 사용하는 Element 객체를 Cache.put() 메서드에 전달하면 됩니다.
TestBean testBean = new TestBean( id, name );
Element newElement = new Element( testBean.getId(), testBean );
cache.put( newElement );
Read 작업
Cache.get() : key에 해당하는 Element 객체를 리턴, 존재하지 않을 경우 null을 리턴 합니다
Element.getValue() : 캐시에 저장된 객체를 리턴합니다
Element element = cache.get( <key> );
TestBean bean = ( TestBean ) element.getValue();
만약 Serializable 하지 않은 객체를 값으로 저장한 경우 Element.getObjectValue() 메서드를 사용해야합니다
Element element = cache.get( <key> );
NonSerializableBean bean = ( NonSerializableBean ) element.getObjectValue();
getQuiet()
get()메서드와 달리 캐시 항목의 조회 횟수를 증가시키지 않고, 마지막 접근 시간을 업데이트 하지 않습니다.
따라서 캐시 만료 정책에 영향을 주지 않습니다.
Element element2 = cache.getQuiet( <key> );
Delete 작업
cache.remove( <key> );
정상 삭제 시 true 리턴, 존재하지 않는 경우 false을 리턴 합니다
#3. Replication 은 어떻게 해?
앞서 다른 서버에 접근해도 인증 상태를 유지한다고 말씀드렸는데요,
이렇게 되려면 A서버의 캐시에 있는 데이터가 B서버의 캐시에도 동일하게 존재해야 되는거죠.
이걸 Ehcache가 해줍니다. RMI를 이용해 분산캐시를 지원해요.
'TWIL' 카테고리의 다른 글
[TWIL] MariaDB - MHA 이중화를 알아보자 (0) | 2025.02.23 |
---|