콘텐츠로 이동
Exposed 문서1.11

Exposed JDBC Lettuce 캐시

최신 안정판 Exposed 1.11.0 릴리스 기준

이 어댑터는 동기 JDBC 경로와, 코루틴 호출을 지원하는 별도의 suspend 저장소를 Lettuce 기반 Redis에 연결합니다. 수명주기와 영속성 선택을 감추지 않으면서 공통 캐시 저장소 계약을 구현합니다.

캐시 미스, 쓰기, 무효화, 타임아웃, 취소, 종료가 일부만 끝나면 캐시와 DB 상태가 달라집니다. 이 모듈은 연결 코드를 제공하지만, 어느 정도의 오래된 값과 실패를 허용할지는 애플리케이션이 정해야 합니다.

캐시 백엔드로 Lettuce 기반 Redis를 선택했고, 동기 JDBC와 코루틴용 suspend 저장소를 같이 제공해야 할 때 사용합니다. 인프라를 추가하기 전에 캐시 선택 가이드에서 여섯 어댑터를 비교하세요.

dependencies {
implementation(platform("io.github.bluetape4k:bluetape4k-dependencies:<version>"))
implementation("io.github.bluetape4k.exposed:bluetape4k-exposed-jdbc-lettuce")
}

사용자가 선택할 버전은 중앙 BOM 버전 하나입니다. 이 페이지는 안정 배포본 1.11 소스 계보를 기록합니다.

getgetAll은 Read-through 연산입니다. Cache-aside는 애플리케이션이 DB를 바꾼 뒤 캐시를 무효화하는 방식입니다. 진짜 Write-through는 설정한 writer가 DB 쓰기를 마친 뒤 반환합니다. Write-behind는 영속화를 미룹니다. writer 정책을 확인하지 않은 평범한 put을 Write-through라고 부르면 안 됩니다. 이 어댑터는 동기 저장소는 원격 map을 쓰고 suspend 저장소만 설정한 Caffeine Near Cache를 덧붙일 수 있습니다.

AbstractJdbcLettuceRepository를 상속하고 table, extractId, ResultRow.toEntity, update/insert DSL hook을 구현한 뒤 검토한 LettuceCacheConfig로 생성합니다.

repository.use { repo ->
val current = repo.get(id) // 미스 -> DB loader -> 캐시
current?.let { repo.put(id, it) } // 영속성은 쓰기 모드가 결정
repo.invalidate(id) // 기본값은 캐시만 제거
}
작업API
캐시 조회containsKey, get, getAll
DB 직접 조회findByIdFromDb, findAllFromDb, countFromDb
정책에 따른 쓰기put, putAll
무효화invalidate, invalidateAll, clear
엔티티 매핑ResultRow.toEntity, extractId, update/insert hook
수명주기close

캐시 이름 공간마다 저장소 하나를 두고 애플리케이션과 함께 닫으세요. Cache-aside에서는 DB 트랜잭션 커밋 뒤 무효화합니다. Write-through 실패는 쓰기가 끝나지 않은 상태입니다. Write-behind를 켜기 전에는 큐·dead-letter 상태와 종료 drain 시간을 노출하세요. 키 접두사와 직렬화 형식은 안정적으로 유지해야 합니다.

이 모듈은 Exposed JDBC, 공통 캐시 기반 모듈, Lettuce 기반 Redis를 연결합니다. loader·writer가 캐시와 테이블 사이를 맡고, 애플리케이션이 서비스 트랜잭션과 클라이언트 수명주기를 소유합니다.

LettuceCacheConfig가 이름 공간, TTL·만료, 캐시·쓰기 모드, 백엔드 제한을 정합니다. 명시적인 RedisCodec<String, E>가 필요하며, 코덱 변경은 저장 데이터 마이그레이션입니다. 시작할 때 시간이 양수인지, 배치와 큐 크기가 제한되어 있는지 확인하세요.

Redis 타임아웃·재시도와 DB 실패는 서로 다른 상태입니다. Write-behind는 제한된 채널과 재시도·dead-letter 처리를 사용합니다. 캐시 hit도 오래된 값일 수 있고, 백엔드 성공 뒤 DB가 실패할 수 있으며, DB 커밋 뒤 무효화가 실패할 수도 있습니다. 이 상태를 하나의 캐시 오류로 뭉개지 말고 따로 기록하세요.

애플리케이션이 RedisClient를 소유하고 저장소는 자신이 연 연결만 닫습니다. 공유 클라이언트는 따로 닫아야 합니다. hit/miss, 백엔드 지연, 재시도·타임아웃, 큐 깊이, 거부·dead-letter 쓰기, 무효화 지연, 종료 drain을 관찰합니다. 캐시와 DB 경로의 SLO도 따로 잡아야 합니다.

격리한 캐시와 DB fixture에 고유한 이름 공간을 사용합니다. 미스 로딩, getAll 일부 미스, 켠 쓰기 모드, 캐시 전용 무효화, TTL, 부분 실패, 수명주기 정리를 검증하세요.

Terminal window
./gradlew :bluetape4k-exposed-jdbc-lettuce:test
  1. Exposed 캐시 기반 라이브러리에서 공통 계약을 익힙니다.
  2. 캐시 선택 가이드에서 백엔드를 고릅니다.
  3. Read-through와 캐시 전용 무효화를 먼저 구현합니다.
  4. Near Cache나 Write-behind 전에 부분 실패와 종료 테스트를 추가합니다.
  5. exposed-workshop에서 실행 가능한 구성을 살펴봅니다.

이 어댑터는 분산 트랜잭션을 만들거나 백엔드를 설치하지 않습니다. 저장 데이터를 마이그레이션하거나 오래된 값을 허용할지도 대신 정하지 않습니다. 동기 저장소는 원격 map을 쓰고 suspend 저장소만 설정한 Caffeine Near Cache를 덧붙일 수 있습니다.

아래 그림은 1.11.0 배포본의 README 자산을 해당 배포 커밋에서 직접 불러옵니다. 이후 SNAPSHOT이 아니라 이 매뉴얼 버전의 구조와 실행 흐름을 보여 줍니다. 미리보기를 누르면 같은 배포 커밋의 SVG 원본이 열립니다.

JDBC Lettuce Redis cache 아키텍처

배포본 README: exposed/jdbc-lettuce/README.ko.md

JDBC Lettuce cache 처리 흐름

배포본 README: exposed/jdbc-lettuce/README.ko.md