Files
llm-wiki/raw/official-docs/cache-caffeine-asyncloadingcache-readme.md
T

117 lines
11 KiB
Markdown

---
title: Caffeine — AsyncLoadingCache & cache stampede prevention (GitHub Wiki — Population)
source_type: official-doc
url: https://github.com/ben-manes/caffeine/wiki/Population
archive_url:
status: raw
confidence: high
tags: [ca-cache-consistency, caffeine, local-cache, stampede, single-instance, official-doc]
related_branches: [feature-cache-consistency-contract]
related_projects: [ca-skeleton]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# Caffeine — AsyncLoadingCache & cache stampede prevention
> Layer: `raw/official-docs/` — Caffeine GitHub Wiki "Population" 페이지 (verbatim 발췌) + 관련 보조 인용 (`Refresh`, Spring `@Cacheable` Javadoc).
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-cache-consistency-contract]] | ca-tmpl single-instance stampede 방지에 Caffeine `LoadingCache` / `AsyncLoadingCache` 또는 Spring `@Cacheable(sync=true)` 채택 근거 |
## 컨텍스트 / 왜 저장했는지
ca-tmpl single-instance stampede 방지 결정 **"Caffeine local lock"** 의 근거. `LoadingCache` / `AsyncLoadingCache` 의 stampede 방지 메커니즘과 Spring `@Cacheable sync=true` 와의 관계를 명시.
## 출처 / Source
- 원본 URL (Wiki "Population" 페이지): https://github.com/ben-manes/caffeine/wiki/Population
- 보조 페이지: Caffeine Wiki — "Refresh", "Specification"
- 보조 자료: Spring Framework `@Cacheable` Javadoc (`sync` attribute)
- 저자 / 조직: Ben Manes (Caffeine 저자) / Caffeine project
- 발행일: 지속 갱신 (GitHub Wiki)
- 마지막 확인일: 2026-05-27
## 핵심 인용 / Key quotes (verbatim)
**Caffeine Wiki "Population" — 2026-05-27 fetch 로 확인된 인용**:
> [§LoadingCache] "A `LoadingCache` is a `Cache` built with an attached `CacheLoader`."
> [§AsyncLoadingCache] "A `AsyncLoadingCache` is a `AsyncCache` built with an attached `AsyncCacheLoader`."
> [§Asynchronous Computation] "A `AsyncCache` is a `Cache` variant that computes entries on an `Executor` and returns a `CompletableFuture`."
> [§CacheLoader Options] "A `CacheLoader` should be supplied when the computation is best expressed in a synchronous fashion." / "Alternatively, a `AsyncCacheLoader` should be supplied when the computation is expressed asynchronously and returns a `CompletableFuture`."
> [§Bulk Operations] "By default, `getAll` will issue a separate call to `CacheLoader.load` for each key which is absent from the cache."
**보조 인용 (별도 페이지 — 본 fetch 로는 verbatim 미확인, 원래 raw 작성 시점 수집본 보존)**:
> [Caffeine Wiki "Refresh" — needs-confirmation] "`refreshAfterWrite` reloads asynchronously, returning the old value during reload. Combined with `AsyncLoadingCache`, refresh does not block readers." *(2026-05-27 Wiki Population fetch 에서는 verbatim 미확인 — Refresh 별도 페이지 재확인 필요)*
> [Spring Framework `@Cacheable` Javadoc — `sync` attribute] "`sync=true` instructs the cache abstraction to synchronize the invocation of the underlying method, if several threads are attempting to load a value for the same key. Only one invocation is performed; others wait." *(별도 출처 — Caffeine wiki 가 아님)*
## Claims Extracted / 추출된 주장
> 본 raw 의 1차 출처는 Caffeine Wiki "Population". `CAFFEINE-POP-C*` prefix.
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| CAFFEINE-POP-C1 | `LoadingCache` = `CacheLoader` 가 attach 된 `Cache` 변형 | [§LoadingCache] "A `LoadingCache` is a `Cache` built with an attached `CacheLoader`." | `official-vendor-doc` | Caffeine 2.x/3.x `LoadingCache` API 사용 | "동일 key 동시 miss 시 single load 직렬화" 메커니즘 자체는 본 인용으로 직접 증명 안 됨 — 별도 Caffeine 동작 명세 또는 `CacheLoader.load` 계약 확인 필요 |
| CAFFEINE-POP-C2 | `AsyncLoadingCache` = `AsyncCacheLoader` 가 attach 된 `AsyncCache` 변형 | [§AsyncLoadingCache] "A `AsyncLoadingCache` is a `AsyncCache` built with an attached `AsyncCacheLoader`." | `official-vendor-doc` | Caffeine async API 사용 | in-flight `CompletableFuture` 가 같은 key 동시 요청에 공유되는지 / 실패 future 의 자동 제거 여부는 본 인용 범위 밖 |
| CAFFEINE-POP-C3 | `AsyncCache``Executor` 위에서 entry 를 계산하고 `CompletableFuture` 를 반환 | [§Asynchronous Computation] "A `AsyncCache` is a `Cache` variant that computes entries on an `Executor` and returns a `CompletableFuture`." | `official-vendor-doc` | Caffeine `AsyncCache.get(key, loader)` 호출 | Executor 의 기본 구현 (ForkJoinPool 등) 은 본 인용으로 명시 안 됨 — Caffeine `Specification` 페이지 별도 확인 |
| CAFFEINE-POP-C4 | 계산이 동기적이면 `CacheLoader`, 비동기적이고 `CompletableFuture` 반환이면 `AsyncCacheLoader` 사용 | [§CacheLoader Options] "A `CacheLoader` should be supplied when the computation is best expressed in a synchronous fashion." / "Alternatively, a `AsyncCacheLoader` should be supplied when the computation is expressed asynchronously and returns a `CompletableFuture`." | `official-vendor-doc` | loader 선택 결정 | "어느 쪽이 stampede 방지 측면에서 더 강력한지" 는 본 인용 범위 밖 |
| CAFFEINE-POP-C5 | `getAll` 의 기본 동작은 cache 에 없는 각 key 에 대해 `CacheLoader.load` 를 개별 호출 | [§Bulk Operations] "By default, `getAll` will issue a separate call to `CacheLoader.load` for each key which is absent from the cache." | `official-vendor-doc` | Caffeine `Cache.getAll(keys)` 호출 | bulk load 최적화 (예: `loadAll` override) 의 효과는 본 인용으로 직접 증명 안 됨 |
| CAFFEINE-POP-C6 | `refreshAfterWrite` 는 비동기 reload, 진행 중 old value 반환. `AsyncLoadingCache` 와 결합 시 reader 를 block 하지 않음 | [Wiki "Refresh"] "`refreshAfterWrite` reloads asynchronously, returning the old value during reload. Combined with `AsyncLoadingCache`, refresh does not block readers." | `needs-confirmation` *(원 raw 수집본; 2026-05-27 Population 페이지 fetch 에서는 verbatim 미발견 — Refresh 별도 페이지 재fetch 필요)* | Caffeine refresh 모드 | reload 실패 시 old value 의 유효 기간은 본 인용 범위 밖 |
| SPRING-CACHEABLE-C1 | Spring `@Cacheable(sync=true)` 는 같은 key 에 대해 여러 thread 가 동시에 load 시도할 때 underlying method 호출을 1회로 동기화. 나머지는 대기 | [Spring `@Cacheable` Javadoc — `sync` attribute] "`sync=true` instructs the cache abstraction to synchronize the invocation of the underlying method, if several threads are attempting to load a value for the same key. Only one invocation is performed; others wait." | `official-vendor-doc` *(Spring Framework reference Javadoc; Caffeine wiki 아님)* | Spring Cache abstraction 사용 + Caffeine backend | 이 동기화가 Caffeine 내부 lock 으로 위임되는지 vs Spring 자체 lock 인지는 본 인용으로 직접 증명 안 됨 — Spring `CaffeineCache` 구현 확인 필요 |
### Strength 적용 메모
- `official-vendor-doc`: Caffeine GitHub Wiki 는 저자 (Ben Manes) 가 직접 유지하는 공식 문서. official-standard (RFC) 가 아니므로 한 단계 아래.
- `needs-confirmation`: 본 fetch 에서 verbatim 으로 확인 불가능한 인용. 원 raw 작성 시점 수집본을 보존하되 별도 fetch 로 재확인 필요.
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `CAFFEINE-POP-C1~C5`: Caffeine `LoadingCache`/`AsyncLoadingCache` 의 API 형태 + `getAll` 기본 동작
- `SPRING-CACHEABLE-C1`: Spring `@Cacheable(sync=true)` 의 동기화 의미 (Spring Javadoc 기준)
- **이 자료가 증명하지 않는 것**:
- **Caffeine `LoadingCache` 가 동일 key 동시 miss 시 backend 호출을 정확히 1회로 직렬화한다는 보장**: 본 Population 페이지 fetch 에서 verbatim 인용 미확보. ca-tmpl `Required test` 검증 시 별도 동작 테스트 + Caffeine source 코드 (`BoundedLocalCache#doComputeIfAbsent`) 확인 필요
- in-flight `CompletableFuture` 공유 / 실패 future 자동 제거 메커니즘: 본 fetch 범위 밖
- Spring `@Cacheable(sync=true)` 가 Caffeine backend 와 결합 시 어느 layer 에서 lock 이 걸리는지 (Spring 자체 lock vs Caffeine 내부): 별도 검증 필요
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl `Required test` ("동일 key 동시 cache miss → backend 호출 1회") 의 actual 검증
- multi-instance 환경에서 본 메커니즘이 적용 안 되는 점 (instance 별 별도 load) — Redisson RLock 등 분산 잠금으로 승격 필요한 분기
## 메모 / Notes (내 프로젝트 해석 — PRESERVED)
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. 원 raw 의 해석을 보존하되 verifiability gap 을 명시.
- single-instance stampede 방지 mechanism:
- **Caffeine `LoadingCache` 자체가 같은 key 에 대한 동시 load 를 1회로 직렬화 (널리 알려진 동작이나, 본 Population 페이지 fetch 만으로는 verbatim 증거 없음 — `needs-confirmation`)**. 외부 lock 불필요.
- Spring abstraction 을 쓸 때는 `@Cacheable(sync=true)` 로 동등 효과. 내부적으로 Caffeine `get(key, loader)` 가 호출됨 (Spring `CaffeineCache` 구현 가정 — 본 raw 자료로 직접 증명 안 됨).
- ca-tmpl `Required test` 와의 정합성:
- "동일 key 에 대해 동시 cache miss 시 backend 호출 1회로 제한" 검증 → Caffeine `LoadingCache` 또는 `@Cacheable(sync=true)` 둘 다 통과 가정.
- test 에서 명시한 (a) `sync=true` 또는 (b) `AsyncLoadingCache` 또는 (c) Redisson RLock wrap 분기 중 **(a)(b) 가 Caffeine 분기**, (c) 가 multi-instance 분기.
- 장점:
- in-process, network round-trip 없음 → 1µs급 hit latency.
- Window TinyLFU eviction policy 로 LRU 보다 hit-rate 우수 (Caffeine 논문 인용 영역 — 본 wiki 페이지 직접 증명 아님).
- 단점 (ca-tmpl 입장):
- **multi-instance** 에서는 의미 없음 — instance 별로 별도 load 가 일어남. HPA 환경에서는 RLock 으로 승격 필요.
- JVM restart 시 cache cold start. 안 가져갈 hot key 가 cold path 를 거치면 backend burst.
- 시사점: ca-tmpl 의 "single-instance Caffeine, multi-instance Redisson" 분기는 **scope 에 맞춘 도구 차등화**. write-back/distributed mode 를 Caffeine 에 요구하지 않음 (out of scope).
## Related / 관련
- 같은 주제 다른 raw:
- (Caffeine `Refresh` / `Specification` 별도 페이지 — 미작성)
- 인용하는 branch:
- [[raw/branch-notes/feature-cache-consistency-contract]]
- 적용 contract:
- [[raw/project-notes/ca-skeleton-operational-contract]] (Cache consistency 그룹)
- 인용하는 wiki: (미작성)