프랙티스 실전 가이드

프랙티스의 핵심 개념과 실무 활용

JavaScript중급
10시간
20개 항목
학습 진행률0 / 20 (0%)

학습 항목

1. JavaScript
중급
Caching|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
2. JavaScript
중급
Firebase|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
3. JavaScript
고급
HTTPS|보안|통신|베스트|프랙티스
퀴즈튜토리얼
4. JavaScript
초급
Load Balancing 베스트 프랙티스 완벽 가이드
퀴즈튜토리얼
5. JavaScript
초급
Logstash|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
6. JavaScript
중급
OAuth|2.0|보안|베스트|프랙티스
퀴즈튜토리얼
7. JavaScript
고급
PWA|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
8. JavaScript
중급
Proxy Pattern 베스트 프랙티스 완벽 가이드
퀴즈튜토리얼
9. JavaScript
중급
Refactoring|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
10. JavaScript
초급
Responsive Design 베스트 프랙티스
퀴즈튜토리얼
11. JavaScript
중급
SSL|TLS|보안|베스트|프랙티스
퀴즈튜토리얼
12. JavaScript
고급
Sentry|베스트|프랙티스|에러|모니터링
퀴즈튜토리얼
13. JavaScript
고급
Sentry|에러|모니터링|베스트|프랙티스
퀴즈튜토리얼
14. JavaScript
고급
Solidity|베스트|프랙티스|보안|최적화
퀴즈튜토리얼
15. Python
고급
Ansible 베스트 프랙티스 완벽 가이드
퀴즈튜토리얼
16. Python
고급
Selenium|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
17. React
중급
Chakra|UI|베스트|프랙티스
퀴즈튜토리얼
18. TypeScript
고급
Accessibility|베스트|프랙티스|완벽|가이드
퀴즈튜토리얼
19. TypeScript
고급
Bridge|Pattern|베스트|프랙티스
퀴즈튜토리얼
20. TypeScript
고급
Dependency|Injection|베스트|프랙티스
퀴즈튜토리얼
1 / 20

이미지 로딩 중...

Caching 베스트 프랙티스 완벽 가이드 - 슬라이드 1/11

Caching 베스트 프랙티스 완벽 가이드

애플리케이션 성능을 극대적으로 향상시키는 캐싱 전략과 구현 방법을 다룹니다. 메모리 캐시, HTTP 캐시, 분산 캐시 등 실무에서 바로 적용 가능한 패턴을 학습합니다.


카테고리:JavaScript
언어:JavaScript
난이도:intermediate
메인 태그:#JavaScript
서브 태그:
#Caching#Performance#Optimization#Redis

들어가며

이 글에서는 Caching 베스트 프랙티스 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. 메모리_캐시_구현
  2. LRU_캐시_전략
  3. 함수_메모이제이션
  4. HTTP_캐시_헤더
  5. Redis_캐시_구현
  6. 캐시_무효화_전략
  7. 캐시_워밍업
  8. 캐시_관통_방지
  9. 다층_캐시_전략
  10. 캐시_압축_저장

1. 메모리_캐시_구현

개요

간단한 인메모리 캐시를 구현하여 반복적인 연산 결과를 저장하고 재사용합니다. TTL(Time To Live)을 설정하여 캐시 만료를 관리합니다.

코드 예제

class MemoryCache {
  constructor() {
    this.cache = new Map();
  }

  set(key, value, ttl = 60000) {
    const expiry = Date.now() + ttl;
    this.cache.set(key, { value, expiry });
  }

  get(key) {
    const item = this.cache.get(key);
    if (!item) return null;
    if (Date.now() > item.expiry) {
      this.cache.delete(key);
      return null;
    }
    return item.value;
  }
}

설명

Map을 사용하여 키-값 쌍을 저장하고, 각 항목에 만료 시간을 설정합니다. 조회 시 만료 여부를 확인하여 유효한 데이터만 반환합니다.


2. LRU_캐시_전략

개요

LRU(Least Recently Used) 알고리즘으로 캐시 크기를 제한하고 가장 오래 사용되지 않은 항목을 자동으로 제거합니다.

코드 예제

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (!this.cache.has(key)) return null;
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
    return value;
  }

  set(key, value) {
    this.cache.delete(key);
    this.cache.set(key, value);
    if (this.cache.size > this.capacity) {
      this.cache.delete(this.cache.keys().next().value);
    }
  }
}

설명

Map의 삽입 순서 특성을 활용하여 최근 사용된 항목을 뒤로 이동시킵니다. 용량 초과 시 가장 앞의 항목(가장 오래된 항목)을 제거합니다.


3. 함수_메모이제이션

개요

함수의 결과를 캐싱하여 동일한 인자로 호출 시 재계산 없이 저장된 결과를 반환합니다. 비용이 큰 연산에 효과적입니다.

코드 예제

function memoize(fn) {
  const cache = new Map();

  return function(...args) {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      console.log('캐시에서 반환');
      return cache.get(key);
    }
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

const expensiveCalc = memoize((n) => {
  return n * n;
});

설명

함수 인자를 문자열로 변환하여 캐시 키로 사용합니다. 동일한 인자로 호출 시 이전 결과를 즉시 반환하여 성능을 개선합니다.


4. HTTP_캐시_헤더

개요

HTTP 응답 헤더를 설정하여 브라우저와 CDN에서 리소스를 캐싱합니다. 불필요한 네트워크 요청을 줄입니다.

코드 예제

const express = require('express');
const app = express();

app.get('/api/data', (req, res) => {
  res.set({
    'Cache-Control': 'public, max-age=3600',
    'ETag': '"abc123"',
    'Last-Modified': new Date().toUTCString()
  });

  res.json({ data: 'cached response' });
});

설명

Cache-Control로 캐시 유효 기간을 설정하고, ETag와 Last-Modified로 조건부 요청을 가능하게 합니다. 클라이언트는 변경되지 않은 리소스를 재사용합니다.


5. Redis_캐시_구현

개요

Redis를 사용한 분산 캐시 시스템으로 여러 서버 간 캐시를 공유합니다. 확장성이 뛰어난 캐싱 솔루션입니다.

코드 예제

const redis = require('redis');
const client = redis.createClient();

async function getCachedData(key) {
  const cached = await client.get(key);
  if (cached) return JSON.parse(cached);

  const data = await fetchFromDB(key);
  await client.setEx(key, 3600, JSON.stringify(data));
  return data;
}

async function fetchFromDB(key) {
  return { id: key, name: 'User Data' };
}

설명

Redis에서 데이터를 먼저 조회하고, 없으면 DB에서 가져와 Redis에 저장합니다. setEx로 만료 시간을 함께 설정하여 자동 정리됩니다.


6. 캐시_무효화_전략

개요

데이터 변경 시 관련 캐시를 제거하여 최신 데이터를 보장합니다. 캐시 일관성을 유지하는 핵심 패턴입니다.

코드 예제

class CacheManager {
  constructor() {
    this.cache = new Map();
  }

  async getData(id) {
    if (this.cache.has(id)) return this.cache.get(id);
    const data = await fetchData(id);
    this.cache.set(id, data);
    return data;
  }

  async updateData(id, newData) {
    await saveData(id, newData);
    this.cache.delete(id);
  }
}

설명

데이터 업데이트 시 해당 캐시를 명시적으로 제거합니다. 다음 조회 시 최신 데이터를 가져와 캐시를 새로 갱신합니다.


7. 캐시_워밍업

개요

애플리케이션 시작 시 자주 사용되는 데이터를 미리 캐시에 로드합니다. 초기 요청의 응답 속도를 개선합니다.

코드 예제

class CacheWarmer {
  constructor(cache) {
    this.cache = cache;
  }

  async warmUp(keys) {
    console.log('캐시 워밍업 시작...');
    const promises = keys.map(async (key) => {
      const data = await fetchData(key);
      this.cache.set(key, data);
    });
    await Promise.all(promises);
    console.log('캐시 워밍업 완료');
  }
}

설명

애플리케이션 시작 시 중요한 데이터를 병렬로 조회하여 캐시에 미리 저장합니다. 사용자의 첫 요청부터 빠른 응답이 가능합니다.


8. 캐시_관통_방지

개요

존재하지 않는 데이터 요청으로 인한 반복적인 DB 조회를 방지합니다. null 값도 캐싱하여 불필요한 부하를 줄입니다.

코드 예제

async function safeGetData(key) {
  const cached = cache.get(key);
  if (cached !== undefined) {
    return cached === null ? null : cached;
  }

  const data = await fetchFromDB(key);
  if (data === null) {
    cache.set(key, null, 300000);
    return null;
  }

  cache.set(key, data);
  return data;
}

설명

데이터가 없는 경우에도 null을 캐싱하여 동일한 요청이 반복되지 않도록 합니다. 짧은 TTL을 설정하여 나중에 추가될 수 있는 데이터를 고려합니다.


9. 다층_캐시_전략

개요

메모리 캐시와 분산 캐시를 함께 사용하는 2단계 캐싱 전략입니다. 빠른 로컬 캐시와 공유 가능한 분산 캐시의 장점을 결합합니다.

코드 예제

class TieredCache {
  constructor(localCache, redisCache) {
    this.local = localCache;
    this.redis = redisCache;
  }

  async get(key) {
    let value = this.local.get(key);
    if (value) return value;

    value = await this.redis.get(key);
    if (value) {
      this.local.set(key, value);
      return value;
    }
    return null;
  }
}

설명

로컬 캐시를 먼저 확인하고, 없으면 Redis를 조회합니다. Redis에서 찾은 데이터는 로컬 캐시에도 저장하여 다음 접근을 더 빠르게 합니다.


10. 캐시_압축_저장

개요

큰 데이터를 압축하여 저장함으로써 메모리 사용량을 줄입니다. 저장 공간과 네트워크 대역폭을 절약합니다.

코드 예제

const zlib = require('zlib');
const { promisify } = require('util');
const gzip = promisify(zlib.gzip);
const gunzip = promisify(zlib.gunzip);

async function setCached(key, data) {
  const json = JSON.stringify(data);
  const compressed = await gzip(json);
  cache.set(key, compressed);
}

async function getCached(key) {
  const compressed = cache.get(key);
  if (!compressed) return null;
  const json = await gunzip(compressed);
  return JSON.parse(json.toString());
}

설명

JSON 문자열을 gzip으로 압축하여 저장하고, 조회 시 압축을 해제합니다. 큰 객체나 배열을 캐싱할 때 메모리를 효율적으로 사용합니다.


마치며

이번 글에서는 Caching 베스트 프랙티스 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#JavaScript #Caching #Performance #Optimization #Redis

#JavaScript#Caching#Performance#Optimization#Redis