이 블로그 게시물에서는 다음을 사용하여 데이터를 쉽게 캐시하는 방법을 알아보세요. 스프링 캐시
그리고 카우치베이스
를 지원 스토어 관리자로 지정했습니다.
목차
소개 한마디
다음과 관련된 많은 작업이 있었습니다. 봄
요즘! 저희는 최근 Spring 데이터 카우치베이스
커넥터를 사용하여 2.x 세대의 Java SDK로 업그레이드하여 다양한 새로운 기능 및 개선 사항 (자세한 내용은 추후 블로그 게시물에서 확인할 수 있습니다)...
그 과정에서 프로젝트에 다음과 직접적으로 관련이 없는 몇 가지 클래스가 있다는 사실을 알게 되었습니다. 스프링 데이터
따라서 공식적인 '릴리스 트레인' 릴리스 주기를 준수할 필요가 없었습니다: 의 캐시
패키지.
그래서 우리는 새로운 간단한 Spring Boot 캐시 예제 프로젝트를 시작했습니다. 의 2.x
세대의 카우치베이스 스프링 캐시
구현 깃허브(카우치베이스 랩/카우치베이스 스프링 캐시
).
이를 활용하여 Spring 프로젝트에 Couchbase 지원 캐싱을 쉽게 도입하는 방법을 살펴보겠습니다!
그리고 캐시
추상화
Spring 프레임워크는 다음과 같은 경량 추상화와 함께 제공됩니다. 캐시
개발자가 클래스의 메서드에 주석을 달아 자동으로 사용할 수 있습니다(예를 들어 리포지토리
고정관념).
Spring의 부팅 캐싱 메커니즘을 사용하려면 메서드에 몇 가지 캐시 관련 어노테이션을 추가하기만 하면 됩니다:
캐시 가능
를 사용하면 특정 입력 매개변수 집합을 가진 주석이 달린 메서드의 첫 번째 호출이 실행되지만 결과는 캐시되고 후속 호출(동일한 집합을 가진)은 캐시에서 투명하게 제공됩니다.캐시풋
는 항상 메서드를 호출하고 그 결과를 캐시합니다(캐시 가능
호출 흐름을 최적화하지 않습니다).캐시이빅트
는 주석이 달린 메서드의 매개변수에서 캐시 키를 계산하고 메서드가 실행될 때 캐시에서 제거합니다(예: 이 메서드를 호출하면 항목이 부실해지기 때문).@캐싱
를 사용하면 이전 어노테이션의 동작을 하나의 어노테이션으로 재그룹화할 수 있습니다.캐시 구성
를 사용하면 전체 클래스에 공통 캐시 매개변수를 설정할 수 있습니다.
카우치베이스 구현
추상적인 메커니즘은 프레임워크에서 제공하지만 실제 뒷받침하는 구현은 선택해야 합니다. Spring에는 몇 가지가 있습니다(메모리에서 지도
, EhCache
, Gemfire
...), 사용자 정의 정의도 가능합니다, 를 구현하는 것만으로 캐시
및 CacheManager
를 사용하여 Spring 컨텍스트에서 표시되도록 합니다..
이것이 바로 카우치베이스-스프링 캐시
.
각 캐시에는 이름이 있고, 캐시의 각 값에는 캐시 키가 있습니다. Couchbase 구현은 이를 반영하는 문서 키로 변환합니다.
- 이것은
캐시
관련 문서(기본적으로 접두사 "캐시:
“) - 특정
캐시
(CACHE_NAME
를 위의 접두사로 추가) - 아래에 특정 캐시 값을 저장합니다.
CACHE_KEY
(그래서 전체적으로 "캐시:캐시_이름:캐시_키
“).
현재 값은 다음과 같아야 합니다. 직렬화 가능
로 저장되며 직렬화 가능 문서
에서 2.x
그러나 향후 대체 트랜스코딩이 제공될 수 있습니다. JSON
/JsonDocument
…
얻기 카우치베이스-스프링 캐시
활용하기
참고:
이 글을 쓰는 시점에서 이 프로젝트는 현재
1.0-스냅샷
버전에서는 사용할 수 없으므로Maven Central
를 아직 지원하지 않습니다. 수동으로 항아리를 빌드하고 로컬 Maven 리포지토리에 추가해야 합니다.
다운로드 및 빌드 카우치베이스-스프링 캐시
프로젝트
먼저 깃허브에서 프로젝트를 복제합니다:
1 2 |
git 복제 https://github.com/couchbaselabs/couchbase-spring-cache.git cd 카우치베이스-봄-캐시 |
그런 다음 Maven을 사용하여 로컬에 빌드하고 설치합니다:
1 |
mvn clean 설치 |
빌드된 버전과 설치 위치를 나타내는 성공 메시지가 표시됩니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[정보] 설치 /경로/에/카우치베이스-봄-캐시/대상/카우치베이스-봄-캐시-<span 스타일="배경색: 노란색">1.0-스냅샷.jar</span> 에 <span 스타일="배경색: 주황색">/경로/에/.m2/저장소/</span><span 스타일="배경색: 밝은 회색">com/카우치베이스/클라이언트/카우치베이스-봄-캐시/1.0-스냅샷/카우치베이스-봄-캐시-1.0-스냅샷.jar</span> [정보] 설치 /경로/에/카우치베이스-봄-캐시/pom.xml 에 /경로/에/.m2/저장소/com/카우치베이스/클라이언트/카우치베이스-봄-캐시/1.0-스냅샷/카우치베이스-봄-캐시-1.0-스냅샷.pom [정보] ------------------------------------------------------------------------ [정보] 빌드 성공 [정보] ------------------------------------------------------------------------ |
튜토리얼 프로젝트 시작하기
Maven을 사용하여 Spring Cache 예제 프로젝트를 빌드하고 스프링 부팅
를 기본으로 합니다.
먼저 원하는 루트 디렉터리에 프로젝트의 디렉터리 구조를 다음과 같이 생성합니다(여기서는 cbcache
여기를 클릭하세요):
1 2 3 4 5 6 7 |
cbcache └── src └── 메인 └── 자바 └── com └── 카우치베이스 └── 데모 |
예를 들어 다음 명령을 사용합니다:
1 2 |
mkdir -p cbcache/src/메인/자바/com/카우치베이스/데모/ cd cbcache |
그런 다음 cbcache 루트에서 POM을 시작하십시오. pom.xml
를 다음과 같은 내용으로 업데이트합니다:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<!--?xml 버전="1.0" 인코딩="UTF-8"?--> 4.0.0 com.카우치베이스.데모 cbcache 0.1.0 org.스프링 프레임워크.boot 봄-boot-스타터-부모 1.3.0.릴리스 1.8 org.스프링 프레임워크.boot 봄-boot-스타터 org.스프링 프레임워크 봄-컨텍스트 <!--의 카우치베이스 캐시 인공물 우리 built 이전--> com.카우치베이스.클라이언트 카우치베이스-봄-캐시 1.0-스냅샷 org.스프링 프레임워크.boot 봄-boot-maven-플러그인 |
도서 관리 엔터티 및 리포지토리 추가하기
예를 들어 예약
리포지토리("시작하기 - Spring으로 데이터 캐싱하기" Spring.io의 공식 가이드).
생성하기 예약
엔티티 클래스의 src/main/java/com/couchbase/demo/Book.java
:
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 31 32 33 34 35 |
가져오기 자바.io.직렬화 가능; public 클래스 예약 구현 직렬화 가능 { 비공개 정적 final long serialVersionUID = -7674163614777124381L; 비공개 문자열 isbn; 비공개 문자열 title; public 예약(문자열 isbn, 문자열 title) { 이.isbn = isbn; 이.title = title; } public 문자열 getIsbn() { 반환 isbn; } public void setIsbn(문자열 isbn) { 이.isbn = isbn; } public 문자열 getTitle() { 반환 title; } public void setTitle(문자열 title) { 이.title = title; } @오버라이드 public 문자열 toString() { 반환 "Book{" + "isbn='" + isbn + ''' + ", title='" + title + ''' + '}'; } } |
참고
예약
클래스는직렬화 가능
는 현재로서는 카우치베이스 스토리지에 중요합니다.
간단한 리포지토리 인터페이스와 지연을 시뮬레이션하는 순진한 구현을 만듭니다:
in src/main/java/com/couchbase/demo/BookRepository.java
:
1 2 3 4 5 6 7 |
패키지 com.카우치베이스.데모; public 인터페이스 도서 저장소 { 예약 getByIsbn(문자열 isbn); } |
in src/main/java/com/couchbase/demo/SimpleBookRepository.java
:
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 31 |
패키지 com.카우치베이스.데모; 가져오기 org.slf4j.로거; 가져오기 org.slf4j.로거 팩토리; 가져오기 org.스프링 프레임워크.고정관념.구성 요소; @구성 요소 public 클래스 간단한 책 저장소 구현 도서 저장소 { 비공개 정적 final 로거 로그 = 로거 팩토리.getLogger(간단한 책 저장소.클래스); @오버라이드 public 예약 getByIsbn(문자열 isbn) { 시뮬레이션 슬로우 서비스(); 예약 결과 = new 예약(isbn, "어떤 책"); 로그.정보("실제 " + isbn); 반환 결과; } // 집에서는 이 작업을 하지 마세요. 비공개 void 시뮬레이션 슬로우 서비스() { 시도 { long 시간 = 5000L; 스레드.수면(시간); } catch (중단된 예외 e) { throw new 불법 상태 예외(e); } } } |
메인 스프링 부팅
애플리케이션
마지막으로, 다음에서 리포지토리를 사용하는 애플리케이션을 만듭니다. src/main/java/com/couchbase/demo/Application.java
:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
패키지 com.카우치베이스.데모; 가져오기 org.slf4j.로거; 가져오기 org.slf4j.로거 팩토리; 가져오기 org.스프링 프레임워크.콩.공장.주석.자동 유선; 가져오기 org.스프링 프레임워크.boot.CommandLineRunner; 가져오기 org.스프링 프레임워크.boot.스프링 애플리케이션; 가져오기 org.스프링 프레임워크.boot.자동 구성.스프링 부팅 애플리케이션; 가져오기 org.스프링 프레임워크.고정관념.구성 요소; @스프링 부팅 애플리케이션 public 클래스 애플리케이션 { 비공개 정적 final 로거 로그 = 로거 팩토리.getLogger(애플리케이션.클래스); @구성 요소 정적 클래스 러너 구현 CommandLineRunner { @자동 유선 비공개 도서 저장소 책 저장소; @오버라이드 public void 실행(문자열... args) 던지기 예외 { long 시작; 로그.정보(".... 책 가져오기"); fetchAndLog("ISBN-1234"); fetchAndLog("ISBN-1234"); fetchAndLog("ISBN-1234"); fetchAndLog("isbn-8888"); fetchAndLog("isbn-8888"); } 비공개 void fetchAndLog(문자열 isbn) { long 시작 = 시스템.currentTimeMillis(); 예약 책 = 책 저장소.getByIsbn(isbn); long 시간 = 시스템.currentTimeMillis() - 시작; 로그.정보(isbn + " --> " + 책 + "에서 " + 시간 + "ms"); } } public 정적 void 메인(문자열[] args) { 스프링 애플리케이션.실행(애플리케이션.클래스, args); } } |
실행하는 경우 애플리케이션
's 메인
메서드를 호출하는 경우 (또는 "MVN 스프링 부팅:실행
"를 명령줄에서 실행하면 모든 호출이 실제로 상당히 느리다는 것을 알 수 있습니다:
1 2 3 4 5 6 7 8 9 10 11 |
[...] .... 가져오기 책 [...] 실제 fetch 의 isbn-1234 [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 5001ms [...] 실제 fetch 의 isbn-1234 [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 5004ms [...] 실제 fetch 의 isbn-1234 [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 5004ms [...] 실제 fetch 의 isbn-8888 [...] isbn-8888 --> 예약{isbn='isbn-8888', title='어떤 책'} in 5003ms [...] 실제 fetch 의 isbn-8888 [...] isbn-8888 --> 예약{isbn='isbn-8888', title='어떤 책'} in 5003ms |
스프링 부트 캐싱 기능 추가
캐싱을 활성화하려면 몇 가지 단계를 수행해야 합니다. 먼저 Spring에 CacheManager
@Bean
…
우리는 CouchbaseCacheManager
(물론)에 연결해야 합니다. 클러스터
를 사용하여 버킷
참조(카우치베이스가 캐시 문서를 저장할 저장소)를 설정합니다.
따라서 CouchbaseCacheManager
사이의 매핑이 필요합니다. 캐시
이름과 해당 버킷
로 전달되어 맵
.
In src/main/java/com/couchbase/demo/Application.java
에 다음 빈 선언을 추가합니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public 정적 final 문자열 BOOK_CACHE = "books"; @Bean(destroyMethod = "연결 끊기") public 클러스터 클러스터() { //이것은 로컬 호스트에서 실행되는 Couchbase 인스턴스에 연결됩니다. 반환 카우치베이스클러스터.create(); } @Bean(destroyMethod = "close") public 버킷 버킷() { //이 버킷은 모든 캐시 관련 데이터가 저장되는 버킷이 됩니다. //버킷 "기본"이 존재해야 합니다. 반환 클러스터().오픈버킷("default", ""); } @Bean public CacheManager 캐시 관리자() { 지도<문자열, 버킷> 매핑 = new 해시맵<문자열, 버킷>(); //이 캐시 관리자가 "books"라는 단일 캐시를 인식하도록 하겠습니다. 매핑.put(BOOK_CACHE, 버킷()); 반환 new CouchbaseCacheManager(매핑); } |
그런 다음 캐시 관련 어노테이션 및 관련 프록시 검색을 활성화하려면 @EnableCaching
주석의 애플리케이션
클래스.
에서 캐싱 활성화 간단한 책 저장소
실제 캐싱을 활성화하는 방법을 살펴보겠습니다. 간단한 책 저장소
를 클릭하고 그 후 애플리케이션이 어떻게 작동하는지 확인합니다.
만들려면 getByIsbn
첫 번째 호출 시 자동으로 캐시에 저장하고 이후 호출에 캐시의 데이터를 제공하려면 다음과 같이 주석을 달기만 하면 됩니다:
1 2 3 4 5 6 7 8 |
@오버라이드 @캐시 가능(애플리케이션.BOOK_CACHE) //앞서 선언한 캐시 이름을 사용합니다. public 예약 getByIsbn(문자열 isbn) { 시뮬레이션 슬로우 서비스(); 예약 결과 = new 예약(isbn, "어떤 책"); 로그.정보("실제 " + isbn); 반환 결과; } |
애플리케이션을 다시 실행하여 이제 어떻게 작동하는지 확인해 보겠습니다:
1 2 3 4 5 6 7 8 |
[...] .... 가져오기 책 [...] 실제 fetch 의 isbn-1234 [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 5022ms [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 3ms [...] isbn-1234 --> 예약{isbn='isbn-1234', title='어떤 책'} in 1ms [...] 실제 fetch 의 isbn-8888 [...] isbn-8888 --> 예약{isbn='isbn-8888', title='어떤 책'} in 5007ms [...] isbn-8888 --> 예약{isbn='isbn-8888', title='어떤 책'} in 1ms |
와우! 첫 번째 호출 이후의 호출에 훨씬 더 좋으며 실제로 캐시 된 것처럼 보입니다 :-)
Couchbase에서 데이터 보기
웹콘솔을 간단히 살펴보고 이러한 뛰어난 타이밍이 Couchbase 덕분인지 확인해 보겠습니다:
- 브라우저에서 새 탭을 열고 다음 위치로 이동합니다.
http://localhost:8091
. - 웹 콘솔에 연결합니다.
- 로 이동하여
데이터 버킷
탭을 클릭하고문서
버튼을 클릭합니다("기본값").
이 화면에 표시되는 내용(빠른 링크 게으른 분들을 위해)도 이와 비슷할 것입니다:
두 책이 모두 카우치베이스에 캐시된 것을 볼 수 있습니다. 캐시:캐시_이름:캐시_키
패턴을 문서 ID에 적용합니다.
결론
이제 Couchbase를 사용하여 간편하게 캐싱할 수 있습니다!
그 외에도 스프링 캐시
가 수행할 수 있는 작업(예: 캐시 키 생성 방법 선택, 조건부 캐싱, 캐시 퇴거 등)과 카우치베이스-스프링 캐시
(예: 캐시 지우기의 경우 관련 문서만 제거하는 보기를 사용하거나, 버킷이 단일 캐시 전용인 경우 플러시
메커니즘...).
이 소개 튜토리얼을 통해 다음을 사용하여 간편한 캐싱에 대한 욕구를 불러 일으켰기를 바랍니다. 스프링 캐시
그리고 카우치베이스
!
다음 단계는 아마도 대체 저장 형식(예: JSON)을 도입하고 아티팩트를 Maven Central 또는 유사한 공개적으로 액세스 가능한 Maven 리포지토리에서 제공하는 것입니다(빈트레이 누구?)...
가까운 시일 내에 봄 관련 소식을 기대해 주세요!
그동안 즐거운 코딩 되세요 :)