티스토리 뷰
spring cache 기본 사용법: https://dolgogae.tistory.com/85
Overview
앞선 글에서 spring caching에 기본적인 사용법에 대해서 설명을 했다. 결과 값이 자주 업데이트 되지 않는 함수에 대해서 적용하면 in-memory에서 별도 연산없이 바로 결과를 가져오기 때문에 성능적인 이득을 볼 수 있었다. caching을 만드는 과정에서 각 cache를 구분하는 key를 생성하는 keyGenerator에 관한 내용을 이번 장에서 다뤄보고자 한다.
SimpleKeyGenerator
SimpleKeyGenerator는 keyGenerator의 디폴트 설정값이다. 캐싱을 하는 메서드에서 인자값을 기반으로 key를 생성한다.
@Cacheable(value = "products")
public Product getProduct(Long id, String category) {
return new Product(id, category);
}
위 함수에서 key는 SimpleKey(id, category)로 생성된다. 그리고 SimpleKey 생성자를 살펴보면 아래처럼 값을 구분하여 저장한다.
public SimpleKey(Object... elements) {
Assert.notNull(elements, "Elements must not be null");
this.params = (Object[])elements.clone();
this.hashCode = Arrays.deepHashCode(this.params);
}
위처럼 deepHashCode를 사용해서 자신만의 해시 값을 가지게 되고, 그 해시 값을 기반으로 유니크한 값인지 비교를 한다.
여기서 deepHashCode에 대해서 이해할 필요가 있고,
deepHashCode가 어떤 경우에 단점을 가지는지 알면 우리가 언제 커스텀 key generator를 만들어야 할지 알 수 있다.
DeepHashCode
우선 그 전에 deepHashCode가 일반적인 해시코드와 무엇이 다른지 살펴보자.
- hashCode: 중첩 배열을 참조값으로 처리하고, Object[] 배열 자체의 해시 코드만 계산.
- deepHashCode: 중첩 배열까지 해시 코드를 재귀적으로 계산.
위에서 볼 수 있듯 일반 hashCode는 참조값을 기반으로 해시를 만들기 때문에
배열안에 들어가 있는 값이 같더라도 배열의 주소가 다르면 다른 해시 값을 생성하게 된다.
따라서 캐싱에서는 주소값이 다르더라도 같은 값인게 중요하기 때문에 deepHashCode가 쓰였음을 확인할 수 있다.
성능 저하
앞서 설명한 것처럼 재귀적으로 호출하기 때문에 hash 값을 만드는데 성능적인 측면이 문제가 될 수 있다.
하지만 key를 생성하는 데이터 자체가 크지 않다면 성능은 크게 문제가 되지 않는다.
따라서 대규모 데이터를 통해서 key를 만들어야 하는 상황이라면 그 값 중 유니크한 값 몇 개를 추출하여
customKeyGenerator를 만드는게 효과적이라고 할 수 있다.
충돌
사실 이 경우는 잘 발생하지 않지만 deepHashCode는 32비트 정수를 기반으로 생성된다.
물론 32비트 정수라도 어마어마하게 큰 수라서 중복될 가능성이 현저히 낮지만
보안적으로 더 좋은 알고리즘이나 충돌이 전혀 일어나지 않을 알고리즘을 선택하는 것도 방법이다.
CustomKeyGenerator
위에서 deepHashCode의 단점으로 keyGenerator를 만들때 방법이다.
KeyGenerator를 상속받아 클래스를 만들고 spring bean으로 등록해야 한다.
@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
String key = target.getClass().getSimpleName() + "_" + method.getName() + "_" + Arrays.toString(params);
return key;
}
}
generate() 함수를 오버라이드 받고 거기에 원하는 해싱 알고리즘을 만들면 된다.
커스텀으로 key를 만들어야 한다면 위처럼 자신만의 알고리즘을 만들어서 사용하면 된다.
'Back End > Spring' 카테고리의 다른 글
[JAVA] Thread Pool과 ThreadLocal (0) | 2025.03.04 |
---|---|
Spring Caching으로 성능 올리기 - (3) cache config(ehcache, redis, caffeine) (0) | 2025.01.11 |
Spring Caching으로 성능 올리기 - (1) 기본 사용법 (0) | 2024.12.01 |
[Test] Spring boot, Junit, Testcontainers를 이용한 테스트 환경 만들기 (0) | 2024.04.11 |
[Spring Data] Spring Data MongoDB - insert() vs save() (0) | 2024.04.06 |
- Total
- Today
- Yesterday
- Data Engineering
- Container
- OS
- broker
- caching
- React
- Producer
- 리액트
- NextJS
- zookeeper
- KAFKA
- rhel
- apache kafka
- Linux
- Java
- cs
- apache
- spring
- Firebase
- frontend
- feign client
- 프론트엔드
- Front
- centos
- API
- backend
- K8S
- spring boot
- JPA
- consumer
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |