
맨날 헷갈려서 이 참에 정리해놓는다…
Filter Cache(Node Level)
- 해당 캐시가 특정 인덱스나 샤드에 종속되지 않고, 해당 노드가 보유한 모든 샤드들이 공유해서 사용하는 자원
1. 물리적 메모리 할당 방식
필터 캐시는 노드 단위로 설정된 힙(Heap) 메모리의 일정 비율(기본값 10%)을 점유
예시: 한 노드에 인덱스 A의 샤드와 인덱스 B의 샤드가 함께 있다면, 두 샤드 모두 노드에 할당된 하나의 쿼리 캐시 영역을 나누어 사용
특정 샤드 전용 메모리가 아니라, 노드 프로세스 전체가 관리하는 공용 풀
2. 세그먼트 단위의 캐싱 (재사용성)
Elasticsearch의 데이터는 세그먼트(Segment)라는 단위로 저장
필터 캐시는 쿼리 결과(Bitset)를 세그먼트 단위로 저장하는데, 이 세그먼트들이 노드 내에서 관리되므로 노드 수준에서 효율적으로 제어 가능
3. LRU(Least Recently Used) 정책의 범위
- 노드 레벨 캐시는 노드 전체의 메모리 상황을 보고 캐시를 관리
왜 노드 레벨이라 불리냐면, 인덱스 별로 구분하지 않고 노드 내에서 한번에 관리하기 때문
| 구분 | 내용 |
| 관리 주체 | 개별 샤드가 아닌 노드(JVM Instance)가 직접 관리 |
| 자원 공유 | 노드 내의 모든 샤드와 인덱스가 하나의 캐시 풀을 공유 |
| 설정 단위 | indices.queries.cache.size와 같이 노드 설정을 통해 크기 제어 |
그럼 Request Cache는 다를까? 똑같이 노드 내에서 한번에 관리하는 걸로 알고있는데?
→ 이 둘을 부르는 명칭이 다른 이유는 캐시가 저장되는 단위(Scope)와 수명(Lifecycle)이 완전히 다르기 때문이다
1. 왜 '샤드 요청 캐시'라고 부를까? (단위의 차이)
노드 쿼리 캐시(필터 캐시)는 세그먼트(Segment) 단위로 결과를 쪼개서 저장하지만, 샤드 요청 캐시는 샤드에 전달된 전체 쿼리 결과를 통째로 저장
노드 쿼리 캐시: "이 문서가 '서울' 지역인가?"라는 필터 결과를 비트셋($0$ 또는 $1$)으로 저장. 이 정보는 다른 검색 쿼리에서도 재사용이 가능
샤드 요청 캐시: "A 샤드에서 2024년 매출 합계는?"이라는 질의 전체의 결과값을 저장. 특정 샤드에 떨어진 요청 그 자체를 키(Key)로 사용하기 때문에 해당 샤드에 종속적
2. 수명과 관리 방식의 차이
두 캐시는 노드 메모리를 공유하지만, 관리 규칙이 다르다
| 구분 | 노드 쿼리 캐시 (Node Query Cache) | 샤드 요청 캐시 (Shard Request Cache) |
| 관리 단위 | 세그먼트(Segment) 단위 | 샤드(Shard) 단위 |
| 데이터 형태 | 필터 결과 (Bitset) | Aggregation 결과, 총 검색 수 등 |
| 무효화 시점 | 세그먼트가 병합(Merge)되거나 삭제될 때 | 샤드가 Refresh될 때 (데이터가 하나라도 변하면 전체 삭제) |
| 기본 메모리 | 노드 힙 메모리의 10% | 노드 힙 메모리의 1% |
결론: "관리는 노드가 하지만, 데이터의 주인은 샤드다"
사용자가 샤드 요청 캐시라고 부르는 이유는, 해당 캐시 내용이 특정 샤드의 특정 시점 데이터를 완벽하게 대표하기 때문. 샤드에 새로운 문서가 하나라도 들어와서 refresh가 일어나면, 그 샤드에 할당되었던 요청 캐시는 모두 무효화(Invalidate).
반면 노드 쿼리 캐시는 세그먼트 단위라 데이터가 좀 추가되어도 기존 세그먼트용 캐시는 그대로 살아있을 수 있다. 그래서 더 '노드 수준에서 범용적으로 쓰이는 캐시'라는 인상이 강하다는 것!




