Community

모든 개발자가 알아야 하는 Caching Pitfalls

1. Cache Stampede 문제 회피하기: 일반적으로 Cache-Aside Pattern 을 통해 캐시 시스템을 구현하게 되면, 캐시를 먼저 조회해보고 캐시 키가 없다면 데이터베이스에서 이를 조회하도록 구현할 겁니다. Cache Stampede 는 캐시의 특정 키가 만료될 때 대규모 클라이언트가 데이터베이스에서 해당 키를 조회할 때 발생할 수 있는 문제입니다. 해결 방법은 다양합니다: * Locking * External Process 를 이용하는 방법 * Probabilistic early expiration Locking: * 이 방법은 캐시에서 데이터가 만료되었다는 걸 알면 Locking 을 걸어둬서, 다른 클라이언트들이 데이터베이스를 조회하지 않도록 하는 방법입니다. * 즉 정리하자면 Lock 을 가진 데이터가 Recompuation (= 만료된 캐시 키를 데이터베이스에서 조회해서 다시 캐시에 채우는 연산) 을 수행하고, Lock 을 가지지 못한 클라이언트는 일정 시간을 기다렸다가 다시 캐시에 조회하도록 하는 방법입니다. * 이 방법을 좀 더 응용하자면 Lock 을 가지지 못한 클라이언트는 꼭 기다릴 필요는 없습니다. 그냥 Not Found 로 리턴하거나, 오래된 버전의 데이터를 받아오는 방법이 있다면 이를 이용하는 Fallback 접근 방식을 취하는 것도 방법입니다. External Process 를 이용하는 방법: * 이 방법은 외부 프로세스에서 캐시에 데이터를 채우도록 하는 매커니즘입니다. * 캐시 키가 만료되기 전에 먼저 수행하도록 하는 Proactively 방식과 캐시 키가 없을 때 반응해서 채우도록 하는 Reactive 방식이 있습니다. * Locking 매커니즘에 대해 구현을 하지 않아도 되므로 보다 간단한 솔루션입니다. Probabilistic early expiration: * 캐시에서 데이터를 조회하는 클라이언트가 확률적으로 캐시 키가 만료되기 전에 Recomputation 과정을 수행하도록 하는 기법입니다. * 이 확률은 캐시 키가 만료에 가까울 때 증가하도록 구현하면 됩니다. 2. Cache Penetration 문제 회피하기: Cache Penetration 는 존재하지도 않는 키를 캐시에서 조회하고 실패해서 데이터베이스에 추가로 조회하면서 데이터베이스 안정성을 떨어뜨리는 문제입니다. 해결 방법은 다양합니다: * implement a placeholder for non-existing keys: * Bloomfilter implement a placeholder for non-existing keys: * 존재하지 않는 데이터의 경우에도 캐시에 NULL 값으로 세팅해 놓는 방법입니다. * 이렇게 적용한다면 계속해서 추가적인 데이터베이스로의 부하는 일어나지 않을 것이지만 캐시 리소스를 많이 차지할 수도 있는 문제가 발생할 수 있습니다. Bloomfilter: * Bloomfilter 를 데이터베이스 앞단에 별도의 컴포넌트로 사용한다면 존재하지 않는 데이터를 명확하게 구별할 수 있습니다. * 다만 Bloomfilter 특성상 존재하지 않는 데이터는 명확히 구별하지만 존재하는 데이터라고 판단한 경우에도 존재하지 않는 데이터가 있을 수 있다는 점을 알고 있어야 합니다. 3. Cache Crash 와 Cache Avalanche 문제 회피하기: Cache Crash 는 캐시 시스템이 장애가 나서 캐시를 이용할 수 없는 문제를 말하며, Cache Avalanche 는 캐시 시스템이 재시작하거나 할 때 캐시 데이터가 비어있는 상태에서 일어나는 문제를 말합니다. Cache Crash 문제가 발생하면 모든 부하는 데이터베이스로 가기 때문에 안정성이 떨어지는 문제가 발생할 수 있고, Cache Avalanche 문제가 발생하면 Cache Stampede 현상처럼 모든 키가 miss 가 나서 모든 캐시 부하가 데이터베이스로 가기 때문에 안정성이 떨어지는 문제가 발생할 수 있습니다. 이런 문제들에서 시스템의 안정성을 올리는 해결 방법은 다양합니다: * Circuit Breaker * Redundancy * Warm-up Circuit Breaker: * 과부하 상태일 때 트래픽을 일시적으로 차단해서 서버가 무너지도록 않도록 하고, 서버의 안정성을 회복하도록 하는 방법입니다. Redundancy: * Cache Cluster 를 구축하는 것처럼 여러 개의 캐시 인스턴스를 운영해서 하나의 인스턴스가 장애가 나도 문제가 없도록 하는 방법입니다. Warm-up: * 캐시 서비스를 운영환경에 투입하기 전에 자주 사용하는 데이터를 로드시킨 후 서비스에 투입되는 방법입니다. References: * https://www.youtube.com/watch?v=wh98s0XhMmQ

알림

알림이 없습니다