[Java] Caffeine Cache๋ž€?

2025. 5. 20. 17:55ยท๐Ÿ’ป Language/Java : ์ž๋ฐ”
728x90

Caffeine์€ Java์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ณ ์„ฑ๋Šฅ ๋กœ์ปฌ ์บ์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, Google์˜ Guava Cache์˜ ๋Œ€์ฒด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด์กŒ์œผ๋ฉฐ, ์„ฑ๋Šฅ(ํžˆํŠธ์œจ๊ณผ ์ฒ˜๋ฆฌ๋Ÿ‰) ๋ฉด์—์„œ ์šฐ์ˆ˜ํ•œ ์บ์‹œ์ด๋‹ค. ๋ถ„์‚ฐ ์„œ๋ฒ„ ๋“ฑ์œผ๋กœ ์ธํ•ด Redis ์‚ฌ์šฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๋ฉด, ๋กœ์ปฌ ์บ์‹œ๋กœ ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

 

Caffeine Cache ํŠน์ง•

์นดํŽ˜์ธ ์บ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ–๋Š”๋‹ค. ๋‚˜๋„ ์ž์„ธํžˆ ๋ชจ๋“  ๊ฑธ ์•Œ์ง„ ๋ชปํ•˜์ง€๋งŒ, Java ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์— ๋กœ์ปฌ ์บ์‹œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜์—ฌ ์ด๋ฒˆ ๊ฐœ๋ฐœ ๊ฑด์— ์ ์šฉํ•ด ๋ณด๋ฉด์„œ ์•Œ์•„๋ณธ ๋‚ด์šฉ์„ ๊ธฐ์ˆ ํ•˜์˜€๋‹ค.

  • ๋†’์€ ์„ฑ๋Šฅ : ConcurrentHashMap๋ณด๋‹ค ๋น ๋ฅด๊ณ , Guava๋ณด๋‹ค 3~10๋ฐฐ ๋น ๋ฅธ ๊ฒฝ์šฐ๋„ ์žˆ์Œ
  • ์ž๋™ ๋งŒ๋ฃŒ : TTL(Time To Live), TTI(Time To Idle) ์ง€์›
  • ์ตœ์‹  ์ ‘๊ทผ ๊ธฐ๋ฐ˜ ์‚ญ์ œ : LRU ๋Œ€์‹  W-TinyLFU ๊ธฐ๋ฐ˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ
  • ๋น„๋™๊ธฐ ๋กœ๋”ฉ ์ง€์› : AsyncLoadingCache ์‚ฌ์šฉ
  • Soft/Weak ์ฐธ์กฐ : ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์‹œ GC์— ์˜ํ•ด ์ œ๊ฑฐ๋˜๋Š” ์บ์‹œ ์„ค์ • ๊ฐ€๋Šฅ
  • ํ†ต๊ณ„ ์ œ๊ณต : ํžˆํŠธ์œจ, ๋กœ๋”ฉ ์‹œ๊ฐ„ ๋“ฑ ํ†ต๊ณ„ ์ˆ˜์ง‘ ๊ฐ€๋Šฅ

 


 

Caffeine Cache ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์˜์กด์„ฑ (Maven)

pom.xml ํŒŒ์ผ์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ ๋’ค ๋นŒ๋“œํ•œ๋‹ค.

<dependency>
  <groupId>com.github.ben-manes.caffeine</groupId>
  <artifactId>caffeine</artifactId>
  <version>3.1.8</version>
</dependency>

 

 

์ฃผ์š” Functions

1) Cache(K, V) - ๊ธฐ๋ณธ ์บ์‹œ

put(K key, V value)

์บ์‹œ์— ๊ฐ’์„ ์ˆ˜๋™์œผ๋กœ ์ €์žฅํ•œ๋‹ค.

cache.put("user1", "ํ™๊ธธ๋™");

 

getIfPresent(K key)

์บ์‹œ์— ํ‚ค๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์—†์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

String name = cache.getIfPresent("user1");  // "ํ™๊ธธ๋™"

 

get(K key, Function<? super K, ? extends V> mappingFunction)

๊ฐ’์ด ์—†์œผ๋ฉด ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅ ํ›„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

String name = cache.get("user2", k -> "๊ธฐ๋ณธ๊ฐ’");

 

invalidate(K key)

ํŠน์ • ํ‚ค์˜ ์บ์‹œ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•œ๋‹ค.

cache.invalidate("user1");

 

invalidateAll()

๋ชจ๋“  ์บ์‹œ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•œ๋‹ค.

cache.invalidateAll();

 

asMap()

์บ์‹œ๋ฅผ ConcurrentMap์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•œ๋‹ค.

cache.asMap().forEach((key, value) -> {
    System.out.println(key + ": " + value);
});

 

 

2) LoadingCache(K, V) - ์ž๋™ ๋กœ๋”ฉ ์บ์‹œ

get(K key)

ํ‚ค๊ฐ€ ์—†์œผ๋ฉด ๋“ฑ๋ก๋œ ๋กœ๋”ฉ ํ•จ์ˆ˜๋กœ ๊ฐ’์„ ์ž๋™ ์ƒ์„ฑ ๋ฐ ์ €์žฅํ•œ๋‹ค.

LoadingCache<String, String> loadingCache = Caffeine.newBuilder()
        .build(key -> "User_" + key);

String user = loadingCache.get("123");  // "User_123"

 

getAll(Iterable<? extends K> keys)

์—ฌ๋Ÿฌ ํ‚ค๋ฅผ ํ•œ ๋ฒˆ์— ๋กœ๋”ฉํ•œ๋‹ค.

Map<String, String> users = loadingCache.getAll(List.of("1", "2"));

 

refresh(K key)

ํ•ด๋‹น ํ‚ค์˜ ๊ฐ’์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์žฌ๋กœ๋”ฉํ•œ๋‹ค.

loadingCache.refresh("123");

 

 

 

3) AsyncLoadingCache<K, V> – ๋น„๋™๊ธฐ ์บ์‹œ

get(K key)

๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ ๋น„๋™๊ธฐ ๋กœ๋”ฉ ํ›„ CompletableFuture๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

AsyncLoadingCache<String, String> asyncCache = Caffeine.newBuilder()
        .buildAsync(key -> CompletableFuture.supplyAsync(() -> "AsyncUser_" + key));

CompletableFuture<String> future = asyncCache.get("123");
future.thenAccept(System.out::println);=

 

getAll(Iterable<? extends K> keys)

์—ฌ๋Ÿฌ ํ‚ค๋ฅผ ํ•œ ๋ฒˆ์— ๋กœ๋”ฉํ•œ๋‹ค.

CompletableFuture<Map<String, String>> allUsers = asyncCache.getAll(List.of("1", "2"));
allUsers.thenAccept(map -> {
    map.forEach((k, v) -> System.out.println(k + ": " + v));
});

 

synchronous()

๋น„๋™๊ธฐ ์บ์‹œ๋ฅผ ๋™๊ธฐ ์บ์‹œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” View์ด๋‹ค.

Cache<String, String> syncView = asyncCache.synchronous();
String value = syncView.getIfPresent("123");

 

 

4) ์„ค์ • ๊ด€๋ จ

maximumSize(long size)

์ตœ๋Œ€ ์บ์‹œ ํ•ญ๋ชฉ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•œ๋‹ค.

Caffeine.newBuilder().maximumSize(1000);

 

expireAfterWrite(long duration, TimeUnit unit)

ํ•ญ๋ชฉ์„ ์ €์žฅํ•œ ํ›„ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋งŒ๋ฃŒ์‹œํ‚จ๋‹ค.

Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES);

 

expireAfterAccess(long duration, TimeUnit unit)

ํ•ญ๋ชฉ์— ์ ‘๊ทผํ•œ ํ›„ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋งŒ๋ฃŒ์‹œํ‚จ๋‹ค.

Caffeine.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES);

 

refreshAfterWrite(long duration, TimeUnit unit)

์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ๋กœ๊ณ ์นจํ•œ๋‹ค. (LoadingCache์—๋งŒ ํ•ด๋‹น).

Caffeine.newBuilder().refreshAfterWrite(5, TimeUnit.MINUTES);

 

recordStats()

ํ†ต๊ณ„ ์ˆ˜์ง‘ (ํžˆํŠธ์œจ, ๋ฏธ์Šค์œจ ๋“ฑ)

Cache<String, String> statsCache = Caffeine.newBuilder()
        .recordStats()
        .build();

CacheStats stats = statsCache.stats();
System.out.println("Hit Rate: " + stats.hitRate());

 

 

์บ์‹œ ๋ฐ์ดํ„ฐ ์กฐํšŒ(get) ๊ด€๋ จ ์ฐจ์ด์ 

์บ์‹œ ๋ฏธ์Šค๋ฅผ ๋ฌด์‹œํ•˜๋Š” ๊ฒฝ์šฐ getIfPresent๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์กฐํšŒ ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด DB์— Accessํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ†ตํ•ด ์บ์‹ฑํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธธ ์›ํ•˜๋Š” ๊ฒฝ์šฐ get์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

getIfPresent(K Key)

๋‹จ์ˆœ ์กฐํšŒ์šฉ ๋ฉ”์„œ๋“œ๋กœ, ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

String val = cache.getIfPresent("id");  // ์—†์œผ๋ฉด null

 

get(K key, Function<K,V> mappingFunction)

์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด ์ƒ์„ฑ ํ›„ ์ €์žฅํ•œ๋‹ค. (Lazy loading)

String val = cache.get("id", k -> "default_" + k);

 

 

 


 

์บ์‹œ ๋งŒ๋ฃŒ ์ •์ฑ…

์นดํŽ˜์ธ ์บ์‹œ์˜ ๋งŒ๋ฃŒ ์ •์ฑ…์„ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • expireAfterWrite : ์บ์‹œ์— ์“ฐ์ธ ํ›„ ์ง€์ • ์‹œ๊ฐ„ ์ง€๋‚˜๋ฉด ๋งŒ๋ฃŒ
  • expireAfterAccess : ๋งˆ์ง€๋ง‰ ์ ‘๊ทผ(์ฝ๊ธฐ/์“ฐ๊ธฐ) ํ›„ ์ง€์ • ์‹œ๊ฐ„ ์ง€๋‚˜๋ฉด ๋งŒ๋ฃŒ
  • refreshAfterWrite : ์ง€์ • ์‹œ๊ฐ„ ํ›„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ๋กœ๊ณ ์นจ

 


 

API ์‚ฌ์šฉ ์˜ˆ์‹œ

1) ๊ธฐ๋ณธ ์บ์‹œ ์ƒ์„ฑ

Cache<String, String> cache = Caffeine.newBuilder()
        .maximumSize(1000)             // ์ตœ๋Œ€ 1000๊ฐœ ์ €์žฅ
        .expireAfterWrite(10, TimeUnit.MINUTES) // ์“ฐ๊ธฐ ํ›„ 10๋ถ„ ๊ฒฝ๊ณผํ•˜๋ฉด ๋งŒ๋ฃŒ
        .build();

2) ๊ฐ’ ์ €์žฅ ๋ฐ ์กฐํšŒ

cache.put("key", "value");
String value = cache.getIfPresent("key");  // ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜

3) ๊ฐ’ ์ž๋™ ๋กœ๋”ฉ

LoadingCache<String, String> loadingCache = Caffeine.newBuilder()
        .maximumSize(100)
        .expireAfterAccess(5, TimeUnit.MINUTES)
        .build(key -> loadFromDB(key)); // ์—†์„ ๋•Œ ์ž๋™ ๋กœ๋”ฉ

String result = loadingCache.get("user123");

4) ๋น„๋™๊ธฐ ์บ์‹œ

AsyncLoadingCache<String, String> asyncCache = Caffeine.newBuilder()
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .buildAsync(key -> loadFromDBAsync(key));

CompletableFuture<String> future = asyncCache.get("user123");

5) ํ†ต๊ณ„ ํ™œ์„ฑํ™”

Cache<String, String> cache = Caffeine.newBuilder()
        .recordStats()
        .build();

CacheStats stats = cache.stats();
System.out.println(stats.hitRate());

 

728x90
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐Ÿ’ป Language > Java : ์ž๋ฐ”' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[E] java: warning: source release 17 requires target release 17  (0) 2025.04.17
[E] Unchecked cast: 'java.lang.Object' to 'java.util.Map<java.lang.String,java.lang.Object>'  (0) 2025.04.15
[Java/JPA] QueryDSL์ด๋ž€?  (0) 2025.03.25
[Java] JDK ์„ค์น˜ (Windows 10, JDK 17)  (0) 2025.03.12
[Java] ๋ฐฑ์ค€ ์˜จ๋ผ์ธ ์ €์ง€ ๋‹จ๊ณ„๋ณ„๋กœ ํ’€์–ด๋ณด๊ธฐ - ์ž…์ถœ๋ ฅ๊ณผ ์‚ฌ์น™์—ฐ์‚ฐ  (0) 2024.11.20
'๐Ÿ’ป Language/Java : ์ž๋ฐ”' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [E] java: warning: source release 17 requires target release 17
  • [E] Unchecked cast: 'java.lang.Object' to 'java.util.Map<java.lang.String,java.lang.Object>'
  • [Java/JPA] QueryDSL์ด๋ž€?
  • [Java] JDK ์„ค์น˜ (Windows 10, JDK 17)
mxnxeonx
mxnxeonx
"์•„, ์ด๊ฑฐ ๋ญ์˜€๋”๋ผ"๋ฅผ ํ•˜์ง€ ์•Š๊ธฐ์œ„ํ•œ ์ผ๊ธฐ์žฅ.
  • mxnxeonx
    MJ's Development Diary
    mxnxeonx
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (158)
      • ๐Ÿ’ป Language (43)
        • Java : ์ž๋ฐ” (18)
        • Python : ํŒŒ์ด์ฌ (9)
        • ROS : ๋กœ๋ด‡์‹œ์Šคํ…œ (9)
        • Android : ์•ˆ๋“œ๋กœ์ด๋“œ (4)
        • JavaScript : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ (2)
      • ๐ŸŒ Environment (19)
        • IDE : ํ†ตํ•ฉ๊ฐœ๋ฐœํ™˜๊ฒฝ (9)
        • Virtual : ๊ฐ€์ƒํ™˜๊ฒฝ (10)
      • โš™ Framework (12)
        • Vue-๋ทฐ (3)
        • Spring-์Šคํ”„๋ง (7)
      • ๐Ÿ’พ DataBase (18)
      • ๐ŸŒŒ OS (36)
        • Linux-๋ฆฌ๋ˆ…์Šค (36)
      • ๐Ÿ’ฌ CI · CD (7)
        • Git : ๊นƒ (7)
      • ๐Ÿ“ƒ ETC (6)
      • ๐Ÿค– AI (5)
  • ๋งํฌ

    • GitHub
  • ์ธ๊ธฐ ๊ธ€

  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
mxnxeonx
[Java] Caffeine Cache๋ž€?
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”