ARCUS 응용이 가진 캐시 대상 API 목록의 동적 변경 및 관리 기능

잼투인·2021년 6월 30일
3

ARCUS 공통 모듈

목록 보기
2/2

ARCUS 공통 모듈은 Spring AOP 기술을 활용하여, Java 응용의 코드 수정 없이 선언적인(declarative) 방식으로 응용의 캐시 대상 API에 ARCUS 캐시를 쉽게 적용할 수 있는 기능을 제공합니다. ARCUS 캐시의 적용 방식으로는 캐시 대상 API에 Annotation을 부여하는 방식과 Property 파일에 캐시 대상 API 정보를 명시하는 방식이 있습니다. ARCUS 공통 모듈에 대한 자세한 설명은 - Java 환경에서 기본 패턴의 캐시 적용을 돕는 ARCUS 공통 모듈 편에서 확인할 수 있습니다.

ARCUS 공통 모듈의 캐싱 적용 방식(Annotation 방식, Property 파일 방식)에서 캐시 대상 API나 캐시 적용 속성의 변경이 필요할 경우, 이를 수정하고 반영하기 위해서는 응용 재배포가 필요하였습니다.

응용 재배포 없이 변경할 수 있는 기능이 요구되어 기존의 정적인 Property 파일 방식 외에 동적인 Property 관리 방식을 추가하였습니다. 캐시 대상 API 정보를 ARCUS 메타 정보 저장소인 ZooKeeper에 보관해 두고 필요시에 변경할 수 있게 하였으며, ARCUS 공통 모듈은 ZooKeeper Watcher 기능으로 변경된 캐시 대상 API를 실시간으로 조회하여 ARCUS 캐시 적용을 동적으로 변경할 수 있게 하였습니다.

ZooKeeper에서 캐시 대상 API 정보 관리

ZooKeeper는 znode (ZooKeeper Node)라는 키-밸류 아이템들의 디렉토리 구조로, 원하는 데이터를 저장, 관리합니다. ARCUS 응용의 캐시 대상 API 정보를 저장, 관리하기 위해 아래의 ZooKeeper 디렉토리 구조를 사용합니다. 가장 최상위 디렉토리로 /arcus_apps/cache_target_list 디렉토리를 두고, 그 하위에 각 응용이 접근하는 ARCUS 캐시 클러스터의 service-code znode들을 두었으며, 해당 ARCUS 캐시 클러스터를 사용하는 개별 응용의 캐시 대상 API 목록은 service-code 하위의 znode들로 저장하여 관리합니다.

캐시 대상 API 정보를 저장하는 znode의 키는 캐시 대상 API를 유일하게 식별하기 위하여 ‘패키지명.클래스명.메소드명’으로 구성된 target 명을 사용하고, znode의 밸류는 아래 예와 같은 JSON property를 저장합니다.

/* 캐시 대상의 JSON Property */
{
/*
 캐시 대상 API의 시그니처로 '패키지명.클래스명.메소드명' 으로 이루어집니다
*/
  
  "target":"com.service.BoardService.getBoard",

  /* 캐시 대상 API에서 생성하는 Arcus cache key의 prefix를 지정합니다.*/
 
  "prefix":"BOARD",

 /* 
 캐시 대상 API에서 생성하는 Arcus cache item의 TTL(Time to live)을 
 지정합니다. 
*/
  
  "expireTime":60,

 /*
 캐시 대상 API에서 생성하는 Arcus cache key로 사용될 key parameters를 
 콤마로 구분하여 명시합니다. 
*/
  
  "keyParams":["bno"],

 /* 
 캐시 대상 API에서 생성하는 Arcus cache key의 자동 생성 여부
 true이면 모든 parameters를 사용하여 cache key를 자동 생성하고, 
 false이면 keyParams가 명시되어야 합니다. 
*/
  
  "keyAutoGeneration":false,

/* 캐시 대상 API의 Arcus cache 적용 여부 */

  "enable":true,

/* 
 Arcus cache key 생성 시간 정보를 Arcus cache key 문자열 뒤에 
 append 합니다. 서로 다른 cache key를 생성하기 위한 용도입니다.
*/

  "keyDate":"KEY_DATE_NONE"

}

캐시 대상 API들을 저장하는 디렉토리 목적의 arcus_apps, cache_target_list, service-code znode들은 모두 persistent 타입으로 생성하며, 캐시 대상 API 정보를 저장하는 znode들은 persistent & sequence 타입으로 생성합니다. Sequence 타입을 사용한 이유는 캐시 대상 API의 생성, 삭제 외에 캐시 대상 API 속성 변경을 쉽게 판별하기 위한 목적입니다. 캐시 대상 API의 속성 변경 작업은 기존 znode를 제거하고 변경된 속성을 가지는 동일 키의 새로운 znode를 생성함으로써 해당 znode의 sequence 값이 증가되게 하였습니다. 예를 들어, com.service.BoardService.getBoard의 캐시 속성 정보를 가지는 com.service.BoardService.getBoard-0000000000 키의 znode가 존재하는 상태에서, 그 API의 캐시 속성을 변경할 시에 기존 znode 제거와 새로운 znode 생성을 동시에 수행함으로써 새로운 com.service.BoardService.getBoard-0000000001 키를 가진 znode가 만들어지도록 하였습니다. 따라서, ARCUS 응용은 /arcus_apps/cache_target_list/service-code znode의 하위 노드들만 조회하여 자신의 캐시 대상 API 목록에서 생성, 삭제, 변경 여부를 znode들의 sequence 값으로 확인할 수 있습니다.

캐시 공통 모듈의 최신 캐시 대상 API 목록 조회 (ZooKeeper Watcher 활용)

ARCUS 공통 모듈은 ZooKeeper의 /arcus_apps/cache_target_list 디렉토리의 해당 service-code 아래에 저장된 캐시 대상 API 목록을 읽어와서, 캐시 아이템 맵을 사용하여 그 캐시 대상 API 목록을 저장 및 관리합니다.

해당 캐시 대상 API 목록에 변경이 발생한 경우 그에 대한 실시간 알림을 받기 위하여, ZooKeeper Watcher를 해당 service-code znode에 등록합니다. 해당 캐시 대상 API의 생성, 삭제 또는 캐시 대상 API 속성 변경이 발생할 시에 ZooKeeper Watcher의 이벤트 알림을 통해 그 변경을 감지하면 최신 캐시 대상 API 목록을 다시 조회하고 나서, 이전 캐시 대상 API들의 sequence 값과 최신 캐시 대상 API들의 sequence 값을 비교하여 변경된 캐시 대상 API를 식별합니다. 변경된 캐시 대상 API의 JSON property를 ZooKeeper에서 다시 읽어 와서 캐시 아이템 맵에서 교체합니다.

캐시 대상 API의 생성, 삭제와 캐시 대상 API 속성 변경

ZooKeeper Command Line Interface 도구인 zkCli 명령을 이용하여 아래와 같이 캐시 대상 API의 생성, 삭제와 캐시 대상 API 속성 변경을 직접 수행할 수 있습니다. 참고로, 아래 예에서 sequence 타입의 znode를 생성하기 위하여 -s 옵션을 주어 해당 znode를 생성합니다. 매번 zkCli를 사용하여 직접 작업하는 것은 불편하기 때문에, 해당 작업의 script를 작성하여 사용하는 것이 효율적입니다.

// 캐시 대상 API 생성
[ZK: localhost:2180(CONNECTED)]
create -s /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard 
{
 "target":"com.service.BoardService.getBoard",
 "prefix":"BOARD",
 "expireTime":60,
 "keyParams":["bno"],
 "keyAutoGeneration":false,
 "enable":true,
 "keyDate":"KEY_DATE_NONE"
}

// 캐시 대상 API 삭제
[ZK: localhost:2180(CONNECTED)]
delete /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard-0000000000

// 캐시 대상 API 변경
[ZK: localhost:2180(CONNECTED)]
create -s /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard
{
 "target":"com.service.BoardService.getBoard",
 "prefix":"BOARD",
 "expireTime":60,
 "keyParams":["bno"],
 "keyAutoGeneration":false,
 "enable":true,
 "keyDate":"KEY_DATE_NONE"
}
[ZK: localhost:2180(CONNECTED)]
delete /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard-0000000000

캐시 대상 API의 생성, 삭제와 캐시 대상 API 속성 변경 작업을 운영자가 직접 zkCli를 사용하여 수행하는 것은 불편하고 어려울 수 있습니다. 웹 페이지 상에서 Arcus cache cluster (ZooKeeper Ensemble 포함)를 효율적으로 운영 및 관리하기 위한 도구로, 잼투인은 현재 ARCUS 운영 도구를 개발 중에 있습니다. ARCUS 운영 도구에서 응용의 캐시 대상 API 관리를 위하여 캐시 타깃 기능을 개발하였으며, 이의 간단한 예를 보여주고자 합니다.

아래는 특정 service code의 캐시 대상 API 목록을 보여주는 화면입니다. 특정 캐시 대상 API를 클릭하여 상세한 JSON property를 확인할 수 있습니다.

아래는 새로운 캐시 대상 API를 생성하는 화면입니다. JSON property로 만들어질 속성 값들을 사용자로 부터 입력 받아, 해당 캐시 대상 API를 생성합니다. 그 외 삭제, 변경하는 경우도 화면 UI를 보면 직관적으로 알 수 있기 때문에 나머지 부분은 생략합니다.

ARCUS 응용의 캐시 대상 API 관리 기능을 전체 흐름도로 다시 정리하면 아래와 같습니다. 사용자가 ARCUS 운영 도구캐시 타깃 기능을 사용하여 캐시 대상 API들을 생성, 삭제, 변경하면, 이러한 내용들은 ZooKeeper Ensemble에 저장 및 관리되고, ZooKeeper Watcher를 통해 변경 알림이 응용에 장착된 ARCUS 공통 모듈에 전달됩니다. ARCUS 공통 모듈은 앞서 설명한 바와 같이 변경된 캐시 대상 API를 조회하여 캐시 아이템 맵으로 관리하며, 캐시 아이템 맵에 저장된 캐시 대상 API에 한하여 ARCUS 캐시를 자동으로 적용하게 됩니다.

ARCUS 공통 모듈의 적용 방법

ARCUS 공통 모듈 자체에 대해서는 - J Java 환경에서 기본 패턴의 캐시 적용을 돕는 ARCUS 공통 모듈 편에서 설명하였으며, 여기서는 Java 응용에 ARCUS 공통 모듈을 적용하는 방법을 간단히 소개하고자 합니다.

먼저, Java 응용의 pom.xml 파일에 ARCUS 공통 모듈 의존성을 추가합니다.

<dependencies>
   ...
   <dependency>
      <groupId>com.jam2in.arcus</groupId>
      <artifactId>arcus-app-common</artifactId>
      <version>1.4.0</version>
   </dependency>
   ...
</dependencies>

그리고, 아래와 같은 내용의 ARCUS 프로퍼티 파일(arcus.properties)을 생성합니다.

# ZooKeeper Ensemble 주소 
# ARCUS 연결 및 캐시 대상 목록을 갱신하는데 사용됩니다
arcus.address=1.2.3.4:2181,1.2.3.4:2182,1.2.3.4:2183

# Arcus 서비스코드
arcus.serviceCode=test

# Arcus Client의 Connection Pool 사이즈
arcus.poolSize=8

# Operation 처리 대기 시간 (milliseconds)
arcus.asyncOperationTimeout=700

# Arcus Cache Key의 전역 Prefix
arcus.globalPrefix=RELEASE

마지막으로 Spring 설정을 아래와 같이 하시면, ARCUS 공통 모듈 적용이 끝나게 됩니다. 아주 간단하게 적용할 수 있습니다. 이러한 ARCUS 공통 모듈을 사용하여 ARCUS 캐시를 쉽게 적용할 수 있으며, 캐시 대상 API 목록도 동적으로 관리할 수 있게 됩니다.

@Configuration
// Arcus 프로퍼티 로딩
@PropertySource("classpath:arcus.properties")
// @Aspect 사용
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import(ArcusBeans.class)
public class ArcusConfiguration {	
	@Autowired
	private ArcusBeans arcusBeans;
	
	@Bean
	public static PropertySourcesPlaceholderConfigurer 
          propertySourcesPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}
	
	@Bean
	public ArcusStarter arcusStarter() {
		return new ArcusStarter(arcusBeans);
	}	
   
	@Bean
	public ArcusCacheAspect arcusAdvice() {
		return new ArcusCacheAspect(arcusBeans);
	}
}

마치며

지금까지 ARCUS 응용의 재구동 없이 캐시 대상 API를 동적으로 생성, 삭제, 변경할 수 있는 기능의 소개로, 고가용 특성을 가진 ZooKeeper를 활용하여 ARCUS 응용의 캐시 대상 API를 저장 및 관리하고, ARCUS 공통 모듈은 ZooKeeper Watcher를 이용하여 이러한 캐시 대상 API 목록의 실시간 변경을 탐지하여 최신 캐시 대상 API 목록을 유지하는 방법을 설명하였습니다.

캐시 대상 API 관리 기능의 활용도를 높이기 위하여 향후 아래 기능을 추가로 개발하여 제공할 예정입니다.

  • 캐시 대상 API의 HIT, MISS, RATIO 표시,
  • 캐시 대상 API의 HISTORY 기능 (예: 누가, 몇 시에 캐시 대상 API 속성을 변경하였는지 알 수 있는 기능),
  • 캐시 대상 API 생성 시 JSON 또는 JSON 파일로도 생성이 가능하도록 반영.

0개의 댓글