Skip to content

ScriptonBasestar/sb-cached-collection

Repository files navigation

SB Cached Collection

Java Maven Spring License

ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ Java ์บ์‹œ ํ”„๋ ˆ์ž„์›Œํฌ

SB Cached Collection์€ TTL, ์ถ•์ถœ ์ •์ฑ…, ๋‹ค์–‘ํ•œ ์ฐธ์กฐ ํƒ€์ž…, Write-Through/Write-Behind, Refresh-Ahead ์ „๋žต์„ ์ง€์›ํ•˜๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ์บ์‹œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.


๐ŸŒŸ ์ฃผ์š” ํŠน์ง•

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  • โœ… TTL (Time To Live): ์ž๋™ ๋งŒ๋ฃŒ ๋ฐ ๊ฐฑ์‹ 
  • โœ… ๋‹ค์–‘ํ•œ ์ถ•์ถœ ์ •์ฑ…: LRU, LFU, FIFO, RANDOM, TTL
  • โœ… Reference ํƒ€์ž… ์ง€์›: STRONG, SOFT, WEAK (GC ํ˜‘๋ ฅ)
  • โœ… ๋กœ๋”ฉ ์ „๋žต: SYNC, ASYNC (Thundering Herd ๋ฐฉ์ง€)
  • โœ… ์“ฐ๊ธฐ ์ „๋žต: READ_ONLY, WRITE_THROUGH, WRITE_BEHIND
  • โœ… ๊ฐฑ์‹  ์ „๋žต: ON_MISS, REFRESH_AHEAD
  • โœ… ์Šค๋ ˆ๋“œ ์•ˆ์ „: ConcurrentHashMap ๊ธฐ๋ฐ˜ ๊ณ ์„ฑ๋Šฅ
  • โœ… Spring ํ†ตํ•ฉ: CacheManager, @Cacheable ์ง€์›
  • โœ… ํ†ต๊ณ„ ์ˆ˜์ง‘: Hit Rate, Load Time, Metrics

์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๊ธฐ๋Šฅ

  • ๐Ÿš€ ์บ์‹œ ์›Œ๋ฐ์—…: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์‚ฌ์ „ ๋กœ๋”ฉ
  • ๐Ÿ”„ Write-Through/Write-Behind: ๋ฐฑ์—”๋“œ ์ €์žฅ์†Œ ๋™๊ธฐํ™”
  • โšก Refresh-Ahead: ๋งŒ๋ฃŒ ์ „ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฐฑ์‹ 
  • ๐Ÿ“Š JMX/Prometheus ํ†ตํ•ฉ: ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง
  • ๐Ÿ”Œ ํ™•์žฅ ๊ฐ€๋Šฅ: Loader, Writer, EvictionStrategy ์ปค์Šคํ„ฐ๋งˆ์ด์ง•
  • ๐Ÿ›ก๏ธ ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „: MaxSize, Reference ํƒ€์ž…์œผ๋กœ OOM ๋ฐฉ์ง€

๐Ÿ“ฆ Quick Start

Maven ์˜์กด์„ฑ

<dependency>
    <groupId>org.scriptonbasestar.cache</groupId>
    <artifactId>cache-collection</artifactId>
    <version>sb-cache-20251107-1-DEV</version>
</dependency>

<!-- Spring ํ†ตํ•ฉ (์„ ํƒ ์‚ฌํ•ญ) -->
<dependency>
    <groupId>org.scriptonbasestar.cache</groupId>
    <artifactId>cache-spring</artifactId>
    <version>sb-cache-20251107-1-DEV</version>
</dependency>

30์ดˆ ๋งŒ์— ์‹œ์ž‘ํ•˜๊ธฐ

// 1. Loader ์ •์˜ (๋ฐ์ดํ„ฐ ์†Œ์Šค)
SBCacheMapLoader<Long, User> loader = new SBCacheMapLoader<>() {
    @Override
    public User loadOne(Long id) throws SBCacheLoadFailException {
        return userRepository.findById(id)
            .orElseThrow(() -> new SBCacheLoadFailException("User not found: " + id));
    }

    @Override
    public Map<Long, User> loadAll() throws SBCacheLoadFailException {
        return userRepository.findAll().stream()
            .collect(Collectors.toMap(User::getId, user -> user));
    }
};

// 2. ์บ์‹œ ์ƒ์„ฑ (5๋ถ„ TTL, ์ตœ๋Œ€ 1,000๊ฐœ, LRU)
SBCacheMap<Long, User> cache = SBCacheMap.<Long, User>builder()
    .loader(loader)
    .timeoutSec(300)
    .maxSize(1000)
    .evictionPolicy(EvictionPolicy.LRU)
    .enableMetrics(true)
    .build();

// 3. ์‚ฌ์šฉ
User user = cache.get(123L);  // ์ฒซ ํ˜ธ์ถœ: DB ์กฐํšŒ
User cached = cache.get(123L);  // ๋‘ ๋ฒˆ์งธ: ์บ์‹œ ํžˆํŠธ

// 4. ํ†ต๊ณ„ ํ™•์ธ
System.out.println("Hit Rate: " + cache.getHitRate());
System.out.println("Average Load Time: " + cache.getAverageLoadTime() + "ms");

๐Ÿ“š ๋ฌธ์„œ

  • ๐Ÿ“– USER_GUIDE.md - ์ข…ํ•ฉ ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ

    • Quick Start, ํ•ต์‹ฌ ๊ฐœ๋…, ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ
    • ์‹ค์ „ ์˜ˆ์ œ (User Profile, API Response, Product Catalog)
    • ์„ฑ๋Šฅ ํŠœ๋‹, ๋ชจ๋‹ˆํ„ฐ๋ง, ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…
  • ๐Ÿ”— SPRING_INTEGRATION.md - Spring ํ†ตํ•ฉ ๊ฐ€์ด๋“œ

    • CacheManager ์„ค์ •, @Cacheable ์‚ฌ์šฉ๋ฒ•
    • Auto-Configuration (YAML/Properties)
    • Actuator ํ†ตํ•ฉ, 4๊ฐ€์ง€ ์‹ค์ „ ์˜ˆ์ œ
  • ๐Ÿ“– API_REFERENCE.md - ์ „์ฒด API ๋ ˆํผ๋Ÿฐ์Šค

    • ๋ชจ๋“  ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค/Enum ์ƒ์„ธ ์„ค๋ช…
    • ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜, ํŒŒ๋ผ๋ฏธํ„ฐ, ๋ฐ˜ํ™˜๊ฐ’
    • 5๊ฐ€์ง€ ์‚ฌ์šฉ ์˜ˆ์‹œ
  • ๐Ÿ—๏ธ ARCHITECTURE.md - ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

    • ๋ชจ๋“ˆ ๊ตฌ์กฐ, ๋ ˆ์ด์–ด ์•„ํ‚คํ…์ฒ˜
    • 5๊ฐ€์ง€ ๋””์ž์ธ ํŒจํ„ด, ํ™•์žฅ ํฌ์ธํŠธ
    • ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ, ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ, ์„ฑ๋Šฅ ์ตœ์ ํ™”

๐Ÿ”ฅ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ƒ์„ธ

1. ReferenceType (๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ)

๋ฉ”๋ชจ๋ฆฌ ์••๋ฐ•์— ๋Œ€์‘ํ•˜๋Š” 3๊ฐ€์ง€ ์ฐธ์กฐ ํƒ€์ž…:

// STRONG: ๋ช…์‹œ์  ์ œ๊ฑฐ ์ „๊นŒ์ง€ ์œ ์ง€ (๊ธฐ๋ณธ๊ฐ’)
SBCacheMap<String, Config> configCache = SBCacheMap.<String, Config>builder()
    .timeoutSec(3600)
    .referenceType(ReferenceType.STRONG)
    .build();

// SOFT: ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์‹œ GC๊ฐ€ ํšŒ์ˆ˜ (๋Œ€์šฉ๋Ÿ‰ ์บ์‹œ)
SBCacheMap<String, byte[]> imageCache = SBCacheMap.<String, byte[]>builder()
    .timeoutSec(3600)
    .referenceType(ReferenceType.SOFT)  // OOM ๋ฐฉ์ง€
    .build();

// WEAK: ๋‹ค์Œ GC์—์„œ ํšŒ์ˆ˜ (์ž„์‹œ ์บ์‹œ)
SBCacheMap<String, Report> tempCache = SBCacheMap.<String, Report>builder()
    .timeoutSec(60)
    .referenceType(ReferenceType.WEAK)  // ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ
    .build();

2. EvictionPolicy (์ถ•์ถœ ์ •์ฑ…)

MaxSize ์ดˆ๊ณผ ์‹œ ์–ด๋–ค ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ• ์ง€ ๊ฒฐ์ •:

// LRU: ๊ฐ€์žฅ ์ตœ๊ทผ์— ์‚ฌ์šฉ๋˜์ง€ ์•Š์€ ํ•ญ๋ชฉ ์ œ๊ฑฐ (๊ธฐ๋ณธ๊ฐ’)
SBCacheMap<Long, User> lruCache = SBCacheMap.<Long, User>builder()
    .maxSize(10000)
    .evictionPolicy(EvictionPolicy.LRU)
    .build();

// LFU: ๊ฐ€์žฅ ์ ๊ฒŒ ์‚ฌ์šฉ๋œ ํ•ญ๋ชฉ ์ œ๊ฑฐ
SBCacheMap<String, Product> lfuCache = SBCacheMap.<String, Product>builder()
    .maxSize(5000)
    .evictionPolicy(EvictionPolicy.LFU)  // ์ธ๊ธฐ๋„ ๊ธฐ๋ฐ˜
    .build();

// FIFO: ๊ฐ€์žฅ ๋จผ์ € ์ถ”๊ฐ€๋œ ํ•ญ๋ชฉ ์ œ๊ฑฐ
// RANDOM: ๋ฌด์ž‘์œ„ ํ•ญ๋ชฉ ์ œ๊ฑฐ
// TTL: ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ํ•ญ๋ชฉ ์ œ๊ฑฐ

3. LoadStrategy (๋กœ๋”ฉ ์ „๋žต)

์บ์‹œ ๋ฏธ์Šค ์‹œ ๋กœ๋”ฉ ๋ฐฉ์‹:

// SYNC: ๋™๊ธฐ ๋กœ๋”ฉ (๊ธฐ๋ณธ๊ฐ’)
SBCacheMap<String, Data> syncCache = SBCacheMap.<String, Data>builder()
    .loader(dataLoader)
    .loadStrategy(LoadStrategy.SYNC)
    .build();

// ASYNC: ๋น„๋™๊ธฐ ๋กœ๋”ฉ (Thundering Herd ๋ฐฉ์ง€)
SBCacheMap<String, Report> asyncCache = SBCacheMap.<String, Report>builder()
    .loader(reportLoader)
    .loadStrategy(LoadStrategy.ASYNC)  // ์ค‘๋ณต ๋กœ๋”ฉ ๋ฐฉ์ง€
    .build();

// ASYNC ๋™์ž‘:
// Thread 1: miss โ†’ load โ†’ return
// Thread 2: miss โ†’ wait โ†’ (Thread 1 ์™„๋ฃŒ) โ†’ return
// Thread 3: miss โ†’ wait โ†’ (Thread 1 ์™„๋ฃŒ) โ†’ return
// ๊ฒฐ๊ณผ: 1๋ฒˆ๋งŒ ๋กœ๋”ฉ (ํšจ์œจ์ )

4. WriteStrategy (์“ฐ๊ธฐ ์ „๋žต)

์บ์‹œ์™€ ๋ฐฑ์—”๋“œ ์ €์žฅ์†Œ ๋™๊ธฐํ™”:

// WRITE_THROUGH: ๋™๊ธฐ ์“ฐ๊ธฐ (์ฆ‰์‹œ ์˜์†ํ™”)
SBCacheMap<Long, User> writeThrough = SBCacheMap.<Long, User>builder()
    .loader(userLoader)
    .writer(userWriter)
    .writeStrategy(WriteStrategy.WRITE_THROUGH)
    .build();

writeThrough.put(123L, user);  // ์บ์‹œ + DB ๋™์‹œ ์“ฐ๊ธฐ

// WRITE_BEHIND: ๋น„๋™๊ธฐ ์“ฐ๊ธฐ (์„ฑ๋Šฅ ์šฐ์„ ) + ์žฌ์‹œ๋„ ๋กœ์ง
SBCacheMap<String, Session> writeBehind = SBCacheMap.<String, Session>builder()
    .loader(sessionLoader)
    .writer(sessionWriter)
    .writeStrategy(WriteStrategy.WRITE_BEHIND)  // ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ
    .writeBehindBatchSize(100)             // 100๊ฐœ์”ฉ ๋ฐฐ์น˜
    .writeBehindIntervalSeconds(5)         // 5์ดˆ๋งˆ๋‹ค ํ”Œ๋Ÿฌ์‹œ
    .writeBehindMaxRetries(3)              // ์‹คํŒจ ์‹œ ์ตœ๋Œ€ 3ํšŒ ์žฌ์‹œ๋„
    .writeBehindRetryDelayMs(1000)         // ์žฌ์‹œ๋„ ๊ฐ„๊ฒฉ 1์ดˆ
    .build();

writeBehind.put("session1", session);  // ์บ์‹œ์—๋งŒ ์“ฐ๊ณ  ์ฆ‰์‹œ ๋ฐ˜ํ™˜
// ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋‚˜์ค‘์— DB ๋ฐ˜์˜ (์‹คํŒจ ์‹œ ์ž๋™ ์žฌ์‹œ๋„)

5. RefreshStrategy (๊ฐฑ์‹  ์ „๋žต)

์บ์‹œ ํ•ญ๋ชฉ ๊ฐฑ์‹  ๋ฐฉ์‹:

// ON_MISS: ๋ฏธ์Šค ์‹œ์—๋งŒ ๊ฐฑ์‹  (๊ธฐ๋ณธ๊ฐ’)
SBCacheMap<String, Config> onMiss = SBCacheMap.<String, Config>builder()
    .loader(configLoader)
    .refreshStrategy(RefreshStrategy.ON_MISS)
    .build();

// REFRESH_AHEAD: ๋ฏธ๋ฆฌ ๊ฐฑ์‹  (ํ•ญ์ƒ ์‹ ์„ ํ•œ ๋ฐ์ดํ„ฐ)
SBCacheMap<String, StockPrice> refreshAhead = SBCacheMap.<String, StockPrice>builder()
    .loader(stockPriceLoader)
    .timeoutSec(60)  // 1๋ถ„ TTL
    .refreshStrategy(RefreshStrategy.REFRESH_AHEAD)  // 30์ดˆ ํ›„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฐฑ์‹ 
    .build();

// REFRESH_AHEAD ๋™์ž‘:
// T=0: cache.get(key) โ†’ miss โ†’ load โ†’ return
// T=30: cache.get(key) โ†’ hit (์ฆ‰์‹œ ๋ฐ˜ํ™˜) + ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฐฑ์‹  ์‹œ์ž‘
// T=60: cache.get(key) โ†’ hit (์ด๋ฏธ ๊ฐฑ์‹ ๋จ, ์ฆ‰์‹œ ๋ฐ˜ํ™˜)

๐Ÿ”Œ Spring Framework ํ†ตํ•ฉ

@Cacheable ์–ด๋…ธํ…Œ์ด์…˜

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new SBCacheManager()
            .addCache("users", SBCacheMap.<Object, Object>builder()
                .timeoutSec(300)
                .maxSize(1000)
                .evictionPolicy(EvictionPolicy.LRU)
                .referenceType(ReferenceType.SOFT)
                .enableMetrics(true)
                .build());
    }
}

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }

    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

Spring Boot Auto-Configuration

application.yml:

sb:
  cache:
    enabled: true
    caches:
      users:
        timeout-sec: 300
        max-size: 1000
        eviction-policy: LRU
        reference-type: SOFT
        enable-metrics: true
      products:
        timeout-sec: 600
        max-size: 5000
        eviction-policy: LFU
        reference-type: STRONG

๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง & Actuator

Health Indicator

GET /actuator/health:

{
  "status": "UP",
  "components": {
    "sbCache": {
      "status": "UP",
      "details": {
        "users": {
          "status": "UP",
          "size": 234,
          "maxSize": 1000,
          "hitRate": 0.87,
          "missRate": 0.13
        }
      }
    }
  }
}

Metrics

// ํ†ต๊ณ„ ์กฐํšŒ
double hitRate = cache.getHitRate();
double missRate = cache.getMissRate();
long loadCount = cache.getLoadCount();
double avgLoadTime = cache.getAverageLoadTime();

System.out.println("Hit Rate: " + (hitRate * 100) + "%");
System.out.println("Average Load Time: " + avgLoadTime + "ms");

๐Ÿ—๏ธ ๋ชจ๋“ˆ ๊ตฌ์กฐ

sb-cached-collection/
โ”œโ”€โ”€ cache-core/              # ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ์ „๋žต
โ”‚   โ”œโ”€โ”€ strategy/            # ReferenceType, EvictionPolicy, LoadStrategy, etc.
โ”‚   โ”œโ”€โ”€ loader/              # SBCacheMapLoader, SBCacheListLoader
โ”‚   โ”œโ”€โ”€ writer/              # SBCacheMapWriter
โ”‚   โ””โ”€โ”€ exception/           # SBCacheLoadFailException, SBCacheWriteFailException
โ”‚
โ”œโ”€โ”€ cache-collection/        # ์บ์‹œ ๊ตฌํ˜„์ฒด
โ”‚   โ”œโ”€โ”€ map/                 # SBCacheMap (๋ฉ”์ธ ๊ตฌํ˜„)
โ”‚   โ”œโ”€โ”€ storage/             # ReferenceBasedStorage
โ”‚   โ””โ”€โ”€ strategy/            # LRU, LFU, FIFO, RANDOM, TTL ๊ตฌํ˜„
โ”‚
โ”œโ”€โ”€ cache-loader-jdbc/       # JDBC Loader
โ”œโ”€โ”€ cache-loader-file/       # File Loader
โ”œโ”€โ”€ cache-metrics/           # ํ†ต๊ณ„ ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง
โ””โ”€โ”€ cache-spring/            # Spring Framework ํ†ตํ•ฉ
    โ”œโ”€โ”€ SBCacheManager       # Spring CacheManager ๊ตฌํ˜„
    โ”œโ”€โ”€ SBCache              # Spring Cache ๊ตฌํ˜„
    โ””โ”€โ”€ boot/                # Auto-Configuration

์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„:

cache-core (๋…๋ฆฝ)
    โ†‘
    โ”œโ”€โ”€ cache-collection
    โ”œโ”€โ”€ cache-loader-*
    โ””โ”€โ”€ cache-metrics
            โ†‘
        cache-spring

๐Ÿš€ ์„ฑ๋Šฅ ์ตœ์ ํ™”

1. ConcurrentHashMap

  • Lock-free ์ฝ๊ธฐ (๋†’์€ ๋™์‹œ์„ฑ)
  • ์„ธ๊ทธ๋จผํŠธ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ (์“ฐ๊ธฐ ๋ถ„์‚ฐ)
  • O(1) ํ‰๊ท  ์‹œ๊ฐ„ ๋ณต์žก๋„

2. ASYNC LoadStrategy (Thundering Herd ๋ฐฉ์ง€)

SYNC (์ค‘๋ณต ๋กœ๋”ฉ):

Thread 1: load (300ms)
Thread 2: load (300ms)
Thread 3: load (300ms)
์ด DB ์ฟผ๋ฆฌ: 3ํšŒ

ASYNC (ํ•œ ๋ฒˆ๋งŒ ๋กœ๋”ฉ):

Thread 1: load (300ms)
Thread 2: wait โ†’ return
Thread 3: wait โ†’ return
์ด DB ์ฟผ๋ฆฌ: 1ํšŒ

3. Write-Behind ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ

์ „๋žต ๋‹จ์ผ ์“ฐ๊ธฐ 100๊ฐœ ์“ฐ๊ธฐ DB ๋ถ€ํ•˜
WRITE_THROUGH 10ms 1000ms ๋†’์Œ
WRITE_BEHIND 1ms 100ms ๋‚ฎ์Œ

4. Refresh-Ahead ์‚ฌ์ „ ๊ฐฑ์‹ 

  • ์‚ฌ์šฉ์ž๋Š” ํ•ญ์ƒ ์บ์‹œ ํžˆํŠธ ๊ฒฝํ—˜
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ฐฑ์‹  โ†’ ์‘๋‹ต ์‹œ๊ฐ„ ๋‹จ์ถ•

๐Ÿงช ํ…Œ์ŠคํŠธ

# ์ „์ฒด ํ…Œ์ŠคํŠธ ์‹คํ–‰
mvn test

# ํŠน์ • ๋ชจ๋“ˆ ํ…Œ์ŠคํŠธ
cd cache-collection && mvn test

# ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ
Tests run: 148, Failures: 0, Errors: 0, Skipped: 1

ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€:

  • SBCacheMap: 45๊ฐœ ํ…Œ์ŠคํŠธ
  • ReferenceType: 7๊ฐœ ํ…Œ์ŠคํŠธ
  • EvictionPolicy: 8๊ฐœ ํ…Œ์ŠคํŠธ
  • Spring Integration: 48๊ฐœ ํ…Œ์ŠคํŠธ

๐Ÿ“œ ์ตœ์‹  ๊ฐœ์„ ์‚ฌํ•ญ

Phase 10-A: JDBC/File Loader ๊ตฌํ˜„ (2025-01)

  • โœ… JDBCLoader: DataSource ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ
  • โœ… FileLoader: ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ

Phase 10-B: EvictionPolicy ๊ตฌํ˜„ (2025-01)

  • โœ… 5๊ฐ€์ง€ ์ถ•์ถœ ์ •์ฑ…: LRU, LFU, FIFO, RANDOM, TTL
  • โœ… Strategy ํŒจํ„ด์œผ๋กœ ํ™•์žฅ ๊ฐ€๋Šฅ
  • โœ… maxSize ์ดˆ๊ณผ ์‹œ ์ž๋™ ์ถ•์ถœ

Phase 10-C: ReferenceType ์ง€์› (2025-01)

  • โœ… STRONG, SOFT, WEAK ์ฐธ์กฐ ํƒ€์ž…
  • โœ… ReferenceBasedStorage ๊ตฌํ˜„
  • โœ… ReferenceQueue๋ฅผ ํ†ตํ•œ ์ž๋™ ์ •๋ฆฌ
  • โœ… GC์™€ ํ˜‘๋ ฅํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

Phase 11-A: Write-Through/Write-Behind (์ด๋ฏธ ์™„๋ฃŒ)

  • โœ… ๋™๊ธฐ/๋น„๋™๊ธฐ ์“ฐ๊ธฐ ์ „๋žต
  • โœ… ๋ฐฑ์—”๋“œ ์ €์žฅ์†Œ ๋™๊ธฐํ™”
  • โœ… ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ์ง€์›

Phase 11-B: Refresh-Ahead (์ด๋ฏธ ์™„๋ฃŒ)

  • โœ… TTL 50% ๋„๋‹ฌ ์‹œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฐฑ์‹ 
  • โœ… ํ•ญ์ƒ ์‹ ์„ ํ•œ ๋ฐ์ดํ„ฐ ์ œ๊ณต
  • โœ… ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ

Phase 12-A/B: Spring Cache ํ†ตํ•ฉ (์ด๋ฏธ ์™„๋ฃŒ)

  • โœ… SBCacheManager, SBCache ๊ตฌํ˜„
  • โœ… Auto-Configuration ์ง€์›
  • โœ… YAML/Properties ์„ค์ •

Phase 13-A/B/C: ๋ชจ๋‹ˆํ„ฐ๋ง ๊ธฐ๋Šฅ (์ด๋ฏธ ์™„๋ฃŒ)

  • โœ… CacheMetrics: Hit Rate, Load Time
  • โœ… Actuator Health Indicator
  • โœ… Prometheus/Micrometer ํ†ตํ•ฉ

๐Ÿ”ง ๋นŒ๋“œ

# ์ „์ฒด ๋นŒ๋“œ
mvn clean install

# ํŠน์ • ๋ชจ๋“ˆ ๋นŒ๋“œ
cd cache-collection && mvn clean install

# ํ…Œ์ŠคํŠธ ์Šคํ‚ต
mvn clean install -DskipTests

๐Ÿ“– ์ฐธ๊ณ  ์ž๋ฃŒ


๐Ÿ“ ๋ผ์ด์„ ์Šค

Apache License 2.0 - ์ƒ์„ธ ๋‚ด์šฉ์€ LICENSE ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”.


๐Ÿค ๊ธฐ์—ฌ

๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! Issue ์ œ๋ณด ๋ฐ Pull Request๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ œ์ถœํ•ด์ฃผ์„ธ์š”.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'feat: Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“ง ์—ฐ๋ฝ์ฒ˜


Made with โค๏ธ by ScriptonBaseStar Team

About

Collection Util - cache,

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •